diff --git a/common/utils.js b/common/utils.js index f3b55a4..4af6953 100644 --- a/common/utils.js +++ b/common/utils.js @@ -20,6 +20,7 @@ export const getLocation = async () => { export const chooseImage = async () => { return new Promise((resolve, reject) => { uni.chooseImage({ + sourceType:['camera'], count: 1, success: (res) => { resolve(res); @@ -820,7 +821,7 @@ export const saveImageToPhotosAlbum = (image) => { const link = document.createElement("a"); link.href = image; // 如果 image 是 blob url 或 http url,都可以 - link.download = "image_" + Date.now(); // 下载文件名 + link.download = "image_" + Date.now()+".jpg"; // 下载文件名 document.body.appendChild(link); link.click(); document.body.removeChild(link); diff --git a/index.html b/index.html index b5d330d..64d61a8 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,7 @@
+ + +``` + +It's also available on [jsDelivr](http://www.jsdelivr.com/projects/eruda) and [cdnjs](https://cdnjs.com/libraries/eruda). + +```html + + +``` + +For more detailed usage instructions, please read the documentation at [eruda.liriliri.io](https://eruda.liriliri.io/docs/)! + +## Related Projects + +* [eruda-android](https://github.com/liriliri/eruda-android): Simple webview with eruda loaded automatically. +* [chii](https://github.com/liriliri/chii): Remote debugging tool. +* [chobitsu](https://github.com/liriliri/chobitsu): Chrome devtools protocol JavaScript implementation. +* [licia](https://github.com/liriliri/licia): Utility library used by eruda. +* [luna](https://github.com/liriliri/luna): UI components used by eruda. +* [vivy](https://github.com/liriliri/vivy-docs): Icon image generation. + +## Third Party + +* [eruda-pixel](https://github.com/Faithree/eruda-pixel): UI pixel restoration tool. +* [eruda-webpack-plugin](https://github.com/huruji/eruda-webpack-plugin): Eruda webpack plugin. +* [eruda-vue-devtools](https://github.com/Zippowxk/vue-devtools-plugin): Eruda Vue-devtools plugin. + +## Backers + +1&&o--,r=6*o<1?l+6*(t-l)*o:2*o<1?t:3*o<2?l+(t-l)*(2/3-o)*6:l,c[u]=n(255*r);return c};var n=Math.round;e.exports=t},961:function(e,t,n){var o=n(5693);t=function(e,t,n){var r=[];t=o(t,n);for(var i=-1,a=e.length;++i-1&&this._listeners.splice(t,1)},rmAllListeners:function(){this._listeners=[]},emit:function(){var e=this,t=a(arguments),n=r(this._listeners);i(n,(function(n){return n.apply(e,t)}),this)}},{mixin:function(e){i(["addListener","rmListener","emit","rmAllListeners"],(function(n){e[n]=t.prototype[n]})),e._listeners=e._listeners||[]}}),e.exports=t},1034:function(e,t,n){var o=n(9760),r=n(3957),i=n(6214),a=n(5154);t=function(e){return i(e)?e.map((function(e){return t(e)})):o(e)&&!r(e)?a(e,(function(e){return t(e)})):e},e.exports=t},1107:function(e,t,n){(t=n(6314)(!1)).push([e.id,"@font-face{font-family:luna-text-viewer-icon;src:url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAS0AAsAAAAAB2QAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAAFQAAAB0INElr09TLzIAAAFcAAAAPQAAAFZL+0klY21hcAAAAZwAAACfAAACEAEewxRnbHlmAAACPAAAAIYAAACkNSDggmhlYWQAAALEAAAALgAAADZzrb4oaGhlYQAAAvQAAAAWAAAAJAGRANNobXR4AAADDAAAABAAAAAoAZAAAGxvY2EAAAMcAAAAEAAAABYBWgFIbWF4cAAAAywAAAAdAAAAIAEXADtuYW1lAAADTAAAASkAAAIWm5e+CnBvc3QAAAR4AAAAOwAAAFJIWdOleJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBWAdNMDGwMQkAWK1CGlYEZyGMCstiBMpxAUUYGZgDbGgXDeJxjYGTQYJzAwMrAwFDH0AMkZaB0AgMngzEDAxMDKzMDVhCQ5prCcIAh+SMTwwkgVwhMMjAwgggAY84IrgAAAHicvZFLCsMwDERHzsdJ6aL0HD1VQiDQRbIN9Axd9aI+QTpjq5Bdd5F4Bo1lybIBNAAq8iA1YB8YZG+qlvUKl6zXGBjf6MofMWHGEyu2FPb9oCxULCtHs3yy+J2urg1rtojo0HM/MKnFGabOGlbdYvdT+1N6/7drXl8e6Vajo3efHP3b7HAUvntBMy1OJKujMTeHNZMV9McpFBC+tLgY4QB4nGNgZACBEwzrGdgZGOwZxdnVDdXNPfKEGlhchO0KhZtZ3IQYmMFq1jCsZpBi0GLQY2AwNzGzZjQSk2UUYdNmVFID8UyVRUXYlNRMlVGlTM1FjU3tmZkTmVhYmFRBhHwoCyuzKgtTIjMzWJg3ZClIGMRlZQmVB7GhMixM0aGhQIsB52sTqgAAeJxjYGRgYADi2JNxkvH8Nl8ZuBlOAAWiOB/va0DQQHCCYT2Q5GBgAnEANJ0KnQAAeJxjYGRgYDjBwIBEMjKgAi4AOvoCZQAAeJxjYACCE1CMBwAAM7gBkXicY2AAAiGGIFQIABXIAqN4nGNgZGBg4GLQZ2BmAAEmMI8LSP4H8xkADjQBUwAAAHicZZA9bsJAFITHYEgCUoIUKSmzVQoimZ+SA0BPQZfCmLUxsr3WekGiywlyhBwhp4hyghwoY/NoYC0/fzNv3u7KAAb4hYd6ebhtar1auKE6cZv0IOyTn4U76ONFuEt/KNzDG6bCfTzinTt4/h2dAUrhFu7xIdym/ynsk7+EO3jCt3CX/o9wDyv8Cffx6g3TyBSxKdxSJ/sstGd5/q60rVJTqEkwPlsLXWgbOr1R66OqDsnUuVjF1uRqzq7OMqNKa3Y6csHWuXI2GsXiB5HJkSKCQYG4qQ5LaCTYI0MIe9W91CumLSr6tVaYIMD4KrVgqmiSIZXGhsk1jqwVDjxtStcxrfhazuSkucxq3iQjK/7vurejE9EPsG2mSsww4hNf5IPmDvk/PRFeqAAAAHicXcU7CsAgFEXBe4x/l/kQBAtt3X0KSZNpRk7X91/F8eAJRBKZQqUp2Og2va19MAadyWJzpBd4kgcWAA==') format('woff')}[class*=' luna-text-viewer-icon-'],[class^=luna-text-viewer-icon-]{display:inline-block;font-family:luna-text-viewer-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.luna-text-viewer-icon-check:before{content:'\\f101'}.luna-text-viewer-icon-copy:before{content:'\\f102'}.luna-text-viewer{color:#333;background-color:#fff;font-family:Arial,Helvetica,sans-serif;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:14px;padding:0;unicode-bidi:embed;position:relative;overflow:auto;border:1px solid #ccc}.luna-text-viewer.luna-text-viewer-platform-windows{font-family:'Segoe UI',Tahoma,sans-serif}.luna-text-viewer.luna-text-viewer-platform-linux{font-family:Roboto,Ubuntu,Arial,sans-serif}.luna-text-viewer .luna-text-viewer-hidden,.luna-text-viewer.luna-text-viewer-hidden{display:none}.luna-text-viewer .luna-text-viewer-invisible,.luna-text-viewer.luna-text-viewer-invisible{visibility:hidden}.luna-text-viewer *{box-sizing:border-box}.luna-text-viewer.luna-text-viewer-theme-dark{color:#d9d9d9;border-color:#3d3d3d;background:#242424}.luna-text-viewer:hover .luna-text-viewer-copy{opacity:1}.luna-text-viewer-table{display:table}.luna-text-viewer-table .luna-text-viewer-line-number,.luna-text-viewer-table .luna-text-viewer-line-text{padding:0}.luna-text-viewer-table-row{display:table-row}.luna-text-viewer-line-number{display:table-cell;padding:0 3px 0 8px!important;text-align:right;vertical-align:top;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-right:1px solid #ccc}.luna-text-viewer-line-text{display:table-cell;padding-left:4px!important;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.luna-text-viewer-copy{background:#fff;opacity:0;position:absolute;right:5px;top:5px;border:1px solid #ccc;border-radius:4px;width:25px;height:25px;text-align:center;line-height:25px;cursor:pointer;transition:opacity .3s,top .3s}.luna-text-viewer-copy .luna-text-viewer-icon-check{color:#188037}.luna-text-viewer-text{padding:4px;font-size:12px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;box-sizing:border-box;white-space:pre;display:block}.luna-text-viewer-text.luna-text-viewer-line-numbers{padding:0}.luna-text-viewer-text.luna-text-viewer-wrap-long-lines{white-space:pre-wrap}.luna-text-viewer-text.luna-text-viewer-wrap-long-lines .luna-text-viewer-line-text{word-break:break-all}.luna-text-viewer-theme-dark{color-scheme:dark}.luna-text-viewer-theme-dark .luna-text-viewer-copy,.luna-text-viewer-theme-dark .luna-text-viewer-line-number{border-color:#3d3d3d}.luna-text-viewer-theme-dark .luna-text-viewer-copy .luna-text-viewer-icon-check{color:#81c995}.luna-text-viewer-theme-dark .luna-text-viewer-copy{background-color:#242424}",""]),e.exports=t},1162:function(e,t,n){"use strict";n.d(t,{Ay:function(){return ve}});var o=n(991),r=n(3029),i=n(2901),a=n(388),s=n(3954),c=n(5361),l=n(3693),u=n.n(l),d=n(5241),h=n.n(d),f=n(5902),p=n.n(f),v=n(5630),g=n.n(v),m=n(9760),b=n.n(m),y=n(5651),A=n.n(y),w=n(3915),_=n.n(w),x=n(6030),k=n.n(x),C=n(2561),S=n.n(C),E=n(3957),T=n.n(E),N=n(3497),O=n.n(N),j=n(1976),M=n.n(j),I=n(1738),z=n.n(I),D=n(9405),B=n.n(D),F=n(3249),R=n.n(F),L=n(96),G=n.n(L),P=n(4236),H=n.n(P),Y=n(9100),$=n.n(Y);var q=n(2263),Q=n.n(q),U=n(5169),W=n.n(U),J=n(9548),K=n.n(J),V=(n(6097),n(5004)),Z=n.n(V);n(9410),n(8609);function X(e){var t="luna-".concat(e,"-");function n(e){return _()(B()(e).split(/\s+/),(function(e){return R()(e,t)?e:e.replace(/[\w-]+/,(function(e){return"".concat(t).concat(e)}))})).join(" ")}return function(e){if(/<[^>]*>/g.test(e))try{var t=K().parse(e);return ee(t,(function(e){e.attrs&&e.attrs.class&&(e.attrs.class=n(e.attrs.class))})),K().stringify(t)}catch(t){return n(e)}return n(e)}}function ee(e,t){for(var n=0,o=e.length;n".concat(r," "),n+=""})),this.$headerRow.html(t),this.$fillerRow.html(n)}},{key:"renderResizers",value:function(){for(var e="",t=this.options.columns.length-1,n=0;n \n
\n \n \n \n
\n \n \n 1&&void 0!==arguments[1])||arguments[1];return null===e&&(t="Null"),void 0===e&&(t="Undefined"),r(e)&&(t="NaN"),a(e)&&(t="Buffer"),t||(t=o(e).match(s))&&(t=t[1]),t?n?i(t):t:""};var s=/^\[object\s+(.*?)]$/;e.exports=t},2990:function(e,t){t={encode:function(e){var t,n,r=[],i=e.length,a=i%3;i-=a;for(var s=0;s>18&63]+o[t>>12&63]+o[t>>6&63]+o[63&t]));return i=e.length,1===a?(n=e[i-1],r.push(o[n>>2]),r.push(o[n<<4&63]),r.push("==")):2===a&&(n=(e[i-2]<<8)+e[i-1],r.push(o[n>>10]),r.push(o[n>>4&63]),r.push(o[n<<2&63]),r.push("=")),r.join("")},decode:function(e){var t=e.length,o=0;"="===e[t-2]?o=2:"="===e[t-1]&&(o=1);var r,i,a,s,c,l,u,d=new Array(3*t/4-o);for(t=o>0?t-4:t,r=0,i=0;r
"),t=t.map((function(e){return f()(e)})),n+'
"),"').concat(t,"
")}},{key:"formatFn",value:function(e){return''.concat(this.formatJs(e.toString()),"
")}},{key:"formatElName",value:function(e){var t=e.id,n=e.className,o=e.tagName.toLowerCase();if(""!==t&&(o+="#".concat(t)),he()(n)){var r="";x()(n.split(/\s+/g),(function(e){""!==e.trim()&&(r+=".".concat(e))})),o+=r}return o}},{key:"formatEl",value:function(e){var t=gt()();return this.elements[t]=e,this.console.c(''))}}])}(We());function Et(e){var t=(e=Ge()(e)).split(";"),n={};x()(t,(function(e){if(m()(e,":")){var t=i(e.split(":"),2),o=t[0],r=t[1];n[B()(o)]=B()(r)}})),n.display="inline-block",n["max-width"]="100%",delete n.width,delete n.height;var o="";return x()(n,(function(e,t){o+="".concat(t,":").concat(e,";")})),o}var Tt=n(5820),Nt=n.n(Tt),Ot=n(3981),jt=n.n(Ot),Mt=n(8105),It=n.n(Mt),zt=n(7005),Dt=n.n(zt),Bt=n(3497),Ft=n.n(Bt),Rt=n(5865),Lt=n.n(Rt),Gt=n(8862),Pt=n.n(Gt),Ht=n(7030),Yt=n.n(Ht),$t=n(961),qt=n.n($t),Qt=n(7e3),Ut=n.n(Qt);function Wt(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Wt=function(){return!!e})()}var Jt,Kt=function(e){function t(e,n){var o,r,i=n.compName,s=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).theme,u=void 0===s?"light":s;return(0,a.A)(this,t),o=function(e,t,n){return t=(0,l.A)(t),(0,c.A)(e,Wt()?Reflect.construct(t,n||[],(0,l.A)(e).constructor):t.apply(e,n))}(this,t),o.subComponents=[],o.theme="",o.onThemeChange=function(e){"auto"===o.options.theme&&o.setTheme(e)},o.compName=i,o.c=J(i),o.options={},o.container=e,o.$container=$e()(e),o.$container.addClass(["luna-".concat(i),o.c("platform-".concat((r=Q()(),"os x"===r?"mac":r)))]),o.on("changeOption",(function(e,t){if("theme"===e&&t){var n=t;"auto"===t&&(n=Ut().get()),o.setTheme(n),x()(o.subComponents,(function(e){return e.setOption("theme",t)}))}})),Ut().on("change",o.onThemeChange),o.setOption("theme",u),o}return(0,d.A)(t,e),(0,s.A)(t,[{key:"destroy",value:function(){var e=this;this.destroySubComponents();var t=this.$container,n=t.attr("class");x()(n.split(/\s+/),(function(n){y()(n,"luna-".concat(e.compName))&&t.rmClass(n)})),t.html(""),this.emit("destroy"),this.removeAllListeners(),Ut().off("change",this.onThemeChange)}},{key:"setOption",value:function(e,t){var n=this,o=this.options,r={};"string"==typeof e?r[e]=t:r=e,x()(r,(function(e,t){var r=o[t];o[t]=e,e!==r&&n.emit("changeOption",t,e,r)}))}},{key:"getOption",value:function(e){return this.options[e]}},{key:"addSubComponent",value:function(e){e.setOption("theme",this.options.theme),this.subComponents.push(e)}},{key:"removeSubComponent",value:function(e){qt()(this.subComponents,(function(t){return t===e}))}},{key:"destroySubComponents",value:function(){x()(this.subComponents,(function(e){return e.destroy()})),this.subComponents=[]}},{key:"initOptions",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};be()(e,t),It()(this.options,e)}},{key:"find",value:function(e){return this.$container.find(this.c(e))}},{key:"setTheme",value:function(e){var t=this.c,n=this.$container;this.theme&&n.rmClass(t("theme-".concat(this.theme))),n.addClass(t("theme-".concat(e))),this.theme=e}}])}(We()),Vt=n(2228),Zt=n.n(Vt);function Xt(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Xt=function(){return!!e})()}e=n.hmd(e);var en=navigator.userAgent,tn=en.indexOf("Android")>-1||en.indexOf("Adr")>-1,nn=0,on=function(e){function t(e){var n,o,r,i,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return(0,a.A)(this,t),o=this,r=t,i=[e,{compName:"console"},s],r=(0,l.A)(r),(n=(0,c.A)(o,Xt()?Reflect.construct(r,i||[],(0,l.A)(o).constructor):r.apply(o,i))).spaceHeight=0,n.topSpaceHeight=0,n.bottomSpaceHeight=0,n.lastScrollTop=0,n.lastTimestamp=0,n.speedToleranceFactor=100,n.maxSpeedTolerance=2e3,n.minSpeedTolerance=100,n.logs=[],n.displayLogs=[],n.timer={},n.counter={},n.asyncList=[],n.asyncTimer=null,n.isAtBottom=!0,n.groupStack=new(Dt()),n.selectedLog=null,n.onScroll=function(){var e=n.container,t=e.scrollHeight,o=e.offsetHeight,r=e.scrollTop;if(!(r<=0||o+r>t)){var i=!1;(t===o||Math.abs(t-o-r)<1)&&(i=!0),n.isAtBottom=i;var a=n.lastScrollTop,s=n.lastTimestamp,c=jt()(),l=c-s,u=r-a,d=Math.abs(u/l)*n.speedToleranceFactor;l>1e3&&(d=1e3),d>n.maxSpeedTolerance&&(d=n.maxSpeedTolerance),d=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},r=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var o,r,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(o=i.next()).done;)a.push(o.value)}catch(e){r={error:e}}finally{try{o&&!o.done&&(n=i.return)&&n.call(i)}finally{if(r)throw r.error}}return a},i=this&&this.__spreadArray||function(e,t,n){if(n||2===arguments.length)for(var o,r=0,i=t.length;r]*>/g.test(e))try{var t=Oe().parse(e);return De(t,(function(e){e.attrs&&e.attrs.class&&(e.attrs.class=Be(e.attrs.class))})),Oe().stringify(t)}catch(t){return Be(e)}return Be(e)}function De(e,t){for(var n=0,o=e.length;n ";e.reqHeaders&&(n=_e()(e.reqHeaders,(function(e,t){return'Empty \n ")})).join(""));var o="').concat(Tt()(t)," \n ").concat(Tt()(e)," \n ";e.resHeaders&&(o=_e()(e.resHeaders,(function(e,t){return'Empty \n ")})).join(""));var r="";if(e.resTxt){var i=e.resTxt;i.length>Ft&&(i=zt()(i,Ft)),r='').concat(Tt()(t)," \n ").concat(Tt()(e)," \n ').concat(Tt()(i),"
")}var a='Response Headers
\n \n \n ').concat(o,'\n \n
\n Request Headers
\n \n \n ').concat(n,"\n \n
\n \n \n \n \n \n ";St()(e.attributes)||(a=_e()(e.attributes,(function(e){var t=e.name,n=e.value;return'Empty \n ")})).join("")),a='').concat(Tt()(t),' \n ').concat(n," \n Attributes
\n \n \n ').concat(a," \n \n
\n Styles
\n \n Computed Style\n ".concat(u,'\n
\n \n \n \n ').concat(_e()(e.computedStyle,(function(e,t){return'
\n \n ")})).join(""),"\n \n ').concat(Tt()(t)," \n ").concat(e," \n \n ').concat(e,"\n
\n Event Listeners
\n ').concat(Tt()(e.name),'\n
\n \n '.concat("local"===t?"Local":"Session",' Storage\n
\n '))),this._$dataGrid=e.find(ze(".data-grid")),this._$filterText=e.find(ze(".filter-text"))}},{key:"_getVal",value:function(e){return"local"===this._type?localStorage.getItem(e):sessionStorage.getItem(e)}},{key:"_bindEvent",value:function(){var e=this,t=this._type,n=this._devtools;function o(e,t){var o=n.get("sources");if(o)return o.set(e,t),n.showTool("sources"),!0}this._$container.on("click",ze(".refresh-storage"),(function(){n.notify("Refreshed",{icon:"success"}),e.refresh()})).on("click",ze(".clear-storage"),(function(){x()(e._storeData,(function(e){"local"===t?localStorage.removeItem(e.key):sessionStorage.removeItem(e.key)})),e.refresh()})).on("click",ze(".show-detail"),(function(){var t=e._selectedItem,n=e._getVal(t);try{o("object",JSON.parse(n))}catch(e){o("raw",n)}})).on("click",ze(".copy-storage"),(function(){var t=e._selectedItem;Ot()(e._getVal(t)),n.notify("Copied",{icon:"success"})})).on("click",ze(".filter"),(function(){nt.A.prompt("Filter").then((function(t){mt()(t)||(t=Te()(t),e._$filterText.text(t),e._dataGrid.setOption("filter",t))}))})).on("click",ze(".delete-storage"),(function(){var n=e._selectedItem;"local"===t?localStorage.removeItem(n):sessionStorage.removeItem(n),e.refresh()})),this._dataGrid.on("select",(function(t){e._selectedItem=t.data.key,e._updateButtons()})).on("deselect",(function(){e._selectedItem=null,e._updateButtons()})),h.on(h.SCALE,this._updateGridHeight)}}])}();function ko(e,t){e.rmClass(ze("ok")).rmClass(ze("danger")).rmClass(ze("warn")).addClass(ze(t))}function Co(e,t){if(0===t)return"";var n=0,o=0;switch(e){case"cookie":n=30,o=60;break;case"script":n=5,o=10;break;case"stylesheet":n=4,o=8;break;case"image":n=50,o=100}return t>=o?"danger":t>=n?"warn":"ok"}var So=function(){return(0,r.A)((function e(t,n){(0,o.A)(this,e),this._$container=t,this._devtools=n,this._selectedItem=null,this._initTpl(),this._dataGrid=new Kt.A(this._$dataGrid.get(0),{columns:[{id:"key",title:"Key",weight:30},{id:"value",title:"Value",weight:90}],minHeight:60,maxHeight:223}),this._bindEvent()}),[{key:"refresh",value:function(){var e=this._$container,t=this._dataGrid,n=Jt.domain("Network").getCookies().cookies,o=_e()(n,(function(e){return{key:e.name,val:e.value}}));t.clear(),x()(o,(function(e){var n=e.key,o=e.val;t.append({key:n,value:o},{selectable:!0})})),ko(e,Co("cookie",o.length))}},{key:"_initTpl",value:function(){var e=this._$container;e.html(ze('\n Cookie\n \n
\n ')),this._$dataGrid=e.find(ze(".data-grid")),this._$filterText=e.find(ze(".filter-text"))}},{key:"_updateButtons",value:function(){var e=this._$container,t=e.find(ze(".show-detail")),n=e.find(ze(".delete-cookie")),o=e.find(ze(".copy-cookie")),r=ze("btn-disabled");t.addClass(r),n.addClass(r),o.addClass(r),this._selectedItem&&(t.rmClass(r),n.rmClass(r),o.rmClass(r))}},{key:"_getVal",value:function(e){for(var t=Jt.domain("Network").getCookies().cookies,n=0,o=t.length;n\n Script\n
\n \n ').concat(n,"\n
"),r=this._$script;return ko(r,t),r.html(o),this}},{key:"refreshStylesheet",value:function(){var e=[];m()("link").each((function(){"stylesheet"===this.rel&&e.push(this.href)}));var t=Co("stylesheet",(e=wn()(e)).length),n="\n Stylesheet\n
\n \n ').concat(n,"\n
"),r=this._$stylesheet;return ko(r,t),r.html(o),this}},{key:"refreshIframe",value:function(){var e=[];m()("iframe").each((function(){var t=m()(this).attr("src");t&&e.push(t)})),e=wn()(e);var t="\n Iframe\n
\n \n ').concat(t,"\n
");return this._$iframe.html(n),this}},{key:"refreshLocalStorage",value:function(){return this._localStorage.refresh(),this}},{key:"refreshSessionStorage",value:function(){return this._sessionStorage.refresh(),this}},{key:"refreshCookie",value:function(){return this._cookie.refresh(),this}},{key:"refreshImage",value:function(){var e=[],t=this._performance=window.webkitPerformance||window.performance;t&&t.getEntries?this._performance.getEntries().forEach((function(t){if("img"===t.initiatorType||Io(t.name)){if(N()(t.name,"exclude=true"))return;e.push(t.name)}})):m()("img").each((function(){var t=m()(this),n=t.attr("src");"true"!==t.data("exclude")&&e.push(n)}));(e=wn()(e)).sort();var n=Co("image",e.length),o="\n
\n Image\n
\n \n ').concat(o,"\n
"),i=this._$image;return ko(i,n),i.html(r),this}},{key:"show",value:function(){return Oo(t,"show",this,3)([]),this._observeElement&&this._enableObserver(),this.refresh()}},{key:"hide",value:function(){return this._disableObserver(),Oo(t,"hide",this,3)([])}},{key:"_initTpl",value:function(){var e=this._$el;e.html(ze('\n \n \n \n \n \n ')),this._$localStorage=e.find(ze(".local-storage")),this._$sessionStorage=e.find(ze(".session-storage")),this._$cookie=e.find(ze(".cookie")),this._$script=e.find(ze(".script")),this._$stylesheet=e.find(ze(".stylesheet")),this._$iframe=e.find(ze(".iframe")),this._$image=e.find(ze(".image"))}},{key:"_bindEvent",value:function(){var e=this,t=this._$el,n=this._container;function o(e,t){var o=n.get("sources");if(o)return o.set(e,t),n.showTool("sources"),!0}function r(e){return function(t){if(n.get("sources")){t.preventDefault();var r=m()(this).attr("href");"iframe"!==e&&go()(location.href,r)?bo()({url:r,success:function(t){o(e,t)},dataType:"raw"}):o("iframe",r)}}}t.on("click",".eruda-refresh-script",(function(){n.notify("Refreshed",{icon:"success"}),e.refreshScript()})).on("click",".eruda-refresh-stylesheet",(function(){n.notify("Refreshed",{icon:"success"}),e.refreshStylesheet()})).on("click",".eruda-refresh-iframe",(function(){n.notify("Refreshed",{icon:"success"}),e.refreshIframe()})).on("click",".eruda-refresh-image",(function(){n.notify("Refreshed",{icon:"success"}),e.refreshImage()})).on("click",".eruda-img-link",(function(){o("img",m()(this).attr("src"))})).on("click",".eruda-css-link",r("css")).on("click",".eruda-js-link",r("js")).on("click",".eruda-iframe-link",r("iframe"))}},{key:"_rmCfg",value:function(){var e=this.config,t=this._container.get("settings");t&&t.remove(e,"hideErudaSetting").remove(e,"observeElement").remove("Resources")}},{key:"_initCfg",value:function(){var e=this,t=this.config=ce.createCfg("resources",{hideErudaSetting:!0,observeElement:!0});t.get("hideErudaSetting")&&(this._hideErudaSetting=!0),t.get("observeElement")||(this._observeElement=!1),t.on("change",(function(t,n){switch(t){case"hideErudaSetting":return void(e._hideErudaSetting=n);case"observeElement":return e._observeElement=n,n?e._enableObserver():e._disableObserver()}})),this._container.get("settings").text("Resources").switch(t,"hideErudaSetting","Hide Eruda Setting").switch(t,"observeElement","Auto Refresh Elements").separator()}},{key:"_initObserver",value:function(){var e=this;this._observer=new(Nn())((function(t){x()(t,(function(t){e._handleMutation(t)}))}))}},{key:"_handleMutation",value:function(e){var t=this;if(!Ie(e.target)){var n=function(e){var n=function(e){return e.tagName?e.tagName.toLowerCase():""}(e);switch(n){case"script":t.refreshScript();break;case"img":t.refreshImage();break;case"link":t.refreshStylesheet()}};if("attributes"===e.type)n(e.target);else if("childList"===e.type){n(e.target);var o,r=Ao()(e.addedNodes),i=Eo(r=_o()(r,Ao()(e.removedNodes)));try{for(i.s();!(o=i.n()).done;){n(o.value)}}catch(e){i.e(e)}finally{i.f()}}}}},{key:"_enableObserver",value:function(){this._observer.observe(document.documentElement,{attributes:!0,childList:!0,subtree:!0})}},{key:"_disableObserver",value:function(){this._observer.disconnect()}}])}(v);var Mo=/\.(jpeg|jpg|gif|png)$/,Io=function(e){return Mo.test(e)},zo=n(6620),Do=n.n(zo),Bo=Do()(),Fo=[{name:"Location",val:function(){return Tt()(location.href)}},{name:"User Agent",val:navigator.userAgent},{name:"Device",val:["",'
"].join("")},{name:"System",val:[" "),"screen '.concat(screen.width," * ").concat(screen.height," "),"viewport ".concat(window.innerWidth," * ").concat(window.innerHeight," "),"pixel ratio ".concat(window.devicePixelRatio," ",'
"].join("")},{name:"Sponsor this Project",val:function(){return" "),"os '.concat(nn()()," "),"browser ".concat(Bo.name+" "+Bo.version," "+_e()([{name:"Open Collective",link:"https://opencollective.com/eruda"},{name:"Ko-fi",link:"https://ko-fi.com/surunzi"},{name:"Wechat Pay",link:"https://surunzi.com/wechatpay.html"}],(function(e){return"
"}},{name:"About",val:'Eruda v3.4.3'}],Ro=n(1034),Lo=n.n(Ro);function Go(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Go=function(){return!!e})()}function Po(e,t,n,o){var r=(0,f.A)((0,a.A)(1&o?e.prototype:e),t,n);return 2&o&&"function"==typeof r?function(e){return r.apply(n,e)}:r}var Ho=function(e){function t(){var e,r,s,c;return(0,o.A)(this,t),r=this,s=t,s=(0,a.A)(s),(e=(0,i.A)(r,Go()?Reflect.construct(s,c||[],(0,a.A)(r).constructor):s.apply(r,c)))._style=re(n(4657)),e.name="info",e._infos=[],e}return(0,s.A)(t,e),(0,r.A)(t,[{key:"init",value:function(e,n){Po(t,"init",this,3)([e]),this._container=n,this._addDefInfo(),this._bindEvent()}},{key:"destroy",value:function(){Po(t,"destroy",this,3)([]),re.remove(this._style)}},{key:"add",value:function(e,t){var n=this._infos,o=!1;return x()(n,(function(n){e===n.name&&(n.val=t,o=!0)})),o||n.push({name:e,val:t}),this._render(),this}},{key:"get",value:function(e){var t,n=this._infos;return be()(e)?Lo()(n):(x()(n,(function(n){e===n.name&&(t=n.val)})),t)}},{key:"remove",value:function(e){for(var t=this._infos,n=t.length-1;n>=0;n--)t[n].name===e&&t.splice(n,1);return this._render(),this}},{key:"clear",value:function(){return this._infos=[],this._render(),this}},{key:"_addDefInfo",value:function(){var e=this;x()(Fo,(function(t){return e.add(t.name,t.val)}))}},{key:"_render",value:function(){var e=[];x()(this._infos,(function(t){var n=t.name,o=t.val;lt()(o)&&(o=o()),e.push({name:n,val:o})}));var t=" ")})).join(" ")+"".concat(e.name,' ').concat(e.link.replace("https://","")," ".concat(_e()(e,(function(e){return'
");this._renderHtml(t)}},{key:"_bindEvent",value:function(){var e=this._container;this._$el.on("click",ze(".copy"),(function(){var t=m()(this).parent().parent(),n=t.find(ze(".title")).text(),o=t.find(ze(".content")).text();Ot()("".concat(n,": ").concat(o)),e.notify("Copied",{icon:"success"})}))}},{key:"_renderHtml",value:function(e){e!==this._lastHtml&&(this._lastHtml=e,this._$el.html(e))}}])}(v),Yo=n(6911),$o=n(894),qo=n.n($o),Qo=n(4249),Uo=n.n(Qo),Wo=n(1714);function Jo(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Jo=function(){return!!e})()}function Ko(e,t,n,o){var r=(0,f.A)((0,a.A)(1&o?e.prototype:e),t,n);return 2&o&&"function"==typeof r?function(e){return r.apply(n,e)}:r}var Vo=function(e){function t(){var e,r,s,c;return(0,o.A)(this,t),r=this,s=t,s=(0,a.A)(s),(e=(0,i.A)(r,Jo()?Reflect.construct(s,c||[],(0,a.A)(r).constructor):s.apply(r,c)))._style=re(n(4831)),e.name="sources",e._showLineNum=!0,e}return(0,s.A)(t,e),(0,r.A)(t,[{key:"init",value:function(e,n){Ko(t,"init",this,3)([e]),this._container=n,this._bindEvent(),this._initCfg()}},{key:"destroy",value:function(){Ko(t,"destroy",this,3)([]),re.remove(this._style),this._rmCfg()}},{key:"set",value:function(e,t){if("img"===e){this._isFetchingData=!0;var n=new Image,o=this;return n.onload=function(){o._isFetchingData=!1,o._data={type:"img",val:{width:this.width,height:this.height,src:t}},o._render()},n.onerror=function(){o._isFetchingData=!1},void(n.src=t)}return this._data={type:e,val:t},this._render(),this}},{key:"show",value:function(){return Ko(t,"show",this,3)([]),this._data||this._isFetchingData||this._renderDef(),this}},{key:"_renderDef",value:function(){var e=this;if(this._html)return this._data={type:"html",val:this._html},this._render();this._isGettingHtml||(this._isGettingHtml=!0,bo()({url:location.href,success:function(t){return e._html=t},error:function(){return e._html="Sorry, unable to fetch source code:("},complete:function(){e._isGettingHtml=!1,e._renderDef()},dataType:"raw"}))}},{key:"_bindEvent",value:function(){var e=this;this._container.on("showTool",(function(t,n){t!==e.name&&n.name===e.name&&delete e._data}))}},{key:"_rmCfg",value:function(){var e=this.config,t=this._container.get("settings");t&&t.remove(e,"showLineNum").remove("Sources")}},{key:"_initCfg",value:function(){var e=this,t=this.config=ce.createCfg("sources",{showLineNum:!0});t.get("showLineNum")||(this._showLineNum=!1),t.on("change",(function(t,n){"showLineNum"!==t||(e._showLineNum=n)})),this._container.get("settings").text("Sources").switch(t,"showLineNum","Show Line Numbers").separator()}},{key:"_render",value:function(){switch(this._isInit=!0,this._data.type){case"html":case"js":case"css":return this._renderCode();case"img":return this._renderImg();case"object":return this._renderObj();case"raw":return this._renderRaw();case"iframe":return this._renderIframe()}}},{key:"_renderImg",value:function(){var e=this._data.val,t=e.width,n=e.height,o=e.src;this._renderHtml('').concat(Tt()(e.name),'
\n
"),v.default.parse(i)[0].attrs));var i},t.setAttributeValue=function(e){var t=e.nodeId,n=e.name,o=e.value;(0,l.getNode)(t).setAttribute(n,o)},t.setInspectedNode=function(e){var t=(0,l.getNode)(e.nodeId);O.unshift(t),O.length>5&&O.pop();for(var n=0;n<5;n++)(0,k.setGlobal)("$".concat(n),O[n])},t.setNodeValue=function(e){var t=e.nodeId,n=e.value;(0,l.getNode)(t).nodeValue=n},t.setOuterHTML=function(e){var t=e.nodeId,n=e.outerHTML;(0,l.getNode)(t).outerHTML=n},t.getDOMNodeId=function(e){var t=e.node;return{nodeId:c.getOrCreateNodeId(t)}},t.getDOMNode=function(e){var t=e.nodeId;return{node:(0,l.getNode)(t)}},t.getTopLayerElements=function(){return{nodeIds:[]}},t.getNodesForSubtreeByStyle=function(){return{nodeIds:[]}};var s=a(n(8665)),c=i(n(9893)),l=n(9893),u=i(n(2484)),d=a(n(8757)),h=a(n(3693)),f=a(n(4236)),p=a(n(9464)),v=a(n(9548)),g=a(n(3915)),m=a(n(438)),b=a(n(3249)),y=a(n(96)),A=a(n(9100)),w=a(n(769)),_=a(n(8862)),x=a(n(4069)),k=n(2627),C=n(916);var S,E=!1;(S=Element.prototype.attachShadow)&&(Element.prototype.attachShadow=function(e){var t=S.apply(this,[e]);if(!c.isValidNode(this))return t;if(this.chobitsuShadowRoot=t,E){d.default.observe(t);var n=(0,l.getNodeId)(this);n&&s.default.trigger("DOM.shadowRootPushed",{hostId:n,root:c.wrap(t,{depth:1})})}return t});var T=new Map;function N(e){for(var t=[e],n=e.parentNode;n;){if(t.push(n),r=(0,l.getNodeId)(n))break;n=n.parentNode}for(;t.length;){var o=t.pop(),r=(0,l.getNodeId)(o);s.default.trigger("DOM.setChildNodes",{parentId:r,nodes:c.getChildNodes(o,1)})}return(0,l.getNodeId)(e)}var O=[];function j(e,t){for(var n=c.filterNodes(e.childNodes),o=0,r=n.length;o3&&void 0!==arguments[3]&&arguments[3],i=this.c,a=(0,o.A)(t);if(null===t)return"");return r&&(d+=this.objToHtml(this.map[s])),d+'
");return i&&(b+=this.objToHtml(n)),b+'
t.right||e.bottom\n ${title}\n \n \n `);\n }\n else {\n html += `${title} `;\n }\n fillerRowHtml += '';\n });\n this.$headerRow.html(html);\n this.$fillerRow.html(fillerRowHtml);\n }\n renderResizers() {\n let resizers = '';\n const len = this.options.columns.length - 1;\n for (let i = 0; i < len; i++) {\n resizers += this.c(``);\n }\n this.$container.append(resizers);\n this.$resizers = this.find('.resizer');\n }\n initTpl() {\n this.$container.html(this.c(stripIndent `\n \n
\n \n \n \n
\n \n \n
`;\n lines = lines.map((val) => escape(val));\n const stack = `
')}${hightlighted}`;\n }\n formatFn(val) {\n return `${this.formatJs(val.toString())}`;\n }\n formatElName(val) {\n const { id, className } = val;\n let ret = val.tagName.toLowerCase();\n if (id !== '')\n ret += `#${id}`;\n if (isStr(className)) {\n let classes = '';\n each(className.split(/\\s+/g), (val) => {\n if (val.trim() === '')\n return;\n classes += `.${val}`;\n });\n ret += classes;\n }\n return ret;\n }\n formatEl(val) {\n const id = uniqId();\n this.elements[id] = val;\n return this.console.c(``);\n }\n}\nfunction correctStyle(val) {\n val = lowerCase(val);\n const rules = val.split(';');\n const style = {};\n each(rules, (rule) => {\n if (!contain(rule, ':'))\n return;\n const [name, val] = rule.split(':');\n style[trim(name)] = trim(val);\n });\n style['display'] = 'inline-block';\n style['max-width'] = '100%';\n delete style.width;\n delete style.height;\n let ret = '';\n each(style, (val, key) => {\n ret += `${key}:${val};`;\n });\n return ret;\n}\nfunction stringify(obj, options, cb) {\n const result = stringifyAll(obj, options);\n nextTick(() => cb(result));\n}\n","import Emitter from 'licia/Emitter';\nimport $ from 'licia/$';\nimport { classPrefix, getPlatform } from './util';\nimport each from 'licia/each';\nimport extend from 'licia/extend';\nimport defaults from 'licia/defaults';\nimport remove from 'licia/remove';\nimport theme from 'licia/theme';\nimport startWith from 'licia/startWith';\nexport default class Component extends Emitter {\n constructor(container, { compName }, { theme: t = 'light' } = {}) {\n super();\n this.subComponents = [];\n this.theme = '';\n this.onThemeChange = (t) => {\n if (this.options.theme === 'auto') {\n this.setTheme(t);\n }\n };\n this.compName = compName;\n this.c = classPrefix(compName);\n this.options = {};\n this.container = container;\n this.$container = $(container);\n this.$container.addClass([\n `luna-${compName}`,\n this.c(`platform-${getPlatform()}`),\n ]);\n this.on('changeOption', (name, val) => {\n if (name === 'theme' && val) {\n let t = val;\n if (val === 'auto') {\n t = theme.get();\n }\n this.setTheme(t);\n each(this.subComponents, (component) => component.setOption('theme', val));\n }\n });\n theme.on('change', this.onThemeChange);\n this.setOption('theme', t);\n }\n destroy() {\n this.destroySubComponents();\n const { $container } = this;\n const classes = $container.attr('class');\n each(classes.split(/\\s+/), (c) => {\n if (startWith(c, `luna-${this.compName}`)) {\n $container.rmClass(c);\n }\n });\n $container.html('');\n this.emit('destroy');\n this.removeAllListeners();\n theme.off('change', this.onThemeChange);\n }\n setOption(name, val) {\n const options = this.options;\n let newOptions = {};\n if (typeof name === 'string') {\n newOptions[name] = val;\n }\n else {\n newOptions = name;\n }\n each(newOptions, (val, name) => {\n const oldVal = options[name];\n options[name] = val;\n if (val === oldVal) {\n return;\n }\n this.emit('changeOption', name, val, oldVal);\n });\n }\n getOption(name) {\n return this.options[name];\n }\n addSubComponent(component) {\n component.setOption('theme', this.options.theme);\n this.subComponents.push(component);\n }\n removeSubComponent(component) {\n remove(this.subComponents, (com) => com === component);\n }\n destroySubComponents() {\n each(this.subComponents, (component) => component.destroy());\n this.subComponents = [];\n }\n initOptions(options, defs = {}) {\n defaults(options, defs);\n extend(this.options, options);\n }\n find(selector) {\n return this.$container.find(this.c(selector));\n }\n setTheme(theme) {\n const { c, $container } = this;\n if (this.theme) {\n $container.rmClass(c(`theme-${this.theme}`));\n }\n $container.addClass(c(`theme-${theme}`));\n this.theme = theme;\n }\n}\n","import Log from './Log';\nimport isUndef from 'licia/isUndef';\nimport perfNow from 'licia/perfNow';\nimport now from 'licia/now';\nimport isStr from 'licia/isStr';\nimport extend from 'licia/extend';\nimport uniqId from 'licia/uniqId';\nimport isRegExp from 'licia/isRegExp';\nimport isFn from 'licia/isFn';\nimport Stack from 'licia/Stack';\nimport isEmpty from 'licia/isEmpty';\nimport contain from 'licia/contain';\nimport copy from 'licia/copy';\nimport each from 'licia/each';\nimport toArr from 'licia/toArr';\nimport keys from 'licia/keys';\nimport last from 'licia/last';\nimport throttle from 'licia/throttle';\nimport xpath from 'licia/xpath';\nimport lowerCase from 'licia/lowerCase';\nimport dateFormat from 'licia/dateFormat';\nimport isHidden from 'licia/isHidden';\nimport stripIndent from 'licia/stripIndent';\nimport ResizeSensor from 'licia/ResizeSensor';\nimport isNull from 'licia/isNull';\nimport Component from '../share/Component';\nimport raf from 'licia/raf';\nimport trim from 'licia/trim';\nimport { exportCjs } from '../share/util';\nconst u = navigator.userAgent;\nconst isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;\nlet id = 0;\nexport default class Console extends Component {\n constructor(container, options = {}) {\n super(container, { compName: 'console' }, options);\n this.spaceHeight = 0;\n this.topSpaceHeight = 0;\n this.bottomSpaceHeight = 0;\n this.lastScrollTop = 0;\n this.lastTimestamp = 0;\n this.speedToleranceFactor = 100;\n this.maxSpeedTolerance = 2000;\n this.minSpeedTolerance = 100;\n this.logs = [];\n this.displayLogs = [];\n this.timer = {};\n this.counter = {};\n this.asyncList = [];\n this.asyncTimer = null;\n this.isAtBottom = true;\n this.groupStack = new Stack();\n this.selectedLog = null;\n this.onScroll = () => {\n const { scrollHeight, offsetHeight, scrollTop } = this\n .container;\n if (scrollTop <= 0)\n return;\n if (offsetHeight + scrollTop > scrollHeight)\n return;\n let isAtBottom = false;\n if (scrollHeight === offsetHeight) {\n isAtBottom = true;\n }\n else if (Math.abs(scrollHeight - offsetHeight - scrollTop) < 1) {\n isAtBottom = true;\n }\n this.isAtBottom = isAtBottom;\n const lastScrollTop = this.lastScrollTop;\n const lastTimestamp = this.lastTimestamp;\n const timestamp = now();\n const duration = timestamp - lastTimestamp;\n const distance = scrollTop - lastScrollTop;\n const speed = Math.abs(distance / duration);\n let speedTolerance = speed * this.speedToleranceFactor;\n if (duration > 1000) {\n speedTolerance = 1000;\n }\n if (speedTolerance > this.maxSpeedTolerance) {\n speedTolerance = this.maxSpeedTolerance;\n }\n if (speedTolerance < this.minSpeedTolerance) {\n speedTolerance = this.minSpeedTolerance;\n }\n this.lastScrollTop = scrollTop;\n this.lastTimestamp = timestamp;\n let topTolerance = 0;\n let bottomTolerance = 0;\n if (lastScrollTop < scrollTop) {\n topTolerance = this.minSpeedTolerance;\n bottomTolerance = speedTolerance;\n }\n else {\n topTolerance = speedTolerance;\n bottomTolerance = this.minSpeedTolerance;\n }\n if (this.topSpaceHeight < scrollTop - topTolerance &&\n this.topSpaceHeight + this.el.offsetHeight >\n scrollTop + offsetHeight + bottomTolerance) {\n return;\n }\n this.renderViewport({\n topTolerance: topTolerance * 2,\n bottomTolerance: bottomTolerance * 2,\n });\n };\n this.initTpl();\n this.initOptions(options, {\n maxNum: 0,\n asyncRender: true,\n showHeader: false,\n filter: '',\n level: ['verbose', 'info', 'warning', 'error'],\n accessGetter: false,\n unenumerable: true,\n lazyEvaluation: true,\n });\n this.$el = this.find('.logs');\n this.el = this.$el.get(0);\n this.$fakeEl = this.find('.fake-logs');\n this.fakeEl = this.$fakeEl.get(0);\n this.$space = this.find('.logs-space');\n this.space = this.$space.get(0);\n if (isAndroid) {\n this.speedToleranceFactor = 800;\n this.maxSpeedTolerance = 3000;\n this.minSpeedTolerance = 800;\n }\n this.resizeSensor = new ResizeSensor(container);\n this.renderViewport = throttle((options) => {\n this._renderViewport(options);\n }, 16);\n this.global = {\n copy(value) {\n if (!isStr(value))\n value = JSON.stringify(value, null, 2);\n copy(value);\n },\n $(selectors) {\n return document.querySelector(selectors);\n },\n $$(selectors) {\n return toArr(document.querySelectorAll(selectors));\n },\n $x(path) {\n return xpath(path);\n },\n clear: () => {\n this.clear();\n },\n dir: (value) => {\n this.dir(value);\n },\n table: (data, columns) => {\n this.table(data, columns);\n },\n keys,\n };\n this.bindEvent();\n }\n setGlobal(name, val) {\n this.global[name] = val;\n }\n destroy() {\n this.$container.off('scroll', this.onScroll);\n this.resizeSensor.destroy();\n super.destroy();\n }\n count(label = 'default') {\n const { counter } = this;\n !isUndef(counter[label]) ? counter[label]++ : (counter[label] = 1);\n this.info(`${label}: ${counter[label]}`);\n }\n countReset(label = 'default') {\n this.counter[label] = 0;\n }\n assert(...args) {\n if (isEmpty(args))\n return;\n const exp = args.shift();\n if (!exp) {\n if (args.length === 0)\n args.unshift('console.assert');\n args.unshift('Assertion failed: ');\n this.insert('error', args);\n }\n }\n log(...args) {\n if (isEmpty(args))\n return;\n this.insert('log', args);\n }\n debug(...args) {\n if (isEmpty(args))\n return;\n this.insert('debug', args);\n }\n dir(obj) {\n if (isUndef(obj))\n return;\n this.insert('dir', [obj]);\n }\n table(...args) {\n if (isEmpty(args))\n return;\n this.insert('table', args);\n }\n time(name = 'default') {\n if (this.timer[name]) {\n return this.insert('warn', [`Timer '${name}' already exists`]);\n }\n this.timer[name] = perfNow();\n }\n timeLog(name = 'default') {\n const startTime = this.timer[name];\n if (!startTime) {\n return this.insert('warn', [`Timer '${name}' does not exist`]);\n }\n this.info(`${name}: ${perfNow() - startTime}ms`);\n }\n timeEnd(name = 'default') {\n this.timeLog(name);\n delete this.timer[name];\n }\n clear(silent = false) {\n this.logs = [];\n this.displayLogs = [];\n this.selectLog(null);\n this.lastLog = undefined;\n this.counter = {};\n this.timer = {};\n this.groupStack = new Stack();\n this.asyncList = [];\n if (this.asyncTimer) {\n clearTimeout(this.asyncTimer);\n this.asyncTimer = null;\n }\n if (silent) {\n this.render();\n }\n else {\n this.insert('log', [\n '%cConsole was cleared',\n 'color:#808080;font-style:italic;',\n ]);\n }\n }\n info(...args) {\n if (isEmpty(args))\n return;\n this.insert('info', args);\n }\n error(...args) {\n if (isEmpty(args))\n return;\n this.insert('error', args);\n }\n warn(...args) {\n if (isEmpty(args))\n return;\n this.insert('warn', args);\n }\n group(...args) {\n this.insert({\n type: 'group',\n args,\n ignoreFilter: true,\n });\n }\n groupCollapsed(...args) {\n this.insert({\n type: 'groupCollapsed',\n args,\n ignoreFilter: true,\n });\n }\n groupEnd() {\n this.insert('groupEnd');\n }\n evaluate(code) {\n this.insert({\n type: 'input',\n args: [code],\n ignoreFilter: true,\n });\n try {\n this.output(this.evalJs(code));\n }\n catch (e) {\n this.insert({\n type: 'error',\n ignoreFilter: true,\n args: [e],\n });\n }\n }\n html(...args) {\n this.insert('html', args);\n }\n toggleGroup(log) {\n const { targetGroup } = log;\n targetGroup.collapsed\n ? this.openGroup(log)\n : this.collapseGroup(log);\n }\n output(val) {\n this.insert({\n type: 'output',\n args: [val],\n ignoreFilter: true,\n });\n }\n render() {\n const { logs, selectedLog } = this;\n this.$el.html('');\n this.isAtBottom = true;\n this.updateBottomSpace(0);\n this.updateTopSpace(0);\n this.displayLogs = [];\n for (let i = 0, len = logs.length; i < len; i++) {\n this.attachLog(logs[i]);\n }\n if (selectedLog) {\n if (!contain(this.displayLogs, selectedLog)) {\n this.selectLog(null);\n }\n }\n }\n insert(type, args) {\n const { showHeader, asyncRender } = this.options;\n let header;\n if (showHeader) {\n header = {\n time: getCurTime(),\n from: getFrom(),\n };\n }\n if (asyncRender) {\n return this.insertAsync(type, args, header);\n }\n this.insertSync(type, args, header);\n }\n insertAsync(type, args, header) {\n this.asyncList.push([type, args, header]);\n this.handleAsyncList();\n }\n insertSync(type, args, header) {\n const { logs, groupStack } = this;\n const { maxNum, accessGetter, unenumerable, lazyEvaluation } = this.options;\n let options;\n if (isStr(type)) {\n options = {\n type: type,\n args: args,\n header,\n };\n }\n else {\n options = type;\n }\n if (options.type === 'groupEnd') {\n const lastLog = this.lastLog;\n lastLog.groupEnd();\n this.groupStack.pop();\n return;\n }\n if (groupStack.size > 0) {\n options.group = groupStack.peek();\n }\n extend(options, {\n id: ++id,\n accessGetter,\n unenumerable,\n lazyEvaluation,\n });\n if (options.type === 'group' || options.type === 'groupCollapsed') {\n const group = {\n id: uniqId('group'),\n collapsed: false,\n parent: groupStack.peek(),\n indentLevel: groupStack.size + 1,\n };\n if (options.type === 'groupCollapsed')\n group.collapsed = true;\n options.targetGroup = group;\n groupStack.push(group);\n }\n let log = new Log(this, options);\n log.on('updateHeight', () => {\n this.isAtBottom = false;\n this.renderViewport();\n });\n const lastLog = this.lastLog;\n if (lastLog &&\n !contain(['html', 'group', 'groupCollapsed'], log.type) &&\n lastLog.type === log.type &&\n log.isSimple() &&\n lastLog.text() === log.text()) {\n lastLog.addCount();\n if (log.header)\n lastLog.updateTime(log.header.time);\n log = lastLog;\n this.detachLog(lastLog);\n }\n else {\n logs.push(log);\n this.lastLog = log;\n }\n if (maxNum !== 0 && logs.length > maxNum) {\n const firstLog = logs[0];\n this.detachLog(firstLog);\n logs.shift();\n }\n this.attachLog(log);\n this.emit('insert', log);\n }\n updateTopSpace(height) {\n this.topSpaceHeight = height;\n this.el.style.top = height + 'px';\n }\n updateBottomSpace(height) {\n this.bottomSpaceHeight = height;\n }\n updateSpace(height) {\n if (this.spaceHeight === height)\n return;\n this.spaceHeight = height;\n this.space.style.height = height + 'px';\n }\n detachLog(log) {\n const { displayLogs } = this;\n const idx = displayLogs.indexOf(log);\n if (idx > -1) {\n displayLogs.splice(idx, 1);\n this.renderViewport();\n }\n }\n attachLog(log) {\n if (!this.filterLog(log) || log.collapsed)\n return;\n const { displayLogs } = this;\n if (displayLogs.length === 0) {\n displayLogs.push(log);\n this.renderViewport();\n return;\n }\n const lastDisplayLog = last(displayLogs);\n if (log.id > lastDisplayLog.id) {\n displayLogs.push(log);\n this.renderViewport();\n return;\n }\n let startIdx = 0;\n let endIdx = displayLogs.length - 1;\n let middleLog;\n let middleIdx = 0;\n while (startIdx <= endIdx) {\n middleIdx = startIdx + Math.floor((endIdx - startIdx) / 2);\n middleLog = displayLogs[middleIdx];\n if (middleLog.id === log.id) {\n return;\n }\n if (middleLog.id < log.id) {\n startIdx = middleIdx + 1;\n }\n else {\n endIdx = middleIdx - 1;\n }\n }\n if (middleLog.id < log.id) {\n displayLogs.splice(middleIdx + 1, 0, log);\n }\n else {\n displayLogs.splice(middleIdx, 0, log);\n }\n this.renderViewport();\n }\n handleAsyncList(timeout = 20) {\n const asyncList = this.asyncList;\n if (this.asyncTimer)\n return;\n this.asyncTimer = setTimeout(() => {\n this.asyncTimer = null;\n let done = false;\n const len = asyncList.length;\n let timeout, num;\n if (len < 1000) {\n num = 200;\n timeout = 400;\n }\n else if (len < 5000) {\n num = 500;\n timeout = 800;\n }\n else if (len < 10000) {\n num = 800;\n timeout = 1000;\n }\n else if (len < 25000) {\n num = 1000;\n timeout = 1200;\n }\n else if (len < 50000) {\n num = 1500;\n timeout = 1500;\n }\n else {\n num = 2000;\n timeout = 2500;\n }\n if (num > len) {\n num = len;\n done = true;\n }\n for (let i = 0; i < num; i++) {\n const [type, args, header] = asyncList.shift();\n this.insertSync(type, args, header);\n }\n if (!done) {\n raf(() => this.handleAsyncList(timeout));\n }\n }, timeout);\n }\n injectGlobal() {\n each(this.global, (val, name) => {\n if (window[name])\n return;\n window[name] = val;\n });\n }\n clearGlobal() {\n each(this.global, (val, name) => {\n if (window[name] && window[name] === val) {\n delete window[name];\n }\n });\n }\n evalJs(jsInput) {\n let ret;\n this.injectGlobal();\n try {\n ret = eval.call(window, `(${jsInput})`);\n }\n catch (e) {\n ret = eval.call(window, jsInput);\n }\n this.setGlobal('$_', ret);\n this.clearGlobal();\n return ret;\n }\n filterLog(log) {\n const { level } = this.options;\n let { filter } = this.options;\n if (log.ignoreFilter) {\n return true;\n }\n if (!contain(level, log.level)) {\n return false;\n }\n if (filter) {\n if (isFn(filter)) {\n return filter(log);\n }\n else if (isRegExp(filter)) {\n return filter.test(lowerCase(log.text()));\n }\n else if (isStr(filter)) {\n filter = trim(filter);\n if (filter) {\n return contain(lowerCase(log.text()), lowerCase(filter));\n }\n }\n }\n return true;\n }\n collapseGroup(log) {\n const { targetGroup } = log;\n targetGroup.collapsed = true;\n log.updateIcon('caret-right');\n this.updateGroup(log);\n }\n openGroup(log) {\n const { targetGroup } = log;\n targetGroup.collapsed = false;\n log.updateIcon('caret-down');\n this.updateGroup(log);\n }\n updateGroup(log) {\n const { targetGroup } = log;\n const { logs } = this;\n const len = logs.length;\n let i = logs.indexOf(log) + 1;\n while (i < len) {\n const log = logs[i];\n if (!log.checkGroup() && log.group === targetGroup) {\n break;\n }\n log.collapsed ? this.detachLog(log) : this.attachLog(log);\n i++;\n }\n }\n selectLog(log) {\n if (this.selectedLog) {\n this.selectedLog.deselect();\n this.selectedLog = null;\n }\n if (!isNull(log)) {\n this.selectedLog = log;\n this.selectedLog?.select();\n this.emit('select', log);\n }\n else {\n this.emit('deselect');\n }\n }\n bindEvent() {\n const { $el, c } = this;\n this.resizeSensor.addListener(this.renderViewport);\n const self = this;\n $el.on('click', c('.log-container'), function () {\n self.selectLog(this.log);\n });\n this.on('changeOption', (name, val) => {\n const { logs } = this;\n switch (name) {\n case 'maxNum':\n if (val > 0 && logs.length > val) {\n this.logs = logs.slice(logs.length - val);\n this.render();\n }\n break;\n case 'filter':\n this.render();\n break;\n case 'level':\n this.options.level = toArr(val);\n this.render();\n break;\n }\n });\n this.$container.on('scroll', this.onScroll);\n }\n _renderViewport({ topTolerance = 500, bottomTolerance = 500 } = {}) {\n const { el, container, space } = this;\n if (isHidden(container))\n return;\n const { scrollTop, offsetHeight } = container;\n const containerWidth = space.getBoundingClientRect().width;\n const top = scrollTop - topTolerance;\n const bottom = scrollTop + offsetHeight + bottomTolerance;\n const { displayLogs } = this;\n let topSpaceHeight = 0;\n let bottomSpaceHeight = 0;\n let currentHeight = 0;\n const len = displayLogs.length;\n const { fakeEl } = this;\n const fakeFrag = document.createDocumentFragment();\n const logs = [];\n for (let i = 0; i < len; i++) {\n const log = displayLogs[i];\n const { width, height } = log;\n if (height === 0 || width !== containerWidth) {\n fakeFrag.appendChild(log.container);\n logs.push(log);\n }\n }\n if (logs.length > 0) {\n fakeEl.appendChild(fakeFrag);\n for (let i = 0, len = logs.length; i < len; i++) {\n logs[i].updateSize();\n }\n fakeEl.textContent = '';\n }\n const frag = document.createDocumentFragment();\n for (let i = 0; i < len; i++) {\n const log = displayLogs[i];\n const { container, height } = log;\n if (currentHeight > bottom) {\n bottomSpaceHeight += height;\n }\n else if (currentHeight + height > top) {\n frag.appendChild(container);\n }\n else if (currentHeight < top) {\n topSpaceHeight += height;\n }\n currentHeight += height;\n }\n this.updateSpace(currentHeight);\n this.updateTopSpace(topSpaceHeight);\n this.updateBottomSpace(bottomSpaceHeight);\n while (el.firstChild) {\n if (el.lastChild) {\n el.removeChild(el.lastChild);\n }\n }\n el.appendChild(frag);\n const { scrollHeight } = container;\n if (this.isAtBottom && scrollTop <= scrollHeight - offsetHeight) {\n container.scrollTop = 10000000;\n }\n }\n initTpl() {\n this.$container.html(this.c(stripIndent `\n ${escape(data.data)}`\n }\n\n let reqHeaders = ' '\n if (data.reqHeaders) {\n reqHeaders = map(data.reqHeaders, (val, key) => {\n return `Empty \n `\n }).join('')\n }\n\n let resHeaders = '${escape(key)} \n ${escape(val)} \n '\n if (data.resHeaders) {\n resHeaders = map(data.resHeaders, (val, key) => {\n return `Empty \n `\n }).join('')\n }\n\n let resTxt = ''\n if (data.resTxt) {\n let text = data.resTxt\n if (text.length > MAX_RES_LEN) {\n text = truncate(text, MAX_RES_LEN)\n }\n resTxt = `${escape(key)} \n ${escape(val)} \n ${escape(text)}`\n }\n\n const html = `Response Headers
\n \n \n ${resHeaders}\n \n
\n Request Headers
\n \n \n ${reqHeaders}\n \n
\n '\n if (!isEmpty(data.attributes)) {\n attributes = map(data.attributes, ({ name, value }) => {\n return `Empty \n `\n }).join('')\n }\n attributes = `${escape(name)} \n ${value} \n Attributes
\n \n \n ${attributes} \n \n
\n Styles
\n \n Computed Style\n ${toggleButton}\n
\n \n \n \n ${map(data.computedStyle, (val, key) => {\n return `
\n \n `\n }).join('')}\n \n ${escape(key)} \n ${val} \n \n ${listeners}\n
\n Event Listeners
\n ${escape(snippet.name)}\n
\n \n ${type === 'local' ? 'Local' : 'Session'} Storage\n
\n `)\n )\n\n this._$dataGrid = $container.find(c('.data-grid'))\n this._$filterText = $container.find(c('.filter-text'))\n }\n _getVal(key) {\n return this._type === 'local'\n ? localStorage.getItem(key)\n : sessionStorage.getItem(key)\n }\n _updateGridHeight = (scale) => {\n this._dataGrid.setOption({\n minHeight: 60 * scale,\n maxHeight: 223 * scale,\n })\n }\n _bindEvent() {\n const type = this._type\n const devtools = this._devtools\n\n this._$container\n .on('click', c('.refresh-storage'), () => {\n devtools.notify('Refreshed', { icon: 'success' })\n this.refresh()\n })\n .on('click', c('.clear-storage'), () => {\n each(this._storeData, (val) => {\n if (type === 'local') {\n localStorage.removeItem(val.key)\n } else {\n sessionStorage.removeItem(val.key)\n }\n })\n this.refresh()\n })\n .on('click', c('.show-detail'), () => {\n const key = this._selectedItem\n const val = this._getVal(key)\n\n try {\n showSources('object', JSON.parse(val))\n } catch {\n showSources('raw', val)\n }\n })\n .on('click', c('.copy-storage'), () => {\n const key = this._selectedItem\n copy(this._getVal(key))\n devtools.notify('Copied', { icon: 'success' })\n })\n .on('click', c('.filter'), () => {\n LunaModal.prompt('Filter').then((filter) => {\n if (isNull(filter)) return\n filter = trim(filter)\n this._$filterText.text(filter)\n this._dataGrid.setOption('filter', filter)\n })\n })\n .on('click', c('.delete-storage'), () => {\n const key = this._selectedItem\n\n if (type === 'local') {\n localStorage.removeItem(key)\n } else {\n sessionStorage.removeItem(key)\n }\n\n this.refresh()\n })\n\n function showSources(type, data) {\n const sources = devtools.get('sources')\n if (!sources) return\n\n sources.set(type, data)\n\n devtools.showTool('sources')\n\n return true\n }\n\n this._dataGrid\n .on('select', (node) => {\n this._selectedItem = node.data.key\n this._updateButtons()\n })\n .on('deselect', () => {\n this._selectedItem = null\n this._updateButtons()\n })\n\n emitter.on(emitter.SCALE, this._updateGridHeight)\n }\n}\n","import { classPrefix as c } from '../lib/util'\n\nexport function setState($el, state) {\n $el\n .rmClass(c('ok'))\n .rmClass(c('danger'))\n .rmClass(c('warn'))\n .addClass(c(state))\n}\n\nexport function getState(type, len) {\n if (len === 0) return ''\n\n let warn = 0\n let danger = 0\n\n switch (type) {\n case 'cookie':\n warn = 30\n danger = 60\n break\n case 'script':\n warn = 5\n danger = 10\n break\n case 'stylesheet':\n warn = 4\n danger = 8\n break\n case 'image':\n warn = 50\n danger = 100\n break\n }\n\n if (len >= danger) return 'danger'\n if (len >= warn) return 'warn'\n\n return 'ok'\n}\n","import map from 'licia/map'\nimport trim from 'licia/trim'\nimport isNull from 'licia/isNull'\nimport each from 'licia/each'\nimport copy from 'licia/copy'\nimport LunaModal from 'luna-modal'\nimport LunaDataGrid from 'luna-data-grid'\nimport { setState, getState } from './util'\nimport chobitsu from '../lib/chobitsu'\nimport { classPrefix as c } from '../lib/util'\n\nexport default class Cookie {\n constructor($container, devtools) {\n this._$container = $container\n this._devtools = devtools\n this._selectedItem = null\n\n this._initTpl()\n this._dataGrid = new LunaDataGrid(this._$dataGrid.get(0), {\n columns: [\n {\n id: 'key',\n title: 'Key',\n weight: 30,\n },\n {\n id: 'value',\n title: 'Value',\n weight: 90,\n },\n ],\n minHeight: 60,\n maxHeight: 223,\n })\n\n this._bindEvent()\n }\n refresh() {\n const $container = this._$container\n const dataGrid = this._dataGrid\n\n const { cookies } = chobitsu.domain('Network').getCookies()\n const cookieData = map(cookies, ({ name, value }) => ({\n key: name,\n val: value,\n }))\n\n dataGrid.clear()\n each(cookieData, ({ key, val }) => {\n dataGrid.append(\n {\n key,\n value: val,\n },\n {\n selectable: true,\n }\n )\n })\n\n const cookieState = getState('cookie', cookieData.length)\n setState($container, cookieState)\n }\n _initTpl() {\n const $container = this._$container\n\n $container.html(\n c(`\n Cookie\n
\n `)\n )\n\n this._$dataGrid = $container.find(c('.data-grid'))\n this._$filterText = $container.find(c('.filter-text'))\n }\n _updateButtons() {\n const $container = this._$container\n const $showDetail = $container.find(c('.show-detail'))\n const $deleteCookie = $container.find(c('.delete-cookie'))\n const $copyCookie = $container.find(c('.copy-cookie'))\n const btnDisabled = c('btn-disabled')\n\n $showDetail.addClass(btnDisabled)\n $deleteCookie.addClass(btnDisabled)\n $copyCookie.addClass(btnDisabled)\n\n if (this._selectedItem) {\n $showDetail.rmClass(btnDisabled)\n $deleteCookie.rmClass(btnDisabled)\n $copyCookie.rmClass(btnDisabled)\n }\n }\n _getVal(key) {\n const { cookies } = chobitsu.domain('Network').getCookies()\n\n for (let i = 0, len = cookies.length; i < len; i++) {\n if (cookies[i].name === key) {\n return cookies[i].value\n }\n }\n\n return ''\n }\n _bindEvent() {\n const devtools = this._devtools\n\n this._$container\n .on('click', c('.refresh-cookie'), () => {\n devtools.notify('Refreshed', { icon: 'success' })\n this.refresh()\n })\n .on('click', c('.clear-cookie'), () => {\n chobitsu.domain('Storage').clearDataForOrigin({\n storageTypes: 'cookies',\n })\n this.refresh()\n })\n .on('click', c('.delete-cookie'), () => {\n const key = this._selectedItem\n\n chobitsu.domain('Network').deleteCookies({ name: key })\n this.refresh()\n })\n .on('click', c('.show-detail'), () => {\n const key = this._selectedItem\n const val = this._getVal(key)\n\n try {\n showSources('object', JSON.parse(val))\n } catch {\n showSources('raw', val)\n }\n })\n .on('click', c('.copy-cookie'), () => {\n const key = this._selectedItem\n copy(this._getVal(key))\n devtools.notify('Copied', { icon: 'success' })\n })\n .on('click', c('.filter'), () => {\n LunaModal.prompt('Filter').then((filter) => {\n if (isNull(filter)) return\n filter = trim(filter)\n this._filter = filter\n this._$filterText.text(filter)\n this._dataGrid.setOption('filter', filter)\n })\n })\n\n function showSources(type, data) {\n const sources = devtools.get('sources')\n if (!sources) return\n\n sources.set(type, data)\n\n devtools.showTool('sources')\n\n return true\n }\n\n this._dataGrid\n .on('select', (node) => {\n this._selectedItem = node.data.key\n this._updateButtons()\n })\n .on('deselect', () => {\n this._selectedItem = null\n this._updateButtons()\n })\n }\n}\n","import Tool from '../DevTools/Tool'\nimport Settings from '../Settings/Settings'\nimport $ from 'licia/$'\nimport escape from 'licia/escape'\nimport isEmpty from 'licia/isEmpty'\nimport contain from 'licia/contain'\nimport unique from 'licia/unique'\nimport each from 'licia/each'\nimport sameOrigin from 'licia/sameOrigin'\nimport ajax from 'licia/ajax'\nimport MutationObserver from 'licia/MutationObserver'\nimport toArr from 'licia/toArr'\nimport concat from 'licia/concat'\nimport map from 'licia/map'\nimport { isErudaEl, classPrefix as c } from '../lib/util'\nimport evalCss from '../lib/evalCss'\nimport Storage from './Storage'\nimport Cookie from './Cookie'\nimport { setState, getState } from './util'\n\nexport default class Resources extends Tool {\n constructor() {\n super()\n\n this._style = evalCss(require('./Resources.scss'))\n\n this.name = 'resources'\n this._hideErudaSetting = false\n this._observeElement = true\n }\n init($el, container) {\n super.init($el)\n\n this._container = container\n\n this._initTpl()\n this._localStorage = new Storage(\n this._$localStorage,\n container,\n this,\n 'local'\n )\n this._sessionStorage = new Storage(\n this._$sessionStorage,\n container,\n this,\n 'session'\n )\n this._cookie = new Cookie(this._$cookie, container)\n\n this._bindEvent()\n this._initObserver()\n this._initCfg()\n }\n refresh() {\n return this.refreshLocalStorage()\n .refreshSessionStorage()\n .refreshCookie()\n .refreshScript()\n .refreshStylesheet()\n .refreshIframe()\n .refreshImage()\n }\n destroy() {\n super.destroy()\n\n this._localStorage.destroy()\n this._sessionStorage.destroy()\n this._disableObserver()\n evalCss.remove(this._style)\n this._rmCfg()\n }\n refreshScript() {\n let scriptData = []\n\n $('script').each(function () {\n const src = this.src\n\n if (src !== '') scriptData.push(src)\n })\n\n scriptData = unique(scriptData)\n\n const scriptState = getState('script', scriptData.length)\n let scriptDataHtml = '\n Script\n
\n \n ${scriptDataHtml}\n
`\n\n const $script = this._$script\n setState($script, scriptState)\n $script.html(scriptHtml)\n\n return this\n }\n refreshStylesheet() {\n let stylesheetData = []\n\n $('link').each(function () {\n if (this.rel !== 'stylesheet') return\n\n stylesheetData.push(this.href)\n })\n\n stylesheetData = unique(stylesheetData)\n\n const stylesheetState = getState('stylesheet', stylesheetData.length)\n let stylesheetDataHtml = '\n Stylesheet\n
\n \n ${stylesheetDataHtml}\n
`\n\n const $stylesheet = this._$stylesheet\n setState($stylesheet, stylesheetState)\n $stylesheet.html(stylesheetHtml)\n\n return this\n }\n refreshIframe() {\n let iframeData = []\n\n $('iframe').each(function () {\n const $this = $(this)\n const src = $this.attr('src')\n\n if (src) iframeData.push(src)\n })\n\n iframeData = unique(iframeData)\n\n let iframeDataHtml = '\n Iframe\n
\n \n ${iframeDataHtml}\n
`\n\n this._$iframe.html(iframeHtml)\n\n return this\n }\n refreshLocalStorage() {\n this._localStorage.refresh()\n\n return this\n }\n refreshSessionStorage() {\n this._sessionStorage.refresh()\n\n return this\n }\n refreshCookie() {\n this._cookie.refresh()\n\n return this\n }\n refreshImage() {\n let imageData = []\n\n const performance = (this._performance =\n window.webkitPerformance || window.performance)\n if (performance && performance.getEntries) {\n const entries = this._performance.getEntries()\n entries.forEach((entry) => {\n if (entry.initiatorType === 'img' || isImg(entry.name)) {\n if (contain(entry.name, 'exclude=true')) {\n return\n }\n imageData.push(entry.name)\n }\n })\n } else {\n $('img').each(function () {\n const $this = $(this)\n const src = $this.attr('src')\n\n if ($this.data('exclude') === 'true') {\n return\n }\n\n imageData.push(src)\n })\n }\n\n imageData = unique(imageData)\n imageData.sort()\n\n const imageState = getState('image', imageData.length)\n let imageDataHtml = '\n
\n Image\n
\n \n ${imageDataHtml}\n
`\n\n const $image = this._$image\n setState($image, imageState)\n $image.html(imageHtml)\n\n return this\n }\n show() {\n super.show()\n if (this._observeElement) this._enableObserver()\n\n return this.refresh()\n }\n hide() {\n this._disableObserver()\n\n return super.hide()\n }\n _initTpl() {\n const $el = this._$el\n $el.html(\n c(`\n \n \n \n \n \n `)\n )\n this._$localStorage = $el.find(c('.local-storage'))\n this._$sessionStorage = $el.find(c('.session-storage'))\n this._$cookie = $el.find(c('.cookie'))\n this._$script = $el.find(c('.script'))\n this._$stylesheet = $el.find(c('.stylesheet'))\n this._$iframe = $el.find(c('.iframe'))\n this._$image = $el.find(c('.image'))\n }\n _bindEvent() {\n const $el = this._$el\n const container = this._container\n\n $el\n .on('click', '.eruda-refresh-script', () => {\n container.notify('Refreshed', { icon: 'success' })\n this.refreshScript()\n })\n .on('click', '.eruda-refresh-stylesheet', () => {\n container.notify('Refreshed', { icon: 'success' })\n this.refreshStylesheet()\n })\n .on('click', '.eruda-refresh-iframe', () => {\n container.notify('Refreshed', { icon: 'success' })\n this.refreshIframe()\n })\n .on('click', '.eruda-refresh-image', () => {\n container.notify('Refreshed', { icon: 'success' })\n this.refreshImage()\n })\n .on('click', '.eruda-img-link', function () {\n const src = $(this).attr('src')\n\n showSources('img', src)\n })\n .on('click', '.eruda-css-link', linkFactory('css'))\n .on('click', '.eruda-js-link', linkFactory('js'))\n .on('click', '.eruda-iframe-link', linkFactory('iframe'))\n\n function showSources(type, data) {\n const sources = container.get('sources')\n if (!sources) return\n\n sources.set(type, data)\n\n container.showTool('sources')\n\n return true\n }\n\n function linkFactory(type) {\n return function (e) {\n if (!container.get('sources')) return\n e.preventDefault()\n\n const url = $(this).attr('href')\n\n if (type === 'iframe' || !sameOrigin(location.href, url)) {\n showSources('iframe', url)\n } else {\n ajax({\n url,\n success: (data) => {\n showSources(type, data)\n },\n dataType: 'raw',\n })\n }\n }\n }\n }\n _rmCfg() {\n const cfg = this.config\n\n const settings = this._container.get('settings')\n\n if (!settings) return\n\n settings\n .remove(cfg, 'hideErudaSetting')\n .remove(cfg, 'observeElement')\n .remove('Resources')\n }\n _initCfg() {\n const cfg = (this.config = Settings.createCfg('resources', {\n hideErudaSetting: true,\n observeElement: true,\n }))\n\n if (cfg.get('hideErudaSetting')) this._hideErudaSetting = true\n if (!cfg.get('observeElement')) this._observeElement = false\n\n cfg.on('change', (key, val) => {\n switch (key) {\n case 'hideErudaSetting':\n this._hideErudaSetting = val\n return\n case 'observeElement':\n this._observeElement = val\n return val ? this._enableObserver() : this._disableObserver()\n }\n })\n\n const settings = this._container.get('settings')\n settings\n .text('Resources')\n .switch(cfg, 'hideErudaSetting', 'Hide Eruda Setting')\n .switch(cfg, 'observeElement', 'Auto Refresh Elements')\n .separator()\n }\n _initObserver() {\n this._observer = new MutationObserver((mutations) => {\n each(mutations, (mutation) => {\n this._handleMutation(mutation)\n })\n })\n }\n _handleMutation(mutation) {\n if (isErudaEl(mutation.target)) return\n\n const checkEl = (el) => {\n const tagName = getLowerCaseTagName(el)\n switch (tagName) {\n case 'script':\n this.refreshScript()\n break\n case 'img':\n this.refreshImage()\n break\n case 'link':\n this.refreshStylesheet()\n break\n }\n }\n\n if (mutation.type === 'attributes') {\n checkEl(mutation.target)\n } else if (mutation.type === 'childList') {\n checkEl(mutation.target)\n let nodes = toArr(mutation.addedNodes)\n nodes = concat(nodes, toArr(mutation.removedNodes))\n\n for (const node of nodes) {\n checkEl(node)\n }\n }\n }\n _enableObserver() {\n this._observer.observe(document.documentElement, {\n attributes: true,\n childList: true,\n subtree: true,\n })\n }\n _disableObserver() {\n this._observer.disconnect()\n }\n}\n\nfunction getLowerCaseTagName(el) {\n if (!el.tagName) return ''\n return el.tagName.toLowerCase()\n}\n\nconst regImg = /\\.(jpeg|jpg|gif|png)$/\n\nconst isImg = (url) => regImg.test(url)\n","import detectBrowser from 'licia/detectBrowser'\nimport detectOs from 'licia/detectOs'\nimport escape from 'licia/escape'\nimport map from 'licia/map'\n\nconst browser = detectBrowser()\n\nexport default [\n {\n name: 'Location',\n val() {\n return escape(location.href)\n },\n },\n {\n name: 'User Agent',\n val: navigator.userAgent,\n },\n {\n name: 'Device',\n val: [\n '',\n `
',\n ].join(''),\n },\n {\n name: 'System',\n val: [\n ' `,\n `screen ${screen.width} * ${screen.height} `,\n `viewport ${window.innerWidth} * ${window.innerHeight} `,\n 'pixel ratio ${window.devicePixelRatio} ',\n `
',\n ].join(''),\n },\n {\n name: 'Sponsor this Project',\n val() {\n return (\n ' `,\n `os ${detectOs()} `,\n 'browser ${\n browser.name + ' ' + browser.version\n } ' +\n map(\n [\n {\n name: 'Open Collective',\n link: 'https://opencollective.com/eruda',\n },\n {\n name: 'Ko-fi',\n link: 'https://ko-fi.com/surunzi',\n },\n {\n name: 'Wechat Pay',\n link: 'https://surunzi.com/wechatpay.html',\n },\n ],\n (item) => {\n return `
'\n )\n },\n },\n {\n name: 'About',\n val:\n 'Eruda v' +\n VERSION +\n '',\n },\n]\n","import Tool from '../DevTools/Tool'\nimport defInfo from './defInfo'\nimport each from 'licia/each'\nimport isFn from 'licia/isFn'\nimport isUndef from 'licia/isUndef'\nimport cloneDeep from 'licia/cloneDeep'\nimport evalCss from '../lib/evalCss'\nimport map from 'licia/map'\nimport escape from 'licia/escape'\nimport copy from 'licia/copy'\nimport $ from 'licia/$'\nimport { classPrefix as c } from '../lib/util'\n\nexport default class Info extends Tool {\n constructor() {\n super()\n\n this._style = evalCss(require('./Info.scss'))\n\n this.name = 'info'\n this._infos = []\n }\n init($el, container) {\n super.init($el)\n this._container = container\n\n this._addDefInfo()\n this._bindEvent()\n }\n destroy() {\n super.destroy()\n\n evalCss.remove(this._style)\n }\n add(name, val) {\n const infos = this._infos\n let isUpdate = false\n\n each(infos, (info) => {\n if (name !== info.name) return\n\n info.val = val\n isUpdate = true\n })\n\n if (!isUpdate) infos.push({ name, val })\n\n this._render()\n\n return this\n }\n get(name) {\n const infos = this._infos\n\n if (isUndef(name)) {\n return cloneDeep(infos)\n }\n\n let result\n\n each(infos, (info) => {\n if (name === info.name) result = info.val\n })\n\n return result\n }\n remove(name) {\n const infos = this._infos\n\n for (let i = infos.length - 1; i >= 0; i--) {\n if (infos[i].name === name) infos.splice(i, 1)\n }\n\n this._render()\n\n return this\n }\n clear() {\n this._infos = []\n\n this._render()\n\n return this\n }\n _addDefInfo() {\n each(defInfo, (info) => this.add(info.name, info.val))\n }\n _render() {\n const infos = []\n\n each(this._infos, ({ name, val }) => {\n if (isFn(val)) val = val()\n\n infos.push({ name, val })\n })\n\n const html = ` `\n }\n ).join(' ') +\n '${\n item.name\n } ${item.link.replace(\n 'https://',\n ''\n )} ${map(\n infos,\n (info) =>\n `
`\n\n this._renderHtml(html)\n }\n _bindEvent() {\n const container = this._container\n\n this._$el.on('click', c('.copy'), function () {\n const $li = $(this).parent().parent()\n const name = $li.find(c('.title')).text()\n const content = $li.find(c('.content')).text()\n copy(`${name}: ${content}`)\n container.notify('Copied', { icon: 'success' })\n })\n }\n _renderHtml(html) {\n if (html === this._lastHtml) return\n this._lastHtml = html\n this._$el.html(html)\n }\n}\n","import Tool from '../DevTools/Tool'\nimport LunaObjectViewer from 'luna-object-viewer'\nimport Settings from '../Settings/Settings'\nimport ajax from 'licia/ajax'\nimport each from 'licia/each'\nimport isStr from 'licia/isStr'\nimport escape from 'licia/escape'\nimport truncate from 'licia/truncate'\nimport replaceAll from 'licia/replaceAll'\nimport highlight from 'licia/highlight'\nimport LunaTextViewer from 'luna-text-viewer'\nimport evalCss from '../lib/evalCss'\nimport { classPrefix as c } from '../lib/util'\n\nexport default class Sources extends Tool {\n constructor() {\n super()\n\n this._style = evalCss(require('./Sources.scss'))\n\n this.name = 'sources'\n this._showLineNum = true\n }\n init($el, container) {\n super.init($el)\n\n this._container = container\n this._bindEvent()\n this._initCfg()\n }\n destroy() {\n super.destroy()\n\n evalCss.remove(this._style)\n this._rmCfg()\n }\n set(type, val) {\n if (type === 'img') {\n this._isFetchingData = true\n\n const img = new Image()\n\n const self = this\n\n img.onload = function () {\n self._isFetchingData = false\n self._data = {\n type: 'img',\n val: {\n width: this.width,\n height: this.height,\n src: val,\n },\n }\n\n self._render()\n }\n img.onerror = function () {\n self._isFetchingData = false\n }\n\n img.src = val\n\n return\n }\n\n this._data = { type, val }\n\n this._render()\n\n return this\n }\n show() {\n super.show()\n\n if (!this._data && !this._isFetchingData) {\n this._renderDef()\n }\n\n return this\n }\n _renderDef() {\n if (this._html) {\n this._data = {\n type: 'html',\n val: this._html,\n }\n\n return this._render()\n }\n\n if (this._isGettingHtml) return\n this._isGettingHtml = true\n\n ajax({\n url: location.href,\n success: (data) => (this._html = data),\n error: () => (this._html = 'Sorry, unable to fetch source code:('),\n complete: () => {\n this._isGettingHtml = false\n this._renderDef()\n },\n dataType: 'raw',\n })\n }\n _bindEvent() {\n this._container.on('showTool', (name, lastTool) => {\n if (name !== this.name && lastTool.name === this.name) {\n delete this._data\n }\n })\n }\n _rmCfg() {\n const cfg = this.config\n\n const settings = this._container.get('settings')\n\n if (!settings) return\n\n settings.remove(cfg, 'showLineNum').remove('Sources')\n }\n _initCfg() {\n const cfg = (this.config = Settings.createCfg('sources', {\n showLineNum: true,\n }))\n\n if (!cfg.get('showLineNum')) this._showLineNum = false\n\n cfg.on('change', (key, val) => {\n switch (key) {\n case 'showLineNum':\n this._showLineNum = val\n return\n }\n })\n\n const settings = this._container.get('settings')\n settings\n .text('Sources')\n .switch(cfg, 'showLineNum', 'Show Line Numbers')\n .separator()\n }\n _render() {\n this._isInit = true\n\n const data = this._data\n\n switch (data.type) {\n case 'html':\n case 'js':\n case 'css':\n return this._renderCode()\n case 'img':\n return this._renderImg()\n case 'object':\n return this._renderObj()\n case 'raw':\n return this._renderRaw()\n case 'iframe':\n return this._renderIframe()\n }\n }\n _renderImg() {\n const { width, height, src } = this._data.val\n\n this._renderHtml(`${escape(info.name)}
\n
`, false)\n\n let val = this._data.val\n\n try {\n if (isStr(val)) {\n val = JSON.parse(val)\n }\n } catch {\n // No op\n }\n\n const objViewer = new LunaObjectViewer(\n this._$el.find('.eruda-json').get(0),\n {\n unenumerable: true,\n accessGetter: true,\n prototype: false,\n }\n )\n objViewer.set(val)\n }\n _renderRaw() {\n const data = this._data\n\n this._renderHtml(`
`;\n if (firstLevel)\n obj += this.objToHtml(this.map[id]);\n return obj + `
`;\n if (firstLevel)\n obj += this.objToHtml(val);\n return obj + `