!i.includes(e))).join(" ").length/n.join(" ").length:0},_checkByline:function(e,t){if(this._articleByline)return!1;if(void 0!==e.getAttribute)var i=e.getAttribute("rel"),n=e.getAttribute("itemprop");return!(!("author"===i||n&&-1!==n.indexOf("author")||this.REGEXPS.byline.test(t))||!this._isValidByline(e.textContent))&&(this._articleByline=e.textContent.trim(),!0)},_getNodeAncestors:function(e,t){t=t||0;for(var i=0,n=[];e.parentNode&&(n.push(e.parentNode),!t||++i!==t);)e=e.parentNode;return n},_grabArticle:function(e){this.log("**** grabArticle ****");var t=this._doc,i=null!==e;if(!(e=e||this._doc.body))return this.log("No body found in document. Abort."),null;for(var n=e.innerHTML;;){this.log("Starting grabArticle loop");var r=this._flagIsActive(this.FLAG_STRIP_UNLIKELYS),a=[],o=this._doc.documentElement;let X=!0;for(;o;){"HTML"===o.tagName&&(this._articleLang=o.getAttribute("lang"));var s=o.className+" "+o.id;if(this._isProbablyVisible(o))if("true"!=o.getAttribute("aria-modal")||"dialog"!=o.getAttribute("role"))if(this._checkByline(o,s))o=this._removeAndGetNext(o);else if(X&&this._headerDuplicatesTitle(o))this.log("Removing header: ",o.textContent.trim(),this._articleTitle.trim()),X=!1,o=this._removeAndGetNext(o);else{if(r){if(this.REGEXPS.unlikelyCandidates.test(s)&&!this.REGEXPS.okMaybeItsACandidate.test(s)&&!this._hasAncestorTag(o,"table")&&!this._hasAncestorTag(o,"code")&&"BODY"!==o.tagName&&"A"!==o.tagName){this.log("Removing unlikely candidate - "+s),o=this._removeAndGetNext(o);continue}if(this.UNLIKELY_ROLES.includes(o.getAttribute("role"))){this.log("Removing content with role "+o.getAttribute("role")+" - "+s),o=this._removeAndGetNext(o);continue}}if("DIV"!==o.tagName&&"SECTION"!==o.tagName&&"HEADER"!==o.tagName&&"H1"!==o.tagName&&"H2"!==o.tagName&&"H3"!==o.tagName&&"H4"!==o.tagName&&"H5"!==o.tagName&&"H6"!==o.tagName||!this._isElementWithoutContent(o)){if(-1!==this.DEFAULT_TAGS_TO_SCORE.indexOf(o.tagName)&&a.push(o),"DIV"===o.tagName){for(var l=null,c=o.firstChild;c;){var h=c.nextSibling;if(this._isPhrasingContent(c))null!==l?l.appendChild(c):this._isWhitespace(c)||(l=t.createElement("p"),o.replaceChild(l,c),l.appendChild(c));else if(null!==l){for(;l.lastChild&&this._isWhitespace(l.lastChild);)l.removeChild(l.lastChild);l=null}c=h}if(this._hasSingleTagInsideElement(o,"P")&&this._getLinkDensity(o)<.25){var d=o.children[0];o.parentNode.replaceChild(d,o),o=d,a.push(o)}else this._hasChildBlockElement(o)||(o=this._setNodeTag(o,"P"),a.push(o))}o=this._getNextNode(o)}else o=this._removeAndGetNext(o)}else o=this._removeAndGetNext(o);else this.log("Removing hidden node - "+s),o=this._removeAndGetNext(o)}var u=[];this._forEachNode(a,(function(e){if(e.parentNode&&void 0!==e.parentNode.tagName){var t=this._getInnerText(e);if(!(t.length<25)){var i=this._getNodeAncestors(e,5);if(0!==i.length){var n=0;n+=1,n+=t.split(this.REGEXPS.commas).length,n+=Math.min(Math.floor(t.length/100),3),this._forEachNode(i,(function(e,t){if(e.tagName&&e.parentNode&&void 0!==e.parentNode.tagName){if(void 0===e.readability&&(this._initializeNode(e),u.push(e)),0===t)var i=1;else i=1===t?2:3*t;e.readability.contentScore+=n/i}}))}}}}));for(var m=[],g=0,p=u.length;gE.readability.contentScore){m.splice(N,0,f),m.length>this._nbTopCandidates&&m.pop();break}}}var T,b=m[0]||null,y=!1;if(null===b||"BODY"===b.tagName){for(b=t.createElement("DIV"),y=!0;e.firstChild;)this.log("Moving child out:",e.firstChild),b.appendChild(e.firstChild);e.appendChild(b),this._initializeNode(b)}else if(b){for(var A=[],v=1;v=.75&&A.push(this._getNodeAncestors(m[v]));if(A.length>=3)for(T=b.parentNode;"BODY"!==T.tagName;){for(var S=0,C=0;C=3){b=T;break}T=T.parentNode}b.readability||this._initializeNode(b),T=b.parentNode;for(var L=b.readability.contentScore,x=L/3;"BODY"!==T.tagName;)if(T.readability){var R=T.readability.contentScore;if(RL){b=T;break}L=T.readability.contentScore,T=T.parentNode}else T=T.parentNode;for(T=b.parentNode;"BODY"!=T.tagName&&1==T.children.length;)T=(b=T).parentNode;b.readability||this._initializeNode(b)}var D=t.createElement("DIV");i&&(D.id="readability-content");for(var I=Math.max(10,.2*b.readability.contentScore),O=(T=b.parentNode).children,w=0,P=O.length;w=I)k=!0;else if("P"===M.nodeName){var U=this._getLinkDensity(M),H=this._getInnerText(M),G=H.length;(G>80&&U<.25||G<80&&G>0&&0===U&&-1!==H.search(/\.( |$)/))&&(k=!0)}}k&&(this.log("Appending node:",M),-1===this.ALTER_TO_DIV_EXCEPTIONS.indexOf(M.nodeName)&&(this.log("Altering sibling:",M,"to div."),M=this._setNodeTag(M,"DIV")),D.appendChild(M),O=T.children,w-=1,P-=1)}if(this._debug&&this.log("Article content pre-prep: "+D.innerHTML),this._prepArticle(D),this._debug&&this.log("Article content post-prep: "+D.innerHTML),y)b.id="readability-page-1",b.className="page";else{var F=t.createElement("DIV");for(F.id="readability-page-1",F.className="page";D.firstChild;)F.appendChild(D.firstChild);D.appendChild(F)}this._debug&&this.log("Article content after paging: "+D.innerHTML);var W=!0,z=this._getInnerText(D,!0).length;if(z0&&e.length<100)},_unescapeHtmlEntities:function(e){if(!e)return e;var t=this.HTML_ESCAPE_MAP;return e.replace(/&(quot|amp|apos|lt|gt);/g,(function(e,i){return t[i]})).replace(/(?:x([0-9a-z]{1,4})|([0-9]{1,4}));/gi,(function(e,t,i){var n=parseInt(t||i,t?16:10);return String.fromCharCode(n)}))},_getJSONLD:function(e){var t,i=this._getAllNodesWithTag(e,["script"]);return this._forEachNode(i,(function(e){if(!t&&"application/ld+json"===e.getAttribute("type"))try{var i=e.textContent.replace(/^\s*\s*$/g,""),n=JSON.parse(i);if(!n["@context"]||!n["@context"].match(/^https?\:\/\/schema\.org$/))return;if(!n["@type"]&&Array.isArray(n["@graph"])&&(n=n["@graph"].find((function(e){return(e["@type"]||"").match(this.REGEXPS.jsonLdArticleTypes)}))),!n||!n["@type"]||!n["@type"].match(this.REGEXPS.jsonLdArticleTypes))return;if(t={},"string"==typeof n.name&&"string"==typeof n.headline&&n.name!==n.headline){var r=this._getArticleTitle(),a=this._textSimilarity(n.name,r)>.75,o=this._textSimilarity(n.headline,r)>.75;t.title=o&&!a?n.headline:n.name}else"string"==typeof n.name?t.title=n.name.trim():"string"==typeof n.headline&&(t.title=n.headline.trim());return n.author&&("string"==typeof n.author.name?t.byline=n.author.name.trim():Array.isArray(n.author)&&n.author[0]&&"string"==typeof n.author[0].name&&(t.byline=n.author.filter((function(e){return e&&"string"==typeof e.name})).map((function(e){return e.name.trim()})).join(", "))),"string"==typeof n.description&&(t.excerpt=n.description.trim()),n.publisher&&"string"==typeof n.publisher.name&&(t.siteName=n.publisher.name.trim()),void("string"==typeof n.datePublished&&(t.datePublished=n.datePublished.trim()))}catch(e){this.log(e.message)}})),t||{}},_getArticleMetadata:function(e){var t={},i={},n=this._doc.getElementsByTagName("meta"),r=/\s*(article|dc|dcterm|og|twitter)\s*:\s*(author|creator|description|published_time|title|site_name)\s*/gi,a=/^\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\s*[\.:]\s*)?(author|creator|description|title|site_name)\s*$/i;return this._forEachNode(n,(function(e){var t=e.getAttribute("name"),n=e.getAttribute("property"),o=e.getAttribute("content");if(o){var s=null,l=null;n&&(s=n.match(r))&&(l=s[0].toLowerCase().replace(/\s/g,""),i[l]=o.trim()),!s&&t&&a.test(t)&&(l=t,o&&(l=l.toLowerCase().replace(/\s/g,"").replace(/\./g,":"),i[l]=o.trim()))}})),t.title=e.title||i["dc:title"]||i["dcterm:title"]||i["og:title"]||i["weibo:article:title"]||i["weibo:webpage:title"]||i.title||i["twitter:title"],t.title||(t.title=this._getArticleTitle()),t.byline=e.byline||i["dc:creator"]||i["dcterm:creator"]||i.author,t.excerpt=e.excerpt||i["dc:description"]||i["dcterm:description"]||i["og:description"]||i["weibo:article:description"]||i["weibo:webpage:description"]||i.description||i["twitter:description"],t.siteName=e.siteName||i["og:site_name"],t.publishedTime=e.datePublished||i["article:published_time"]||null,t.title=this._unescapeHtmlEntities(t.title),t.byline=this._unescapeHtmlEntities(t.byline),t.excerpt=this._unescapeHtmlEntities(t.excerpt),t.siteName=this._unescapeHtmlEntities(t.siteName),t.publishedTime=this._unescapeHtmlEntities(t.publishedTime),t},_isSingleImage:function(e){return"IMG"===e.tagName||1===e.children.length&&""===e.textContent.trim()&&this._isSingleImage(e.children[0])},_unwrapNoscriptImages:function(e){var t=Array.from(e.getElementsByTagName("img"));this._forEachNode(t,(function(e){for(var t=0;t0&&r>i)return!1;if(e.parentNode.tagName===t&&(!n||n(e.parentNode)))return!0;e=e.parentNode,r++}return!1},_getRowAndColumnCount:function(e){for(var t=0,i=0,n=e.getElementsByTagName("tr"),r=0;r0)n._readabilityDataTable=!0;else{if(["col","colgroup","tfoot","thead","th"].some((function(e){return!!n.getElementsByTagName(e)[0]})))this.log("Data table because found data-y descendant"),n._readabilityDataTable=!0;else if(n.getElementsByTagName("table")[0])n._readabilityDataTable=!1;else{var a=this._getRowAndColumnCount(n);a.rows>=10||a.columns>4?n._readabilityDataTable=!0:n._readabilityDataTable=a.rows*a.columns>10}}}else n._readabilityDataTable=!1;else n._readabilityDataTable=!1}},_fixLazyImages:function(e){this._forEachNode(this._getAllNodesWithTag(e,["img","picture","figure"]),(function(e){if(e.src&&this.REGEXPS.b64DataUrl.test(e.src)){if("image/svg+xml"===this.REGEXPS.b64DataUrl.exec(e.src)[1])return;for(var t=!1,i=0;in+=this._getInnerText(e,!0).length)),n/i},_cleanConditionally:function(e,t){this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)&&this._removeNodes(this._getAllNodesWithTag(e,[t]),(function(e){var i=function(e){return e._readabilityDataTable},n="ul"===t||"ol"===t;if(!n){var r=0,a=this._getAllNodesWithTag(e,["ul","ol"]);this._forEachNode(a,(e=>r+=this._getInnerText(e).length)),n=r/this._getInnerText(e).length>.9}if("table"===t&&i(e))return!1;if(this._hasAncestorTag(e,"table",-1,i))return!1;if(this._hasAncestorTag(e,"code"))return!1;var o=this._getClassWeight(e);this.log("Cleaning Conditionally",e);if(o+0<0)return!0;if(this._getCharCount(e,",")<10){for(var s=e.getElementsByTagName("p").length,l=e.getElementsByTagName("img").length,c=e.getElementsByTagName("li").length-100,h=e.getElementsByTagName("input").length,d=this._getTextDensity(e,["h1","h2","h3","h4","h5","h6"]),u=0,m=this._getAllNodesWithTag(e,["object","embed","iframe"]),g=0;g1&&s/l<.5&&!this._hasAncestorTag(e,"figure")||!n&&c>s||h>Math.floor(s/3)||!n&&d<.9&&_<25&&(0===l||l>2)&&!this._hasAncestorTag(e,"figure")||!n&&o<25&&f>.2||o>=25&&f>.5||1===u&&_<75||u>1;if(n&&N){for(var E=0;E1)return N}if(l==e.getElementsByTagName("li").length)return!1}return N}return!1}))},_cleanMatchedNodes:function(e,t){for(var i=this._getNextNode(e,!0),n=this._getNextNode(e);n&&n!=i;)n=t.call(this,n,n.className+" "+n.id)?this._removeAndGetNext(n):this._getNextNode(n)},_cleanHeaders:function(e){let t=this._getAllNodesWithTag(e,["h1","h2"]);this._removeNodes(t,(function(e){let t=this._getClassWeight(e)<0;return t&&this.log("Removing header with low class weight:",e),t}))},_headerDuplicatesTitle:function(e){if("H1"!=e.tagName&&"H2"!=e.tagName)return!1;var t=this._getInnerText(e,!1);return this.log("Evaluating similarity of header:",t,this._articleTitle),this._textSimilarity(this._articleTitle,t)>.75},_flagIsActive:function(e){return(this._flags&e)>0},_removeFlag:function(e){this._flags=this._flags&~e},_isProbablyVisible:function(e){return(!e.style||"none"!=e.style.display)&&(!e.style||"hidden"!=e.style.visibility)&&!e.hasAttribute("hidden")&&(!e.hasAttribute("aria-hidden")||"true"!=e.getAttribute("aria-hidden")||e.className&&e.className.indexOf&&-1!==e.className.indexOf("fallback-image"))},parse:function(){if(this._maxElemsToParse>0){var e=this._doc.getElementsByTagName("*").length;if(e>this._maxElemsToParse)throw new Error("Aborting parsing document; "+e+" elements found")}this._unwrapNoscriptImages(this._doc);var t=this._disableJSONLD?{}:this._getJSONLD(this._doc);this._removeScripts(this._doc),this._prepDocument();var i=this._getArticleMetadata(t);this._articleTitle=i.title;var n=this._grabArticle();if(!n)return null;if(this.log("Grabbed: "+n.innerHTML),this._postProcessContent(n),!i.excerpt){var r=n.getElementsByTagName("p");r.length>0&&(i.excerpt=r[0].textContent.trim())}var a=n.textContent;return{title:this._articleTitle,byline:i.byline||this._articleByline,dir:this._articleDir,lang:this._articleLang,content:this._serializer(n),textContent:a,length:a.length,excerpt:i.excerpt,siteName:i.siteName||this._articleSiteName,publishedTime:i.publishedTime}}},e.exports=t},396:(e,t,i)=>{var n=i(238),r=i(804);e.exports={Readability:n,isProbablyReaderable:r}},838:function(e){
-/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */
-e.exports=function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:i,getPrototypeOf:n,getOwnPropertyDescriptor:r}=Object;let{freeze:a,seal:o,create:s}=Object,{apply:l,construct:c}="undefined"!=typeof Reflect&&Reflect;a||(a=function(e){return e}),o||(o=function(e){return e}),l||(l=function(e,t,i){return e.apply(t,i)}),c||(c=function(e,t){return new e(...t)});const h=y(Array.prototype.forEach),d=y(Array.prototype.pop),u=y(Array.prototype.push),m=y(String.prototype.toLowerCase),g=y(String.prototype.toString),p=y(String.prototype.match),f=y(String.prototype.replace),_=y(String.prototype.indexOf),N=y(String.prototype.trim),E=y(Object.prototype.hasOwnProperty),T=y(RegExp.prototype.test),b=A(TypeError);function y(e){return function(t){for(var i=arguments.length,n=new Array(i>1?i-1:0),r=1;r2&&void 0!==arguments[2]?arguments[2]:m;t&&t(e,null);let a=n.length;for(;a--;){let t=n[a];if("string"==typeof t){const e=r(t);e!==t&&(i(n)||(n[a]=e),t=e)}e[t]=!0}return e}function S(e){for(let t=0;t/gm),F=o(/\${[\w\W]*}/gm),W=o(/^data-[\-\w.\u00B7-\uFFFF]/),z=o(/^aria-[\-\w]+$/),j=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),X=o(/^(?:\w+script|data):/i),Y=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),V=o(/^html$/i),$=o(/^[a-z][.\w]*(-[.\w]+)+$/i);var q=Object.freeze({__proto__:null,MUSTACHE_EXPR:H,ERB_EXPR:G,TMPLIT_EXPR:F,DATA_ATTR:W,ARIA_ATTR:z,IS_ALLOWED_URI:j,IS_SCRIPT_OR_DATA:X,ATTR_WHITESPACE:Y,DOCTYPE_NAME:V,CUSTOM_ELEMENT:$});const K={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},J=function(){return"undefined"==typeof window?null:window},Z=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 r="dompurify"+(i?"#"+i:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}};function Q(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:J();const i=e=>Q(e);if(i.version="3.1.6",i.removed=[],!t||!t.document||t.document.nodeType!==K.document)return i.isSupported=!1,i;let{document:n}=t;const r=n,o=r.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:y,Element:A,NodeFilter:S,NamedNodeMap:H=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:G,DOMParser:F,trustedTypes:W}=t,z=A.prototype,X=L(z,"cloneNode"),Y=L(z,"remove"),$=L(z,"nextSibling"),ee=L(z,"childNodes"),te=L(z,"parentNode");if("function"==typeof c){const e=n.createElement("template");e.content&&e.content.ownerDocument&&(n=e.content.ownerDocument)}let ie,ne="";const{implementation:re,createNodeIterator:ae,createDocumentFragment:oe,getElementsByTagName:se}=n,{importNode:le}=r;let ce={};i.isSupported="function"==typeof e&&"function"==typeof te&&re&&void 0!==re.createHTMLDocument;const{MUSTACHE_EXPR:he,ERB_EXPR:de,TMPLIT_EXPR:ue,DATA_ATTR:me,ARIA_ATTR:ge,IS_SCRIPT_OR_DATA:pe,ATTR_WHITESPACE:fe,CUSTOM_ELEMENT:_e}=q;let{IS_ALLOWED_URI:Ne}=q,Ee=null;const Te=v({},[...x,...R,...D,...O,...P]);let be=null;const ye=v({},[...M,...k,...B,...U]);let Ae=Object.seal(s(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}})),ve=null,Se=null,Ce=!0,Le=!0,xe=!1,Re=!0,De=!1,Ie=!0,Oe=!1,we=!1,Pe=!1,Me=!1,ke=!1,Be=!1,Ue=!0,He=!1;const Ge="user-content-";let Fe=!0,We=!1,ze={},je=null;const Xe=v({},["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 Ye=null;const Ve=v({},["audio","video","img","source","image","track"]);let $e=null;const qe=v({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Ke="http://www.w3.org/1998/Math/MathML",Je="http://www.w3.org/2000/svg",Ze="http://www.w3.org/1999/xhtml";let Qe=Ze,et=!1,tt=null;const it=v({},[Ke,Je,Ze],g);let nt=null;const rt=["application/xhtml+xml","text/html"],at="text/html";let ot=null,st=null;const lt=n.createElement("form"),ct=function(e){return e instanceof RegExp||e instanceof Function},ht=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!st||st!==e){if(e&&"object"==typeof e||(e={}),e=C(e),nt=-1===rt.indexOf(e.PARSER_MEDIA_TYPE)?at:e.PARSER_MEDIA_TYPE,ot="application/xhtml+xml"===nt?g:m,Ee=E(e,"ALLOWED_TAGS")?v({},e.ALLOWED_TAGS,ot):Te,be=E(e,"ALLOWED_ATTR")?v({},e.ALLOWED_ATTR,ot):ye,tt=E(e,"ALLOWED_NAMESPACES")?v({},e.ALLOWED_NAMESPACES,g):it,$e=E(e,"ADD_URI_SAFE_ATTR")?v(C(qe),e.ADD_URI_SAFE_ATTR,ot):qe,Ye=E(e,"ADD_DATA_URI_TAGS")?v(C(Ve),e.ADD_DATA_URI_TAGS,ot):Ve,je=E(e,"FORBID_CONTENTS")?v({},e.FORBID_CONTENTS,ot):Xe,ve=E(e,"FORBID_TAGS")?v({},e.FORBID_TAGS,ot):{},Se=E(e,"FORBID_ATTR")?v({},e.FORBID_ATTR,ot):{},ze=!!E(e,"USE_PROFILES")&&e.USE_PROFILES,Ce=!1!==e.ALLOW_ARIA_ATTR,Le=!1!==e.ALLOW_DATA_ATTR,xe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Re=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,De=e.SAFE_FOR_TEMPLATES||!1,Ie=!1!==e.SAFE_FOR_XML,Oe=e.WHOLE_DOCUMENT||!1,Me=e.RETURN_DOM||!1,ke=e.RETURN_DOM_FRAGMENT||!1,Be=e.RETURN_TRUSTED_TYPE||!1,Pe=e.FORCE_BODY||!1,Ue=!1!==e.SANITIZE_DOM,He=e.SANITIZE_NAMED_PROPS||!1,Fe=!1!==e.KEEP_CONTENT,We=e.IN_PLACE||!1,Ne=e.ALLOWED_URI_REGEXP||j,Qe=e.NAMESPACE||Ze,Ae=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ct(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Ae.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ct(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Ae.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Ae.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),De&&(Le=!1),ke&&(Me=!0),ze&&(Ee=v({},P),be=[],!0===ze.html&&(v(Ee,x),v(be,M)),!0===ze.svg&&(v(Ee,R),v(be,k),v(be,U)),!0===ze.svgFilters&&(v(Ee,D),v(be,k),v(be,U)),!0===ze.mathMl&&(v(Ee,O),v(be,B),v(be,U))),e.ADD_TAGS&&(Ee===Te&&(Ee=C(Ee)),v(Ee,e.ADD_TAGS,ot)),e.ADD_ATTR&&(be===ye&&(be=C(be)),v(be,e.ADD_ATTR,ot)),e.ADD_URI_SAFE_ATTR&&v($e,e.ADD_URI_SAFE_ATTR,ot),e.FORBID_CONTENTS&&(je===Xe&&(je=C(je)),v(je,e.FORBID_CONTENTS,ot)),Fe&&(Ee["#text"]=!0),Oe&&v(Ee,["html","head","body"]),Ee.table&&(v(Ee,["tbody"]),delete ve.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');ie=e.TRUSTED_TYPES_POLICY,ne=ie.createHTML("")}else void 0===ie&&(ie=Z(W,o)),null!==ie&&"string"==typeof ne&&(ne=ie.createHTML(""));a&&a(e),st=e}},dt=v({},["mi","mo","mn","ms","mtext"]),ut=v({},["foreignobject","annotation-xml"]),mt=v({},["title","style","font","a","script"]),gt=v({},[...R,...D,...I]),pt=v({},[...O,...w]),ft=function(e){let t=te(e);t&&t.tagName||(t={namespaceURI:Qe,tagName:"template"});const i=m(e.tagName),n=m(t.tagName);return!!tt[e.namespaceURI]&&(e.namespaceURI===Je?t.namespaceURI===Ze?"svg"===i:t.namespaceURI===Ke?"svg"===i&&("annotation-xml"===n||dt[n]):Boolean(gt[i]):e.namespaceURI===Ke?t.namespaceURI===Ze?"math"===i:t.namespaceURI===Je?"math"===i&&ut[n]:Boolean(pt[i]):e.namespaceURI===Ze?!(t.namespaceURI===Je&&!ut[n])&&!(t.namespaceURI===Ke&&!dt[n])&&!pt[i]&&(mt[i]||!gt[i]):!("application/xhtml+xml"!==nt||!tt[e.namespaceURI]))},_t=function(e){u(i.removed,{element:e});try{te(e).removeChild(e)}catch(t){Y(e)}},Nt=function(e,t){try{u(i.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){u(i.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!be[e])if(Me||ke)try{_t(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},Et=function(e){let t=null,i=null;if(Pe)e=" "+e;else{const t=p(e,/^[\r\n\t ]+/);i=t&&t[0]}"application/xhtml+xml"===nt&&Qe===Ze&&(e=''+e+"");const r=ie?ie.createHTML(e):e;if(Qe===Ze)try{t=(new F).parseFromString(r,nt)}catch(e){}if(!t||!t.documentElement){t=re.createDocument(Qe,"template",null);try{t.documentElement.innerHTML=et?ne:r}catch(e){}}const a=t.body||t.documentElement;return e&&i&&a.insertBefore(n.createTextNode(i),a.childNodes[0]||null),Qe===Ze?se.call(t,Oe?"html":"body")[0]:Oe?t.documentElement:a},Tt=function(e){return ae.call(e.ownerDocument||e,e,S.SHOW_ELEMENT|S.SHOW_COMMENT|S.SHOW_TEXT|S.SHOW_PROCESSING_INSTRUCTION|S.SHOW_CDATA_SECTION,null)},bt=function(e){return e instanceof G&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof H)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},yt=function(e){return"function"==typeof y&&e instanceof y},At=function(e,t,n){ce[e]&&h(ce[e],(e=>{e.call(i,t,n,st)}))},vt=function(e){let t=null;if(At("beforeSanitizeElements",e,null),bt(e))return _t(e),!0;const n=ot(e.nodeName);if(At("uponSanitizeElement",e,{tagName:n,allowedTags:Ee}),e.hasChildNodes()&&!yt(e.firstElementChild)&&T(/<[/\w]/g,e.innerHTML)&&T(/<[/\w]/g,e.textContent))return _t(e),!0;if(e.nodeType===K.progressingInstruction)return _t(e),!0;if(Ie&&e.nodeType===K.comment&&T(/<[/\w]/g,e.data))return _t(e),!0;if(!Ee[n]||ve[n]){if(!ve[n]&&Ct(n)){if(Ae.tagNameCheck instanceof RegExp&&T(Ae.tagNameCheck,n))return!1;if(Ae.tagNameCheck instanceof Function&&Ae.tagNameCheck(n))return!1}if(Fe&&!je[n]){const t=te(e)||e.parentNode,i=ee(e)||e.childNodes;if(i&&t)for(let n=i.length-1;n>=0;--n){const r=X(i[n],!0);r.__removalCount=(e.__removalCount||0)+1,t.insertBefore(r,$(e))}}return _t(e),!0}return e instanceof A&&!ft(e)?(_t(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!T(/<\/no(script|embed|frames)/i,e.innerHTML)?(De&&e.nodeType===K.text&&(t=e.textContent,h([he,de,ue],(e=>{t=f(t,e," ")})),e.textContent!==t&&(u(i.removed,{element:e.cloneNode()}),e.textContent=t)),At("afterSanitizeElements",e,null),!1):(_t(e),!0)},St=function(e,t,i){if(Ue&&("id"===t||"name"===t)&&(i in n||i in lt))return!1;if(Le&&!Se[t]&&T(me,t));else if(Ce&&T(ge,t));else if(!be[t]||Se[t]){if(!(Ct(e)&&(Ae.tagNameCheck instanceof RegExp&&T(Ae.tagNameCheck,e)||Ae.tagNameCheck instanceof Function&&Ae.tagNameCheck(e))&&(Ae.attributeNameCheck instanceof RegExp&&T(Ae.attributeNameCheck,t)||Ae.attributeNameCheck instanceof Function&&Ae.attributeNameCheck(t))||"is"===t&&Ae.allowCustomizedBuiltInElements&&(Ae.tagNameCheck instanceof RegExp&&T(Ae.tagNameCheck,i)||Ae.tagNameCheck instanceof Function&&Ae.tagNameCheck(i))))return!1}else if($e[t]);else if(T(Ne,f(i,fe,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==_(i,"data:")||!Ye[e])if(xe&&!T(pe,f(i,fe,"")));else if(i)return!1;return!0},Ct=function(e){return"annotation-xml"!==e&&p(e,_e)},Lt=function(e){At("beforeSanitizeAttributes",e,null);const{attributes:t}=e;if(!t)return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:be};let r=t.length;for(;r--;){const a=t[r],{name:o,namespaceURI:s,value:l}=a,c=ot(o);let u="value"===o?l:N(l);if(n.attrName=c,n.attrValue=u,n.keepAttr=!0,n.forceKeepAttr=void 0,At("uponSanitizeAttribute",e,n),u=n.attrValue,Ie&&T(/((--!?|])>)|<\/(style|title)/i,u)){Nt(o,e);continue}if(n.forceKeepAttr)continue;if(Nt(o,e),!n.keepAttr)continue;if(!Re&&T(/\/>/i,u)){Nt(o,e);continue}De&&h([he,de,ue],(e=>{u=f(u,e," ")}));const m=ot(e.nodeName);if(St(m,c,u)){if(!He||"id"!==c&&"name"!==c||(Nt(o,e),u=Ge+u),ie&&"object"==typeof W&&"function"==typeof W.getAttributeType)if(s);else switch(W.getAttributeType(m,c)){case"TrustedHTML":u=ie.createHTML(u);break;case"TrustedScriptURL":u=ie.createScriptURL(u)}try{s?e.setAttributeNS(s,o,u):e.setAttribute(o,u),bt(e)?_t(e):d(i.removed)}catch(e){}}}At("afterSanitizeAttributes",e,null)},xt=function e(t){let i=null;const n=Tt(t);for(At("beforeSanitizeShadowDOM",t,null);i=n.nextNode();)At("uponSanitizeShadowNode",i,null),vt(i)||(i.content instanceof l&&e(i.content),Lt(i));At("afterSanitizeShadowDOM",t,null)};return i.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,a=null,o=null,s=null;if(et=!e,et&&(e="\x3c!--\x3e"),"string"!=typeof e&&!yt(e)){if("function"!=typeof e.toString)throw b("toString is not a function");if("string"!=typeof(e=e.toString()))throw b("dirty is not a string, aborting")}if(!i.isSupported)return e;if(we||ht(t),i.removed=[],"string"==typeof e&&(We=!1),We){if(e.nodeName){const t=ot(e.nodeName);if(!Ee[t]||ve[t])throw b("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof y)n=Et("\x3c!----\x3e"),a=n.ownerDocument.importNode(e,!0),a.nodeType===K.element&&"BODY"===a.nodeName||"HTML"===a.nodeName?n=a:n.appendChild(a);else{if(!Me&&!De&&!Oe&&-1===e.indexOf("<"))return ie&&Be?ie.createHTML(e):e;if(n=Et(e),!n)return Me?null:Be?ne:""}n&&Pe&&_t(n.firstChild);const c=Tt(We?e:n);for(;o=c.nextNode();)vt(o)||(o.content instanceof l&&xt(o.content),Lt(o));if(We)return e;if(Me){if(ke)for(s=oe.call(n.ownerDocument);n.firstChild;)s.appendChild(n.firstChild);else s=n;return(be.shadowroot||be.shadowrootmode)&&(s=le.call(r,s,!0)),s}let d=Oe?n.outerHTML:n.innerHTML;return Oe&&Ee["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&T(V,n.ownerDocument.doctype.name)&&(d="\n"+d),De&&h([he,de,ue],(e=>{d=f(d,e," ")})),ie&&Be?ie.createHTML(d):d},i.setConfig=function(){ht(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),we=!0},i.clearConfig=function(){st=null,we=!1},i.isValidAttribute=function(e,t,i){st||ht({});const n=ot(e),r=ot(t);return St(n,r,i)},i.addHook=function(e,t){"function"==typeof t&&(ce[e]=ce[e]||[],u(ce[e],t))},i.removeHook=function(e){if(ce[e])return d(ce[e])},i.removeHooks=function(e){ce[e]&&(ce[e]=[])},i.removeAllHooks=function(){ce={}},i}return Q()}()}},t={};function i(n){var r=t[n];if(void 0!==r)return r.exports;var a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,i),a.exports}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.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})};var n={};return(()=>{"use strict";i.r(n),i.d(n,{applyReaderable:()=>o,isReaderable:()=>a});var e=i(396),t=i(838),r=i.n(t);function a(){return(0,e.isProbablyReaderable)(document)}function o(){var t,i=document.cloneNode(!0),n=(t=i,new e.Readability(t).parse()),a=r().sanitize(n.content);a&&(document.body.innerHTML=''+a+"
")}window.isReaderable=a,window.applyReaderable=o})(),n})()));
\ No newline at end of file
diff --git a/app/js/readability/dist/readability.min.js.gz b/app/js/readability/dist/readability.min.js.gz
deleted file mode 100644
index 477fe80e..00000000
Binary files a/app/js/readability/dist/readability.min.js.gz and /dev/null differ
diff --git a/app/js/readability/dist/stats.json b/app/js/readability/dist/stats.json
deleted file mode 100644
index 3feaf288..00000000
--- a/app/js/readability/dist/stats.json
+++ /dev/null
@@ -1,1362 +0,0 @@
-{
- "hash": "8d23fa454595d8aa7895",
- "version": "5.92.1",
- "time": 1715,
- "builtAt": 1720514525488,
- "publicPath": "auto",
- "outputPath": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/dist",
- "assetsByChunkName": {
- "main": [
- "readability.min.js"
- ]
- },
- "assets": [
- {
- "type": "asset",
- "name": "readability.min.js",
- "size": 55954,
- "emitted": true,
- "comparedForEmit": false,
- "cached": false,
- "info": {
- "javascriptModule": false,
- "minimized": true,
- "related": {
- "gzipped": "readability.min.js.gz"
- },
- "size": 55954
- },
- "chunkNames": [
- "main"
- ],
- "chunkIdHints": [],
- "auxiliaryChunkNames": [],
- "auxiliaryChunkIdHints": [],
- "filteredRelated": 0,
- "related": [
- {
- "type": "gzipped",
- "name": "readability.min.js.gz",
- "size": 18947,
- "emitted": true,
- "comparedForEmit": false,
- "cached": false,
- "info": {
- "compressed": true,
- "size": 18947
- },
- "chunkNames": [],
- "chunkIdHints": [],
- "auxiliaryChunkNames": [],
- "auxiliaryChunkIdHints": [],
- "related": {},
- "chunks": [],
- "auxiliaryChunks": [],
- "isOverSizeLimit": false
- }
- ],
- "chunks": [
- 792
- ],
- "auxiliaryChunks": [],
- "isOverSizeLimit": false
- }
- ],
- "chunks": [
- {
- "rendered": true,
- "initial": true,
- "entry": true,
- "recorded": false,
- "size": 157907,
- "sizes": {
- "javascript": 156970,
- "runtime": 937
- },
- "names": [
- "main"
- ],
- "idHints": [],
- "runtime": [
- "main"
- ],
- "files": [
- "readability.min.js"
- ],
- "auxiliaryFiles": [],
- "hash": "55ea9d503085bb5260ad",
- "childrenByOrder": {},
- "id": 792,
- "siblings": [],
- "parents": [],
- "children": [],
- "modules": [
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 4162,
- "sizes": {
- "javascript": 4162
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "name": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "index": 3,
- "preOrderIndex": 3,
- "index2": 1,
- "postOrderIndex": 1,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "dependent": true,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "issuerName": "./node_modules/@mozilla/readability/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- },
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "id": 396
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 804,
- "issuerId": 396,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "module": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "moduleName": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "resolvedModule": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "107:2-16",
- "moduleId": 804,
- "resolvedModuleId": 804
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs require",
- "active": true,
- "explanation": "",
- "userRequest": "./Readability-readerable",
- "loc": "3:27-62",
- "moduleId": 396,
- "resolvedModuleId": 396
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 107:2-16",
- "Statement (VariableDeclaration) with side effects in source code at 22:0-27:2",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 2
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 84033,
- "sizes": {
- "javascript": 84033
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "name": "./node_modules/@mozilla/readability/Readability.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "index": 2,
- "preOrderIndex": 2,
- "index2": 0,
- "postOrderIndex": 0,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "dependent": true,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "issuerName": "./node_modules/@mozilla/readability/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- },
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "id": 396
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 238,
- "issuerId": 396,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "module": "./node_modules/@mozilla/readability/Readability.js",
- "moduleName": "./node_modules/@mozilla/readability/Readability.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "resolvedModule": "./node_modules/@mozilla/readability/Readability.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "2313:2-16",
- "moduleId": 238,
- "resolvedModuleId": 238
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs require",
- "active": true,
- "explanation": "",
- "userRequest": "./Readability",
- "loc": "2:18-42",
- "moduleId": 396,
- "resolvedModuleId": 396
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 2313:2-16",
- "Statement (ExpressionStatement) with side effects in source code at 98:0-2309:2",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 2
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 226,
- "sizes": {
- "javascript": 226
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "index": 1,
- "preOrderIndex": 1,
- "index2": 2,
- "postOrderIndex": 2,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "dependent": true,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "issuerName": "./src/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 396,
- "issuerId": 954,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "5:0-14",
- "moduleId": 396,
- "resolvedModuleId": 396
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony side effect evaluation",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "1:0-73",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "4:9-29",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "7:19-30",
- "moduleId": 954,
- "resolvedModuleId": 954
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 5:0-14",
- "Statement (VariableDeclaration) with side effects in source code at 2:0-43",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 1
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 67137,
- "sizes": {
- "javascript": 67137
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "name": "./node_modules/dompurify/dist/purify.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "index": 4,
- "preOrderIndex": 4,
- "index2": 3,
- "postOrderIndex": 3,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "dependent": true,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "issuerName": "./src/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 838,
- "issuerId": 954,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony side effect evaluation",
- "active": true,
- "explanation": "",
- "userRequest": "dompurify",
- "loc": "2:0-34",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "dompurify",
- "loc": "14:15-33",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "module": "./node_modules/dompurify/dist/purify.js",
- "moduleName": "./node_modules/dompurify/dist/purify.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "resolvedModule": "./node_modules/dompurify/dist/purify.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "4:65-79",
- "moduleId": 838,
- "resolvedModuleId": 838
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "module": "./node_modules/dompurify/dist/purify.js",
- "moduleName": "./node_modules/dompurify/dist/purify.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "resolvedModule": "./node_modules/dompurify/dist/purify.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "7:3-7",
- "moduleId": 838,
- "resolvedModuleId": 838
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: this is used directly at 7:3-7",
- "CommonJS bailout: module.exports is used directly at 4:65-79",
- "Statement (ExpressionStatement) with side effects in source code at 3:0-1561:4",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 1
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 1412,
- "sizes": {
- "javascript": 1412
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "index": 0,
- "preOrderIndex": 0,
- "index2": 4,
- "postOrderIndex": 4,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "dependent": false,
- "issuer": null,
- "issuerName": null,
- "issuerPath": null,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 954,
- "issuerId": null,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": null,
- "module": null,
- "moduleName": null,
- "resolvedModuleIdentifier": null,
- "resolvedModule": null,
- "type": "entry",
- "active": true,
- "explanation": "",
- "userRequest": "./src/index.js",
- "loc": "main",
- "moduleId": null,
- "resolvedModuleId": null
- },
- {
- "moduleIdentifier": null,
- "module": null,
- "moduleName": null,
- "resolvedModuleIdentifier": null,
- "resolvedModule": null,
- "type": null,
- "active": true,
- "explanation": "used as library export",
- "userRequest": null,
- "moduleId": null,
- "resolvedModuleId": null
- }
- ],
- "usedExports": true,
- "providedExports": [
- "applyReaderable",
- "isReaderable"
- ],
- "optimizationBailout": [
- "Statement (ExpressionStatement) with side effects in source code at 33:0-35",
- "ModuleConcatenation bailout: Cannot concat with ./node_modules/@mozilla/readability/index.js: Module is not an ECMAScript module",
- "ModuleConcatenation bailout: Cannot concat with ./node_modules/dompurify/dist/purify.js: Module is not an ECMAScript module"
- ],
- "depth": 0
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 267,
- "sizes": {
- "runtime": 267
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/compat get default export",
- "name": "webpack/runtime/compat get default export",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "dependent": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 308,
- "sizes": {
- "runtime": 308
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/define property getters",
- "name": "webpack/runtime/define property getters",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "dependent": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 88,
- "sizes": {
- "runtime": 88
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/hasOwnProperty shorthand",
- "name": "webpack/runtime/hasOwnProperty shorthand",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "dependent": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 274,
- "sizes": {
- "runtime": 274
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/make namespace object",
- "name": "webpack/runtime/make namespace object",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "dependent": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- }
- ],
- "origins": [
- {
- "module": "",
- "moduleIdentifier": "",
- "moduleName": "",
- "loc": "main",
- "request": "./src/index.js"
- }
- ]
- }
- ],
- "modules": [
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 1412,
- "sizes": {
- "javascript": 1412
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "index": 0,
- "preOrderIndex": 0,
- "index2": 4,
- "postOrderIndex": 4,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "issuer": null,
- "issuerName": null,
- "issuerPath": null,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 954,
- "issuerId": null,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": null,
- "module": null,
- "moduleName": null,
- "resolvedModuleIdentifier": null,
- "resolvedModule": null,
- "type": "entry",
- "active": true,
- "explanation": "",
- "userRequest": "./src/index.js",
- "loc": "main",
- "moduleId": null,
- "resolvedModuleId": null
- },
- {
- "moduleIdentifier": null,
- "module": null,
- "moduleName": null,
- "resolvedModuleIdentifier": null,
- "resolvedModule": null,
- "type": null,
- "active": true,
- "explanation": "used as library export",
- "userRequest": null,
- "moduleId": null,
- "resolvedModuleId": null
- }
- ],
- "usedExports": true,
- "providedExports": [
- "applyReaderable",
- "isReaderable"
- ],
- "optimizationBailout": [
- "Statement (ExpressionStatement) with side effects in source code at 33:0-35",
- "ModuleConcatenation bailout: Cannot concat with ./node_modules/@mozilla/readability/index.js: Module is not an ECMAScript module",
- "ModuleConcatenation bailout: Cannot concat with ./node_modules/dompurify/dist/purify.js: Module is not an ECMAScript module"
- ],
- "depth": 0
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 226,
- "sizes": {
- "javascript": 226
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "index": 1,
- "preOrderIndex": 1,
- "index2": 2,
- "postOrderIndex": 2,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "issuerName": "./src/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 396,
- "issuerId": 954,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "5:0-14",
- "moduleId": 396,
- "resolvedModuleId": 396
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony side effect evaluation",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "1:0-73",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "4:9-29",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "@mozilla/readability",
- "loc": "7:19-30",
- "moduleId": 954,
- "resolvedModuleId": 954
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 5:0-14",
- "Statement (VariableDeclaration) with side effects in source code at 2:0-43",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 1
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 67137,
- "sizes": {
- "javascript": 67137
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "name": "./node_modules/dompurify/dist/purify.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "index": 4,
- "preOrderIndex": 4,
- "index2": 3,
- "postOrderIndex": 3,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "issuerName": "./src/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 838,
- "issuerId": 954,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony side effect evaluation",
- "active": true,
- "explanation": "",
- "userRequest": "dompurify",
- "loc": "2:0-34",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "module": "./src/index.js",
- "moduleName": "./src/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "resolvedModule": "./src/index.js",
- "type": "harmony import specifier",
- "active": true,
- "explanation": "",
- "userRequest": "dompurify",
- "loc": "14:15-33",
- "moduleId": 954,
- "resolvedModuleId": 954
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "module": "./node_modules/dompurify/dist/purify.js",
- "moduleName": "./node_modules/dompurify/dist/purify.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "resolvedModule": "./node_modules/dompurify/dist/purify.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "4:65-79",
- "moduleId": 838,
- "resolvedModuleId": 838
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "module": "./node_modules/dompurify/dist/purify.js",
- "moduleName": "./node_modules/dompurify/dist/purify.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/dompurify/dist/purify.js",
- "resolvedModule": "./node_modules/dompurify/dist/purify.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "7:3-7",
- "moduleId": 838,
- "resolvedModuleId": 838
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: this is used directly at 7:3-7",
- "CommonJS bailout: module.exports is used directly at 4:65-79",
- "Statement (ExpressionStatement) with side effects in source code at 3:0-1561:4",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 1
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 84033,
- "sizes": {
- "javascript": 84033
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "name": "./node_modules/@mozilla/readability/Readability.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "index": 2,
- "preOrderIndex": 2,
- "index2": 0,
- "postOrderIndex": 0,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "issuerName": "./node_modules/@mozilla/readability/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- },
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "id": 396
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 238,
- "issuerId": 396,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "module": "./node_modules/@mozilla/readability/Readability.js",
- "moduleName": "./node_modules/@mozilla/readability/Readability.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability.js",
- "resolvedModule": "./node_modules/@mozilla/readability/Readability.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "2313:2-16",
- "moduleId": 238,
- "resolvedModuleId": 238
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs require",
- "active": true,
- "explanation": "",
- "userRequest": "./Readability",
- "loc": "2:18-42",
- "moduleId": 396,
- "resolvedModuleId": 396
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 2313:2-16",
- "Statement (ExpressionStatement) with side effects in source code at 98:0-2309:2",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 2
- },
- {
- "type": "module",
- "moduleType": "javascript/auto",
- "layer": null,
- "size": 4162,
- "sizes": {
- "javascript": 4162
- },
- "built": true,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "name": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "nameForCondition": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "index": 3,
- "preOrderIndex": 3,
- "index2": 1,
- "postOrderIndex": 1,
- "cacheable": true,
- "optional": false,
- "orphan": false,
- "issuer": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "issuerName": "./node_modules/@mozilla/readability/index.js",
- "issuerPath": [
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!/home/fafre/Repos/kagi_bang_bang/app/js/readability/src/index.js",
- "name": "./src/index.js",
- "id": 954
- },
- {
- "identifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "name": "./node_modules/@mozilla/readability/index.js",
- "id": 396
- }
- ],
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": 804,
- "issuerId": 396,
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "module": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "moduleName": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/Readability-readerable.js",
- "resolvedModule": "./node_modules/@mozilla/readability/Readability-readerable.js",
- "type": "cjs self exports reference",
- "active": true,
- "explanation": "",
- "userRequest": null,
- "loc": "107:2-16",
- "moduleId": 804,
- "resolvedModuleId": 804
- },
- {
- "moduleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "module": "./node_modules/@mozilla/readability/index.js",
- "moduleName": "./node_modules/@mozilla/readability/index.js",
- "resolvedModuleIdentifier": "/home/fafre/Repos/kagi_bang_bang/app/js/readability/node_modules/@mozilla/readability/index.js",
- "resolvedModule": "./node_modules/@mozilla/readability/index.js",
- "type": "cjs require",
- "active": true,
- "explanation": "",
- "userRequest": "./Readability-readerable",
- "loc": "3:27-62",
- "moduleId": 396,
- "resolvedModuleId": 396
- }
- ],
- "usedExports": null,
- "providedExports": null,
- "optimizationBailout": [
- "CommonJS bailout: module.exports is used directly at 107:2-16",
- "Statement (VariableDeclaration) with side effects in source code at 22:0-27:2",
- "ModuleConcatenation bailout: Module is not an ECMAScript module"
- ],
- "depth": 2
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 267,
- "sizes": {
- "runtime": 267
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/compat get default export",
- "name": "webpack/runtime/compat get default export",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 308,
- "sizes": {
- "runtime": 308
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/define property getters",
- "name": "webpack/runtime/define property getters",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 88,
- "sizes": {
- "runtime": 88
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/hasOwnProperty shorthand",
- "name": "webpack/runtime/hasOwnProperty shorthand",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- },
- {
- "type": "module",
- "moduleType": "runtime",
- "layer": null,
- "size": 274,
- "sizes": {
- "runtime": 274
- },
- "built": false,
- "codeGenerated": true,
- "buildTimeExecuted": false,
- "cached": false,
- "identifier": "webpack/runtime/make namespace object",
- "name": "webpack/runtime/make namespace object",
- "nameForCondition": null,
- "index": null,
- "preOrderIndex": null,
- "index2": null,
- "postOrderIndex": null,
- "optional": false,
- "orphan": false,
- "failed": false,
- "errors": 0,
- "warnings": 0,
- "id": "",
- "chunks": [
- 792
- ],
- "assets": [],
- "reasons": [],
- "usedExports": null,
- "providedExports": [],
- "optimizationBailout": [],
- "depth": null
- }
- ],
- "entrypoints": {
- "main": {
- "name": "main",
- "chunks": [
- 792
- ],
- "assets": [
- {
- "name": "readability.min.js",
- "size": 55954
- }
- ],
- "filteredAssets": 0,
- "assetsSize": 55954,
- "auxiliaryAssets": [],
- "filteredAuxiliaryAssets": 0,
- "auxiliaryAssetsSize": 0,
- "children": {},
- "childAssets": {},
- "isOverSizeLimit": false
- }
- },
- "namedChunkGroups": {
- "main": {
- "name": "main",
- "chunks": [
- 792
- ],
- "assets": [
- {
- "name": "readability.min.js",
- "size": 55954
- }
- ],
- "filteredAssets": 0,
- "assetsSize": 55954,
- "auxiliaryAssets": [],
- "filteredAuxiliaryAssets": 0,
- "auxiliaryAssetsSize": 0,
- "children": {},
- "childAssets": {},
- "isOverSizeLimit": false
- }
- },
- "errors": [],
- "errorsCount": 0,
- "warnings": [],
- "warningsCount": 0,
- "children": []
-}
\ No newline at end of file
diff --git a/app/js/readability/src/index.js b/app/js/readability/src/index.js
deleted file mode 100644
index 44d820dc..00000000
--- a/app/js/readability/src/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { Readability, isProbablyReaderable } from '@mozilla/readability';
-import DOMPurify from 'dompurify';
-
-function isReaderable() {
- return isProbablyReaderable(document);
-}
-
-function parseReaderable(doc) {
- const reader = new Readability(doc);
- const article = reader.parse();
- return article;
-}
-
-function applyReaderable() {
- const clonedDoc = document.cloneNode(true);
- const article = parseReaderable(clonedDoc);
- const markup = DOMPurify.sanitize(article.content);
-
- // console.log('article title: ', parsed.title);
- // console.log('HTML string of processed article content: ', parsed.content);
- // console.log('text content of the article, with all the HTML tags removed: ', parsed.textContent);
- // console.log('length of an article, in characters: ', parsed.length);
- // console.log('article description, or short excerpt from the content: ', parsed.excerpt);
- // console.log('author metadata: ', parsed.byline);
- // console.log('content direction: ', parsed.dir);
- // console.log('name of the site: ', parsed.siteName);
- // console.log('content language: ', parsed.lang);
- // console.log('published time: ', parsed.publishedTime);
-
- if (markup) {
- document.body.innerHTML = '' + markup + '
';
- }
-}
-
-// Attach functions to the window object
-window.isReaderable = isReaderable;
-window.applyReaderable = applyReaderable;
-
-export { isReaderable, applyReaderable };
diff --git a/app/lib/core/error_observer.dart b/app/lib/core/error_observer.dart
index 39cc61cc..972935a4 100644
--- a/app/lib/core/error_observer.dart
+++ b/app/lib/core/error_observer.dart
@@ -1,5 +1,5 @@
-import 'package:lensai/core/logger.dart';
import 'package:riverpod/riverpod.dart';
+import 'package:weblibre/core/logger.dart';
class ErrorObserver extends ProviderObserver {
const ErrorObserver();
diff --git a/app/lib/core/extension/result_async.dart b/app/lib/core/extension/result_async.dart
deleted file mode 100644
index e9448764..00000000
--- a/app/lib/core/extension/result_async.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-import 'package:exceptions/exceptions.dart';
-import 'package:riverpod/riverpod.dart';
-
-extension AsyncExtension on Result {
- AsyncValue toAsyncValue() {
- return switch (this) {
- Success(value: final value) => AsyncValue.data(value),
- // TODO: Handle this case.
- Failure(
- error: final error,
- ) =>
- AsyncError(error.message, error.stackTrace ?? StackTrace.empty),
- };
- }
-}
diff --git a/app/lib/core/http_error_handler.dart b/app/lib/core/http_error_handler.dart
index 96c545e0..cbd5ff08 100644
--- a/app/lib/core/http_error_handler.dart
+++ b/app/lib/core/http_error_handler.dart
@@ -2,30 +2,24 @@ import 'package:exceptions/exceptions.dart';
import 'package:http/http.dart';
import 'package:universal_io/io.dart';
-ErrorMessage handleHttpError(
- Exception exception,
- StackTrace stackTrace,
-) {
+ErrorMessage handleHttpError(Exception exception, StackTrace stackTrace) {
return switch (exception) {
SocketException() => const ErrorMessage(
- source: 'http',
- message: 'Could not contact remote service',
- ),
+ source: 'http',
+ message: 'Could not contact remote service',
+ ),
HttpException() => const ErrorMessage(
- source: 'http',
- message: 'Web request returned error',
- ),
+ source: 'http',
+ message: 'Web request returned error',
+ ),
FormatException() => const ErrorMessage(
- source: 'http',
- message: 'Bad response format',
- ),
+ source: 'http',
+ message: 'Bad response format',
+ ),
ClientException() => const ErrorMessage(
- source: 'http',
- message: 'Could not contact remote service',
- ),
- _ => ErrorMessage.fromException(
- exception,
- stackTrace,
- )
+ source: 'http',
+ message: 'Could not contact remote service',
+ ),
+ _ => ErrorMessage.fromException(exception, stackTrace),
};
}
diff --git a/app/lib/core/logger.dart b/app/lib/core/logger.dart
index 55058ea0..b2201889 100644
--- a/app/lib/core/logger.dart
+++ b/app/lib/core/logger.dart
@@ -1,3 +1,15 @@
import 'package:logger/logger.dart';
-final logger = Logger();
+class _DebugLogFilter extends LogFilter {
+ @override
+ bool shouldLog(LogEvent event) {
+ //Log all events
+ return true;
+ }
+}
+
+final loggerMemory = MemoryOutput(
+ bufferSize: 255,
+ secondOutput: ConsoleOutput(),
+);
+final logger = Logger(filter: _DebugLogFilter(), output: loggerMemory);
diff --git a/app/lib/core/providers.dart b/app/lib/core/providers.dart
deleted file mode 100644
index 5df5c93b..00000000
--- a/app/lib/core/providers.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:go_router/go_router.dart';
-import 'package:lensai/core/routing/routes.dart';
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-
-part 'providers.g.dart';
-
-@Riverpod(keepAlive: true)
-GoRouter router(RouterRef ref) => GoRouter(
- debugLogDiagnostics: true,
- routes: $appRoutes,
- );
diff --git a/app/lib/core/providers.g.dart b/app/lib/core/providers.g.dart
deleted file mode 100644
index 5d5f133f..00000000
--- a/app/lib/core/providers.g.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'providers.dart';
-
-// **************************************************************************
-// RiverpodGenerator
-// **************************************************************************
-
-String _$routerHash() => r'4ad45f430b1f43e427e21122d16bd761ca04ae0e';
-
-/// See also [router].
-@ProviderFor(router)
-final routerProvider = Provider.internal(
- router,
- name: r'routerProvider',
- debugGetCreateSourceHash:
- const bool.fromEnvironment('dart.vm.product') ? null : _$routerHash,
- dependencies: null,
- allTransitiveDependencies: null,
-);
-
-typedef RouterRef = ProviderRef;
-// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
diff --git a/app/lib/core/providers/defaults.dart b/app/lib/core/providers/defaults.dart
new file mode 100644
index 00000000..06a035cc
--- /dev/null
+++ b/app/lib/core/providers/defaults.dart
@@ -0,0 +1,14 @@
+import 'package:flutter/material.dart';
+import 'package:riverpod/riverpod.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+part 'defaults.g.dart';
+
+@Riverpod(keepAlive: true)
+Color lightSeedColorFallback(Ref ref) => const Color(0xFF167C80);
+
+@Riverpod(keepAlive: true)
+Color darkSeedColorFallback(Ref ref) => const Color(0xFF167C80);
+
+@Riverpod(keepAlive: true)
+Uri docsUri(Ref ref) => Uri.parse('https://docs.weblibre.eu/');
diff --git a/app/lib/core/providers/defaults.g.dart b/app/lib/core/providers/defaults.g.dart
new file mode 100644
index 00000000..b640b896
--- /dev/null
+++ b/app/lib/core/providers/defaults.g.dart
@@ -0,0 +1,63 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'defaults.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$lightSeedColorFallbackHash() =>
+ r'af151d3293d372f5df451aa8c3a75136377b6ce1';
+
+/// See also [lightSeedColorFallback].
+@ProviderFor(lightSeedColorFallback)
+final lightSeedColorFallbackProvider = Provider.internal(
+ lightSeedColorFallback,
+ name: r'lightSeedColorFallbackProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$lightSeedColorFallbackHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef LightSeedColorFallbackRef = ProviderRef;
+String _$darkSeedColorFallbackHash() =>
+ r'9418cf71e3d80c8a2142e0d3a8820989b29bff86';
+
+/// See also [darkSeedColorFallback].
+@ProviderFor(darkSeedColorFallback)
+final darkSeedColorFallbackProvider = Provider.internal(
+ darkSeedColorFallback,
+ name: r'darkSeedColorFallbackProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$darkSeedColorFallbackHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef DarkSeedColorFallbackRef = ProviderRef;
+String _$docsUriHash() => r'6456efcf97ddc7ee87a67e2d3380f7241e3d76ea';
+
+/// See also [docsUri].
+@ProviderFor(docsUri)
+final docsUriProvider = Provider.internal(
+ docsUri,
+ name: r'docsUriProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$docsUriHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef DocsUriRef = ProviderRef;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/core/providers/format.dart b/app/lib/core/providers/format.dart
new file mode 100644
index 00000000..abc15c2e
--- /dev/null
+++ b/app/lib/core/providers/format.dart
@@ -0,0 +1,19 @@
+import 'package:intl/date_symbol_data_local.dart';
+import 'package:intl/intl.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+part 'format.g.dart';
+
+@Riverpod(keepAlive: true)
+class Format extends _$Format {
+ String fullDateTimeWithTimezone(DateTime date) {
+ final pattern = DateFormat('yMMMMd').addPattern('Hm');
+
+ return pattern.format(date);
+ }
+
+ @override
+ Future build() async {
+ await initializeDateFormatting();
+ }
+}
diff --git a/app/lib/features/content_block/domain/repositories/host.g.dart b/app/lib/core/providers/format.g.dart
similarity index 52%
rename from app/lib/features/content_block/domain/repositories/host.g.dart
rename to app/lib/core/providers/format.g.dart
index f0acb812..a2fcf636 100644
--- a/app/lib/features/content_block/domain/repositories/host.g.dart
+++ b/app/lib/core/providers/format.g.dart
@@ -1,25 +1,25 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
-part of 'host.dart';
+part of 'format.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
-String _$hostRepositoryHash() => r'b28362146b75391f55fb353fc6fde72dc1d2fcb9';
+String _$formatHash() => r'fe7fcdd19b512784a36f3838c57701030475e429';
-/// See also [HostRepository].
-@ProviderFor(HostRepository)
-final hostRepositoryProvider = NotifierProvider.internal(
- HostRepository.new,
- name: r'hostRepositoryProvider',
+/// See also [Format].
+@ProviderFor(Format)
+final formatProvider = AsyncNotifierProvider.internal(
+ Format.new,
+ name: r'formatProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
- : _$hostRepositoryHash,
+ : _$formatHash,
dependencies: null,
allTransitiveDependencies: null,
);
-typedef _$HostRepository = Notifier;
+typedef _$Format = AsyncNotifier;
// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/core/providers/global_drop.dart b/app/lib/core/providers/global_drop.dart
new file mode 100644
index 00000000..7fbe66f6
--- /dev/null
+++ b/app/lib/core/providers/global_drop.dart
@@ -0,0 +1,21 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:weblibre/data/models/drag_data.dart';
+
+part 'global_drop.g.dart';
+
+@Riverpod()
+class WillAcceptDrop extends _$WillAcceptDrop {
+ // ignore: use_setters_to_change_properties api decision
+ void setData(DropTargetData data) {
+ state = data;
+ }
+
+ void clear() {
+ state = null;
+ }
+
+ @override
+ DropTargetData? build() {
+ return null;
+ }
+}
diff --git a/app/lib/core/providers/global_drop.g.dart b/app/lib/core/providers/global_drop.g.dart
new file mode 100644
index 00000000..5bb3e188
--- /dev/null
+++ b/app/lib/core/providers/global_drop.g.dart
@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'global_drop.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$willAcceptDropHash() => r'97b47784ef9101757602b4408d1f545ef2308830';
+
+/// See also [WillAcceptDrop].
+@ProviderFor(WillAcceptDrop)
+final willAcceptDropProvider =
+ AutoDisposeNotifierProvider.internal(
+ WillAcceptDrop.new,
+ name: r'willAcceptDropProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$willAcceptDropHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+ );
+
+typedef _$WillAcceptDrop = AutoDisposeNotifier;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/core/providers/router.dart b/app/lib/core/providers/router.dart
new file mode 100644
index 00000000..963ac6da
--- /dev/null
+++ b/app/lib/core/providers/router.dart
@@ -0,0 +1,35 @@
+import 'package:go_router/go_router.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:weblibre/core/routing/routes.dart';
+import 'package:weblibre/features/user/domain/repositories/onboarding.dart';
+
+part 'router.g.dart';
+
+@Riverpod(keepAlive: true)
+Future router(Ref ref) async {
+ String? initialLocation;
+
+ final onboardingMandatory = await ref
+ .read(onboardingRepositoryProvider.notifier)
+ .isOutdated();
+
+ if (onboardingMandatory) {
+ final current = await ref
+ .read(onboardingRepositoryProvider.notifier)
+ .getCurrentRevision();
+
+ final route = OnboardingRoute(
+ currentRevision: current ?? -1,
+ targetRevision: OnboardingRepository.targetRevision,
+ );
+
+ initialLocation = route.location;
+ }
+
+ return GoRouter(
+ debugLogDiagnostics: true,
+ routes: $appRoutes,
+ initialLocation: initialLocation,
+ );
+}
diff --git a/app/lib/core/providers/router.g.dart b/app/lib/core/providers/router.g.dart
new file mode 100644
index 00000000..fdd8fdc9
--- /dev/null
+++ b/app/lib/core/providers/router.g.dart
@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'router.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$routerHash() => r'ce7cc5b5f236781a06867a852a08ed03d3582022';
+
+/// See also [router].
+@ProviderFor(router)
+final routerProvider = FutureProvider.internal(
+ router,
+ name: r'routerProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$routerHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RouterRef = FutureProviderRef;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/core/routing/routes.bangs.dart b/app/lib/core/routing/routes.bangs.dart
new file mode 100644
index 00000000..ca299a72
--- /dev/null
+++ b/app/lib/core/routing/routes.bangs.dart
@@ -0,0 +1,72 @@
+part of 'routes.dart';
+
+@TypedGoRoute(
+ name: 'BangRoute',
+ path: '/bangs',
+ routes: [
+ TypedGoRoute(
+ name: 'BangSearchRoute',
+ path: 'search/:searchText',
+ ),
+ TypedGoRoute(
+ name: 'BangCategoryRoute',
+ path: 'category/:category',
+ routes: [
+ TypedGoRoute(
+ name: 'BangSubCategoryRoute',
+ path: ':subCategory',
+ ),
+ ],
+ ),
+ ],
+)
+class BangCategoriesRoute extends GoRouteData with _$BangCategoriesRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const BangCategoriesScreen();
+ }
+}
+
+class BangCategoryRoute extends GoRouteData with _$BangCategoryRoute {
+ final String category;
+
+ const BangCategoryRoute({required this.category});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return BangListScreen(category: category);
+ }
+}
+
+class BangSubCategoryRoute extends GoRouteData with _$BangSubCategoryRoute {
+ final String category;
+ final String subCategory;
+
+ const BangSubCategoryRoute({
+ required this.category,
+ required this.subCategory,
+ });
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return BangListScreen(category: category, subCategory: subCategory);
+ }
+}
+
+class BangSearchRoute extends GoRouteData with _$BangSearchRoute {
+ static const String emptySearchText = ' ';
+
+ //This should be nullable but isnt allowed by go_router
+ final String searchText;
+
+ const BangSearchRoute({this.searchText = BangSearchRoute.emptySearchText});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return BangSearchScreen(
+ initialSearchText: (searchText.isEmpty || searchText == emptySearchText)
+ ? null
+ : searchText,
+ );
+ }
+}
diff --git a/app/lib/core/routing/routes.browser.dart b/app/lib/core/routing/routes.browser.dart
new file mode 100644
index 00000000..bf91db53
--- /dev/null
+++ b/app/lib/core/routing/routes.browser.dart
@@ -0,0 +1,145 @@
+part of 'routes.dart';
+
+@TypedGoRoute(
+ name: BrowserRoute.name,
+ path: '/',
+ routes: [
+ TypedGoRoute(name: 'WebPageRoute', path: 'page/:url'),
+ TypedGoRoute(
+ name: 'SearchRoute',
+ path: 'search/:tabType/:searchText',
+ ),
+ TypedGoRoute(name: 'TorProxyRoute', path: 'tor_proxy'),
+ TypedGoRoute(
+ name: 'ContextMenuRoute',
+ path: 'context_menu',
+ ),
+ TypedGoRoute(
+ name: 'ContainerListRoute',
+ path: 'containers',
+ routes: [
+ TypedGoRoute(
+ name: 'ContainerCreateRoute',
+ path: 'create',
+ ),
+ TypedGoRoute(
+ name: 'ContainerEditRoute',
+ path: 'edit',
+ ),
+ ],
+ ),
+ TypedGoRoute(
+ name: 'TabTreeRoute',
+ path: 'tab_tree/:rootTabId',
+ ),
+ ],
+)
+class BrowserRoute extends GoRouteData with _$BrowserRoute {
+ static const name = 'BrowserRoute';
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const BrowserScreen();
+ }
+}
+
+class WebPageRoute extends GoRouteData with _$WebPageRoute {
+ final String url;
+ final WebPageInfo? $extra;
+
+ const WebPageRoute({required this.url, required this.$extra});
+
+ @override
+ Page buildPage(BuildContext context, GoRouterState state) {
+ return DialogPage(
+ builder: (_) => WebPageDialog(url: Uri.parse(url), precachedInfo: $extra),
+ );
+ }
+}
+
+enum TabType { regular, private, child }
+
+class SearchRoute extends GoRouteData with _$SearchRoute {
+ static const String emptySearchText = ' ';
+
+ final TabType tabType;
+
+ //This should be nullable but isnt allowed by go_router
+ final String searchText;
+
+ const SearchRoute({
+ required this.tabType,
+ this.searchText = SearchRoute.emptySearchText,
+ });
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return SearchScreen(
+ tabType: tabType,
+ initialSearchText: (searchText.isEmpty || searchText == emptySearchText)
+ ? null
+ : searchText,
+ );
+ }
+}
+
+class TorProxyRoute extends GoRouteData with _$TorProxyRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const TorProxyScreen();
+ }
+}
+
+class ContainerListRoute extends GoRouteData with _$ContainerListRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const ContainerListScreen();
+ }
+}
+
+class ContainerEditRoute extends GoRouteData with _$ContainerEditRoute {
+ final ContainerData $extra;
+
+ ContainerEditRoute(this.$extra);
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return ContainerEditScreen.edit(initialContainer: $extra);
+ }
+}
+
+class ContainerCreateRoute extends GoRouteData with _$ContainerCreateRoute {
+ final ContainerData $extra;
+
+ ContainerCreateRoute(this.$extra);
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return ContainerEditScreen.create(initialContainer: $extra);
+ }
+}
+
+class ContextMenuRoute extends GoRouteData with _$ContextMenuRoute {
+ final String $extra;
+
+ const ContextMenuRoute(this.$extra);
+
+ @override
+ Page buildPage(BuildContext context, GoRouterState state) {
+ return DialogPage(
+ builder: (_) =>
+ ContextMenuDialog(hitResult: HitResultJson.fromJson($extra)),
+ );
+ }
+}
+
+class TabTreeRoute extends GoRouteData with _$TabTreeRoute {
+ final String rootTabId;
+
+ const TabTreeRoute(this.rootTabId);
+
+ @override
+ Page buildPage(BuildContext context, GoRouterState state) {
+ return DialogPage(builder: (_) => TabTreeDialog(rootTabId));
+ }
+}
diff --git a/app/lib/core/routing/routes.dart b/app/lib/core/routing/routes.dart
index c006a4f8..1cb5f9c4 100644
--- a/app/lib/core/routing/routes.dart
+++ b/app/lib/core/routing/routes.dart
@@ -1,160 +1,69 @@
+import 'dart:convert';
+
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
-import 'package:lensai/core/routing/dialog_page.dart';
-import 'package:lensai/features/about/presentation/screens/about.dart';
-import 'package:lensai/features/bangs/presentation/screens/categories.dart';
-import 'package:lensai/features/bangs/presentation/screens/list.dart';
-import 'package:lensai/features/bangs/presentation/screens/search.dart';
-import 'package:lensai/features/chat_archive/presentation/screens/detail.dart';
-import 'package:lensai/features/chat_archive/presentation/screens/list.dart';
-import 'package:lensai/features/chat_archive/presentation/screens/search.dart';
-import 'package:lensai/features/search_browser/presentation/screens/browser.dart';
-import 'package:lensai/features/settings/presentation/screens/settings.dart';
-import 'package:lensai/features/topics/presentation/screens/topic_list.dart';
+import 'package:weblibre/core/routing/widgets/dialog_page.dart';
+import 'package:weblibre/data/models/web_page_info.dart';
+import 'package:weblibre/features/about/presentation/screens/about.dart';
+import 'package:weblibre/features/bangs/presentation/screens/categories.dart';
+import 'package:weblibre/features/bangs/presentation/screens/list.dart';
+import 'package:weblibre/features/bangs/presentation/screens/search.dart';
+import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/tab_tree.dart';
+import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/web_page_dialog.dart';
+import 'package:weblibre/features/geckoview/features/browser/presentation/screens/browser.dart';
+import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
+import 'package:weblibre/features/geckoview/features/contextmenu/presentation/context_menu_dialog.dart';
+import 'package:weblibre/features/geckoview/features/search/presentation/screens/search.dart';
+import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
+import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_edit.dart';
+import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_list.dart';
+import 'package:weblibre/features/onboarding/presentation/onboarding.dart';
+import 'package:weblibre/features/settings/presentation/screens/bang_settings.dart';
+import 'package:weblibre/features/settings/presentation/screens/general_settings.dart';
+import 'package:weblibre/features/settings/presentation/screens/settings.dart';
+import 'package:weblibre/features/settings/presentation/screens/web_engine_hardening.dart';
+import 'package:weblibre/features/settings/presentation/screens/web_engine_hardening_group.dart';
+import 'package:weblibre/features/settings/presentation/screens/web_engine_settings.dart';
+import 'package:weblibre/features/tor/presentation/screens/tor_proxy.dart';
+import 'package:weblibre/features/web_feed/presentation/add_feed_dialog.dart';
+import 'package:weblibre/features/web_feed/presentation/screens/feed_article.dart';
+import 'package:weblibre/features/web_feed/presentation/screens/feed_article_list.dart';
+import 'package:weblibre/features/web_feed/presentation/screens/feed_edit.dart';
+import 'package:weblibre/features/web_feed/presentation/screens/feed_list.dart';
+import 'package:weblibre/features/web_feed/presentation/select_feed_dialog.dart';
part 'routes.g.dart';
+part 'routes.settings.dart';
+part 'routes.browser.dart';
+part 'routes.bangs.dart';
+part 'routes.feeds.dart';
-@TypedGoRoute(
- name: 'KagiRoute',
- path: '/',
- routes: [
- TypedGoRoute(
- name: 'AboutRoute',
- path: 'about',
- ),
- TypedGoRoute(
- name: 'BangRoute',
- path: 'bangs',
- routes: [
- TypedGoRoute(
- name: 'BangSearchRoute',
- path: 'search',
- ),
- TypedGoRoute(
- name: 'BangCategoryRoute',
- path: 'category/:category',
- routes: [
- TypedGoRoute(
- name: 'BangSubCategoryRoute',
- path: ':subCategory',
- ),
- ],
- ),
- ],
- ),
- TypedGoRoute(
- name: 'TopicsRoute',
- path: 'topics',
- ),
- ],
-)
-class KagiRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const KagiScreen();
- }
-}
-
-class AboutRoute extends GoRouteData {
+@TypedGoRoute(name: 'AboutRoute', path: '/about')
+class AboutRoute extends GoRouteData with _$AboutRoute {
@override
Page buildPage(BuildContext context, GoRouterState state) {
return DialogPage(builder: (_) => const AboutDialogScreen());
}
}
-class BangCategoriesRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const BangCategoriesScreen();
- }
-}
+@TypedGoRoute(
+ name: 'OnboardingRoute',
+ path: '/onboarding/:currentRevision/:targetRevision',
+)
+class OnboardingRoute extends GoRouteData with _$OnboardingRoute {
+ final int currentRevision;
+ final int targetRevision;
-class BangCategoryRoute extends GoRouteData {
- final String category;
-
- const BangCategoryRoute({required this.category});
-
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return BangListScreen(category: category);
- }
-}
-
-class BangSubCategoryRoute extends GoRouteData {
- final String category;
- final String subCategory;
-
- const BangSubCategoryRoute({
- required this.category,
- required this.subCategory,
+ const OnboardingRoute({
+ required this.currentRevision,
+ required this.targetRevision,
});
@override
Widget build(BuildContext context, GoRouterState state) {
- return BangListScreen(category: category, subCategory: subCategory);
- }
-}
-
-class BangSearchRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const BangSearchScreen();
- }
-}
-
-class TopicListRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const TopicListScreen();
- }
-}
-
-@TypedGoRoute(
- name: 'SettingsRoute',
- path: '/settings',
-)
-class SettingsRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const SettingsScreen();
- }
-}
-
-@TypedGoRoute(
- name: 'ChatArchiveListRoute',
- path: '/chat_archive',
- routes: [
- TypedGoRoute(
- name: 'ChatArchiveSearchRoute',
- path: 'search',
- ),
- TypedGoRoute(
- name: 'ChatArchiveDetailRoute',
- path: 'detail/:fileName',
- ),
- ],
-)
-class ChatArchiveListRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const ChatArchiveListScreen();
- }
-}
-
-class ChatArchiveSearchRoute extends GoRouteData {
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return const ChatArchiveSearchScreen();
- }
-}
-
-class ChatArchiveDetailRoute extends GoRouteData {
- final String fileName;
-
- const ChatArchiveDetailRoute({required this.fileName});
-
- @override
- Widget build(BuildContext context, GoRouterState state) {
- return ChatArchiveDetailScreen(fileName);
+ return OnboardingScreen(
+ currentRevision: currentRevision,
+ targetRevision: targetRevision,
+ );
}
}
diff --git a/app/lib/core/routing/routes.feeds.dart b/app/lib/core/routing/routes.feeds.dart
new file mode 100644
index 00000000..264da9c0
--- /dev/null
+++ b/app/lib/core/routing/routes.feeds.dart
@@ -0,0 +1,106 @@
+part of 'routes.dart';
+
+@TypedGoRoute(
+ name: 'FeedListRoute',
+ path: '/feeds',
+ routes: [
+ TypedGoRoute(name: FeedAddRoute.name, path: 'add'),
+ TypedGoRoute(
+ name: 'FeedArticleListRoute',
+ path: 'articles/:feedId',
+ ),
+ TypedGoRoute(
+ name: 'FeedArticleRoute',
+ path: 'article/:articleId',
+ ),
+ TypedGoRoute(
+ name: 'FeedCreateRoute',
+ path: 'create/:feedId',
+ ),
+ TypedGoRoute(
+ name: 'SelectFeedDialogRoute',
+ path: 'available/:feedsJson',
+ ),
+ TypedGoRoute(name: 'FeedEditRoute', path: 'edit/:feedId'),
+ ],
+)
+class FeedListRoute extends GoRouteData with _$FeedListRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const FeedListScreen();
+ }
+}
+
+class FeedCreateRoute extends GoRouteData with _$FeedCreateRoute {
+ final Uri feedId;
+
+ FeedCreateRoute({required this.feedId});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return FeedEditScreen.create(feedId: feedId);
+ }
+}
+
+class SelectFeedDialogRoute extends GoRouteData with _$SelectFeedDialogRoute {
+ final String feedsJson;
+
+ const SelectFeedDialogRoute({required this.feedsJson});
+
+ @override
+ Page buildPage(BuildContext context, GoRouterState state) {
+ final feedUris = Set.from(
+ (jsonDecode(feedsJson) as List).map(
+ (url) => Uri.parse(url as String),
+ ),
+ );
+
+ return DialogPage(builder: (_) => SelectFeedDialog(feedUris: feedUris));
+ }
+}
+
+class FeedEditRoute extends GoRouteData with _$FeedEditRoute {
+ final Uri feedId;
+
+ const FeedEditRoute({required this.feedId});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return FeedEditScreen.edit(feedId: feedId);
+ }
+}
+
+class FeedAddRoute extends GoRouteData with _$FeedAddRoute {
+ final Uri? $extra;
+
+ static const name = 'FeedAddRoute';
+
+ const FeedAddRoute({this.$extra});
+
+ @override
+ Page buildPage(BuildContext context, GoRouterState state) {
+ return DialogPage(builder: (_) => AddFeedDialog(initialUri: $extra));
+ }
+}
+
+class FeedArticleListRoute extends GoRouteData with _$FeedArticleListRoute {
+ final Uri feedId;
+
+ FeedArticleListRoute({required this.feedId});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return FeedArticleListScreen(feedId: feedId);
+ }
+}
+
+class FeedArticleRoute extends GoRouteData with _$FeedArticleRoute {
+ final String articleId;
+
+ FeedArticleRoute({required this.articleId});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return FeedArticleScreen(articleId: articleId);
+ }
+}
diff --git a/app/lib/core/routing/routes.g.dart b/app/lib/core/routing/routes.g.dart
index 4e7a1c44..a261c31d 100644
--- a/app/lib/core/routing/routes.g.dart
+++ b/app/lib/core/routing/routes.g.dart
@@ -7,272 +7,877 @@ part of 'routes.dart';
// **************************************************************************
List get $appRoutes => [
- $kagiRoute,
- $settingsRoute,
- $chatArchiveListRoute,
- ];
+ $aboutRoute,
+ $onboardingRoute,
+ $settingsRoute,
+ $browserRoute,
+ $bangCategoriesRoute,
+ $feedListRoute,
+];
-RouteBase get $kagiRoute => GoRouteData.$route(
- path: '/',
- name: 'KagiRoute',
- factory: $KagiRouteExtension._fromState,
+RouteBase get $aboutRoute => GoRouteData.$route(
+ path: '/about',
+ name: 'AboutRoute',
+
+ factory: _$AboutRoute._fromState,
+);
+
+mixin _$AboutRoute on GoRouteData {
+ static AboutRoute _fromState(GoRouterState state) => AboutRoute();
+
+ @override
+ String get location => GoRouteData.$location('/about');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $onboardingRoute => GoRouteData.$route(
+ path: '/onboarding/:currentRevision/:targetRevision',
+ name: 'OnboardingRoute',
+
+ factory: _$OnboardingRoute._fromState,
+);
+
+mixin _$OnboardingRoute on GoRouteData {
+ static OnboardingRoute _fromState(GoRouterState state) => OnboardingRoute(
+ currentRevision: int.parse(state.pathParameters['currentRevision']!)!,
+ targetRevision: int.parse(state.pathParameters['targetRevision']!)!,
+ );
+
+ OnboardingRoute get _self => this as OnboardingRoute;
+
+ @override
+ String get location => GoRouteData.$location(
+ '/onboarding/${Uri.encodeComponent(_self.currentRevision.toString())}/${Uri.encodeComponent(_self.targetRevision.toString())}',
+ );
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $settingsRoute => GoRouteData.$route(
+ path: '/settings',
+ name: 'SettingsRoute',
+
+ factory: _$SettingsRoute._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: 'general',
+ name: 'GeneralSettingsRoute',
+
+ factory: _$GeneralSettingsRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'bang',
+ name: 'BangSettingsRoute',
+
+ factory: _$BangSettingsRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'web_engine',
+ name: 'WebEngineSettingsRoute',
+
+ factory: _$WebEngineSettingsRoute._fromState,
routes: [
GoRouteData.$route(
- path: 'about',
- name: 'AboutRoute',
- factory: $AboutRouteExtension._fromState,
- ),
- GoRouteData.$route(
- path: 'bangs',
- name: 'BangRoute',
- factory: $BangCategoriesRouteExtension._fromState,
+ path: 'hardening',
+ name: 'WebEngineHardeningRoute',
+
+ factory: _$WebEngineHardeningRoute._fromState,
routes: [
GoRouteData.$route(
- path: 'search',
- name: 'BangSearchRoute',
- factory: $BangSearchRouteExtension._fromState,
- ),
- GoRouteData.$route(
- path: 'category/:category',
- name: 'BangCategoryRoute',
- factory: $BangCategoryRouteExtension._fromState,
- routes: [
- GoRouteData.$route(
- path: ':subCategory',
- name: 'BangSubCategoryRoute',
- factory: $BangSubCategoryRouteExtension._fromState,
- ),
- ],
+ path: 'group/:group',
+ name: 'WebEngineHardeningGroupRoute',
+
+ factory: _$WebEngineHardeningGroupRoute._fromState,
),
],
),
+ ],
+ ),
+ ],
+);
+
+mixin _$SettingsRoute on GoRouteData {
+ static SettingsRoute _fromState(GoRouterState state) => SettingsRoute();
+
+ @override
+ String get location => GoRouteData.$location('/settings');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$GeneralSettingsRoute on GoRouteData {
+ static GeneralSettingsRoute _fromState(GoRouterState state) =>
+ GeneralSettingsRoute();
+
+ @override
+ String get location => GoRouteData.$location('/settings/general');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$BangSettingsRoute on GoRouteData {
+ static BangSettingsRoute _fromState(GoRouterState state) =>
+ BangSettingsRoute();
+
+ @override
+ String get location => GoRouteData.$location('/settings/bang');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$WebEngineSettingsRoute on GoRouteData {
+ static WebEngineSettingsRoute _fromState(GoRouterState state) =>
+ WebEngineSettingsRoute();
+
+ @override
+ String get location => GoRouteData.$location('/settings/web_engine');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$WebEngineHardeningRoute on GoRouteData {
+ static WebEngineHardeningRoute _fromState(GoRouterState state) =>
+ WebEngineHardeningRoute();
+
+ @override
+ String get location =>
+ GoRouteData.$location('/settings/web_engine/hardening');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$WebEngineHardeningGroupRoute on GoRouteData {
+ static WebEngineHardeningGroupRoute _fromState(GoRouterState state) =>
+ WebEngineHardeningGroupRoute(group: state.pathParameters['group']!);
+
+ WebEngineHardeningGroupRoute get _self =>
+ this as WebEngineHardeningGroupRoute;
+
+ @override
+ String get location => GoRouteData.$location(
+ '/settings/web_engine/hardening/group/${Uri.encodeComponent(_self.group)}',
+ );
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+RouteBase get $browserRoute => GoRouteData.$route(
+ path: '/',
+ name: 'BrowserRoute',
+
+ factory: _$BrowserRoute._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: 'page/:url',
+ name: 'WebPageRoute',
+
+ factory: _$WebPageRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'search/:tabType/:searchText',
+ name: 'SearchRoute',
+
+ factory: _$SearchRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'tor_proxy',
+ name: 'TorProxyRoute',
+
+ factory: _$TorProxyRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'context_menu',
+ name: 'ContextMenuRoute',
+
+ factory: _$ContextMenuRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'containers',
+ name: 'ContainerListRoute',
+
+ factory: _$ContainerListRoute._fromState,
+ routes: [
GoRouteData.$route(
- path: 'topics',
- name: 'TopicsRoute',
- factory: $TopicListRouteExtension._fromState,
+ path: 'create',
+ name: 'ContainerCreateRoute',
+
+ factory: _$ContainerCreateRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'edit',
+ name: 'ContainerEditRoute',
+
+ factory: _$ContainerEditRoute._fromState,
),
],
- );
+ ),
+ GoRouteData.$route(
+ path: 'tab_tree/:rootTabId',
+ name: 'TabTreeRoute',
-extension $KagiRouteExtension on KagiRoute {
- static KagiRoute _fromState(GoRouterState state) => KagiRoute();
+ factory: _$TabTreeRoute._fromState,
+ ),
+ ],
+);
- String get location => GoRouteData.$location(
- '/',
- );
+mixin _$BrowserRoute on GoRouteData {
+ static BrowserRoute _fromState(GoRouterState state) => BrowserRoute();
+ @override
+ String get location => GoRouteData.$location('/');
+
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $AboutRouteExtension on AboutRoute {
- static AboutRoute _fromState(GoRouterState state) => AboutRoute();
+mixin _$WebPageRoute on GoRouteData {
+ static WebPageRoute _fromState(GoRouterState state) => WebPageRoute(
+ url: state.pathParameters['url']!,
+ $extra: state.extra as WebPageInfo?,
+ );
+ WebPageRoute get _self => this as WebPageRoute;
+
+ @override
+ String get location =>
+ GoRouteData.$location('/page/${Uri.encodeComponent(_self.url)}');
+
+ @override
+ void go(BuildContext context) => context.go(location, extra: _self.$extra);
+
+ @override
+ Future push(BuildContext context) =>
+ context.push(location, extra: _self.$extra);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location, extra: _self.$extra);
+
+ @override
+ void replace(BuildContext context) =>
+ context.replace(location, extra: _self.$extra);
+}
+
+mixin _$SearchRoute on GoRouteData {
+ static SearchRoute _fromState(GoRouterState state) => SearchRoute(
+ tabType: _$TabTypeEnumMap._$fromName(state.pathParameters['tabType']!)!,
+ searchText:
+ state.pathParameters['searchText'] ?? SearchRoute.emptySearchText,
+ );
+
+ SearchRoute get _self => this as SearchRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/about',
- );
+ '/search/${Uri.encodeComponent(_$TabTypeEnumMap[_self.tabType]!)}/${Uri.encodeComponent(_self.searchText)}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $BangCategoriesRouteExtension on BangCategoriesRoute {
+const _$TabTypeEnumMap = {
+ TabType.regular: 'regular',
+ TabType.private: 'private',
+ TabType.child: 'child',
+};
+
+mixin _$TorProxyRoute on GoRouteData {
+ static TorProxyRoute _fromState(GoRouterState state) => TorProxyRoute();
+
+ @override
+ String get location => GoRouteData.$location('/tor_proxy');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$ContextMenuRoute on GoRouteData {
+ static ContextMenuRoute _fromState(GoRouterState state) =>
+ ContextMenuRoute(state.extra as String);
+
+ ContextMenuRoute get _self => this as ContextMenuRoute;
+
+ @override
+ String get location => GoRouteData.$location('/context_menu');
+
+ @override
+ void go(BuildContext context) => context.go(location, extra: _self.$extra);
+
+ @override
+ Future push(BuildContext context) =>
+ context.push(location, extra: _self.$extra);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location, extra: _self.$extra);
+
+ @override
+ void replace(BuildContext context) =>
+ context.replace(location, extra: _self.$extra);
+}
+
+mixin _$ContainerListRoute on GoRouteData {
+ static ContainerListRoute _fromState(GoRouterState state) =>
+ ContainerListRoute();
+
+ @override
+ String get location => GoRouteData.$location('/containers');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$ContainerCreateRoute on GoRouteData {
+ static ContainerCreateRoute _fromState(GoRouterState state) =>
+ ContainerCreateRoute(state.extra as ContainerData);
+
+ ContainerCreateRoute get _self => this as ContainerCreateRoute;
+
+ @override
+ String get location => GoRouteData.$location('/containers/create');
+
+ @override
+ void go(BuildContext context) => context.go(location, extra: _self.$extra);
+
+ @override
+ Future push(BuildContext context) =>
+ context.push(location, extra: _self.$extra);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location, extra: _self.$extra);
+
+ @override
+ void replace(BuildContext context) =>
+ context.replace(location, extra: _self.$extra);
+}
+
+mixin _$ContainerEditRoute on GoRouteData {
+ static ContainerEditRoute _fromState(GoRouterState state) =>
+ ContainerEditRoute(state.extra as ContainerData);
+
+ ContainerEditRoute get _self => this as ContainerEditRoute;
+
+ @override
+ String get location => GoRouteData.$location('/containers/edit');
+
+ @override
+ void go(BuildContext context) => context.go(location, extra: _self.$extra);
+
+ @override
+ Future push(BuildContext context) =>
+ context.push(location, extra: _self.$extra);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location, extra: _self.$extra);
+
+ @override
+ void replace(BuildContext context) =>
+ context.replace(location, extra: _self.$extra);
+}
+
+mixin _$TabTreeRoute on GoRouteData {
+ static TabTreeRoute _fromState(GoRouterState state) =>
+ TabTreeRoute(state.pathParameters['rootTabId']!);
+
+ TabTreeRoute get _self => this as TabTreeRoute;
+
+ @override
+ String get location => GoRouteData.$location(
+ '/tab_tree/${Uri.encodeComponent(_self.rootTabId)}',
+ );
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+extension on Map {
+ T? _$fromName(String? value) =>
+ entries.where((element) => element.value == value).firstOrNull?.key;
+}
+
+RouteBase get $bangCategoriesRoute => GoRouteData.$route(
+ path: '/bangs',
+ name: 'BangRoute',
+
+ factory: _$BangCategoriesRoute._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: 'search/:searchText',
+ name: 'BangSearchRoute',
+
+ factory: _$BangSearchRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'category/:category',
+ name: 'BangCategoryRoute',
+
+ factory: _$BangCategoryRoute._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: ':subCategory',
+ name: 'BangSubCategoryRoute',
+
+ factory: _$BangSubCategoryRoute._fromState,
+ ),
+ ],
+ ),
+ ],
+);
+
+mixin _$BangCategoriesRoute on GoRouteData {
static BangCategoriesRoute _fromState(GoRouterState state) =>
BangCategoriesRoute();
- String get location => GoRouteData.$location(
- '/bangs',
- );
+ @override
+ String get location => GoRouteData.$location('/bangs');
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $BangSearchRouteExtension on BangSearchRoute {
- static BangSearchRoute _fromState(GoRouterState state) => BangSearchRoute();
+mixin _$BangSearchRoute on GoRouteData {
+ static BangSearchRoute _fromState(GoRouterState state) => BangSearchRoute(
+ searchText:
+ state.pathParameters['searchText'] ?? BangSearchRoute.emptySearchText,
+ );
+ BangSearchRoute get _self => this as BangSearchRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/bangs/search',
- );
+ '/bangs/search/${Uri.encodeComponent(_self.searchText)}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $BangCategoryRouteExtension on BangCategoryRoute {
- static BangCategoryRoute _fromState(GoRouterState state) => BangCategoryRoute(
- category: state.pathParameters['category']!,
- );
+mixin _$BangCategoryRoute on GoRouteData {
+ static BangCategoryRoute _fromState(GoRouterState state) =>
+ BangCategoryRoute(category: state.pathParameters['category']!);
+ BangCategoryRoute get _self => this as BangCategoryRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/bangs/category/${Uri.encodeComponent(category)}',
- );
+ '/bangs/category/${Uri.encodeComponent(_self.category)}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $BangSubCategoryRouteExtension on BangSubCategoryRoute {
+mixin _$BangSubCategoryRoute on GoRouteData {
static BangSubCategoryRoute _fromState(GoRouterState state) =>
BangSubCategoryRoute(
category: state.pathParameters['category']!,
subCategory: state.pathParameters['subCategory']!,
);
- String get location => GoRouteData.$location(
- '/bangs/category/${Uri.encodeComponent(category)}/${Uri.encodeComponent(subCategory)}',
- );
+ BangSubCategoryRoute get _self => this as BangSubCategoryRoute;
+ @override
+ String get location => GoRouteData.$location(
+ '/bangs/category/${Uri.encodeComponent(_self.category)}/${Uri.encodeComponent(_self.subCategory)}',
+ );
+
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $TopicListRouteExtension on TopicListRoute {
- static TopicListRoute _fromState(GoRouterState state) => TopicListRoute();
+RouteBase get $feedListRoute => GoRouteData.$route(
+ path: '/feeds',
+ name: 'FeedListRoute',
- String get location => GoRouteData.$location(
- '/topics',
- );
+ factory: _$FeedListRoute._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: 'add',
+ name: 'FeedAddRoute',
+ factory: _$FeedAddRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'articles/:feedId',
+ name: 'FeedArticleListRoute',
+
+ factory: _$FeedArticleListRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'article/:articleId',
+ name: 'FeedArticleRoute',
+
+ factory: _$FeedArticleRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'create/:feedId',
+ name: 'FeedCreateRoute',
+
+ factory: _$FeedCreateRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'available/:feedsJson',
+ name: 'SelectFeedDialogRoute',
+
+ factory: _$SelectFeedDialogRoute._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'edit/:feedId',
+ name: 'FeedEditRoute',
+
+ factory: _$FeedEditRoute._fromState,
+ ),
+ ],
+);
+
+mixin _$FeedListRoute on GoRouteData {
+ static FeedListRoute _fromState(GoRouterState state) => FeedListRoute();
+
+ @override
+ String get location => GoRouteData.$location('/feeds');
+
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-RouteBase get $settingsRoute => GoRouteData.$route(
- path: '/settings',
- name: 'SettingsRoute',
- factory: $SettingsRouteExtension._fromState,
- );
+mixin _$FeedAddRoute on GoRouteData {
+ static FeedAddRoute _fromState(GoRouterState state) =>
+ FeedAddRoute($extra: state.extra as Uri?);
-extension $SettingsRouteExtension on SettingsRoute {
- static SettingsRoute _fromState(GoRouterState state) => SettingsRoute();
+ FeedAddRoute get _self => this as FeedAddRoute;
+ @override
+ String get location => GoRouteData.$location('/feeds/add');
+
+ @override
+ void go(BuildContext context) => context.go(location, extra: _self.$extra);
+
+ @override
+ Future push(BuildContext context) =>
+ context.push(location, extra: _self.$extra);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location, extra: _self.$extra);
+
+ @override
+ void replace(BuildContext context) =>
+ context.replace(location, extra: _self.$extra);
+}
+
+mixin _$FeedArticleListRoute on GoRouteData {
+ static FeedArticleListRoute _fromState(GoRouterState state) =>
+ FeedArticleListRoute(feedId: Uri.parse(state.pathParameters['feedId']!)!);
+
+ FeedArticleListRoute get _self => this as FeedArticleListRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/settings',
- );
+ '/feeds/articles/${Uri.encodeComponent(_self.feedId.toString())}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-RouteBase get $chatArchiveListRoute => GoRouteData.$route(
- path: '/chat_archive',
- name: 'ChatArchiveListRoute',
- factory: $ChatArchiveListRouteExtension._fromState,
- routes: [
- GoRouteData.$route(
- path: 'search',
- name: 'ChatArchiveSearchRoute',
- factory: $ChatArchiveSearchRouteExtension._fromState,
- ),
- GoRouteData.$route(
- path: 'detail/:fileName',
- name: 'ChatArchiveDetailRoute',
- factory: $ChatArchiveDetailRouteExtension._fromState,
- ),
- ],
- );
+mixin _$FeedArticleRoute on GoRouteData {
+ static FeedArticleRoute _fromState(GoRouterState state) =>
+ FeedArticleRoute(articleId: state.pathParameters['articleId']!);
-extension $ChatArchiveListRouteExtension on ChatArchiveListRoute {
- static ChatArchiveListRoute _fromState(GoRouterState state) =>
- ChatArchiveListRoute();
+ FeedArticleRoute get _self => this as FeedArticleRoute;
+ @override
String get location => GoRouteData.$location(
- '/chat_archive',
- );
+ '/feeds/article/${Uri.encodeComponent(_self.articleId)}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $ChatArchiveSearchRouteExtension on ChatArchiveSearchRoute {
- static ChatArchiveSearchRoute _fromState(GoRouterState state) =>
- ChatArchiveSearchRoute();
+mixin _$FeedCreateRoute on GoRouteData {
+ static FeedCreateRoute _fromState(GoRouterState state) =>
+ FeedCreateRoute(feedId: Uri.parse(state.pathParameters['feedId']!)!);
+ FeedCreateRoute get _self => this as FeedCreateRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/chat_archive/search',
- );
+ '/feeds/create/${Uri.encodeComponent(_self.feedId.toString())}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
void replace(BuildContext context) => context.replace(location);
}
-extension $ChatArchiveDetailRouteExtension on ChatArchiveDetailRoute {
- static ChatArchiveDetailRoute _fromState(GoRouterState state) =>
- ChatArchiveDetailRoute(
- fileName: state.pathParameters['fileName']!,
- );
+mixin _$SelectFeedDialogRoute on GoRouteData {
+ static SelectFeedDialogRoute _fromState(GoRouterState state) =>
+ SelectFeedDialogRoute(feedsJson: state.pathParameters['feedsJson']!);
+ SelectFeedDialogRoute get _self => this as SelectFeedDialogRoute;
+
+ @override
String get location => GoRouteData.$location(
- '/chat_archive/detail/${Uri.encodeComponent(fileName)}',
- );
+ '/feeds/available/${Uri.encodeComponent(_self.feedsJson)}',
+ );
+ @override
void go(BuildContext context) => context.go(location);
+ @override
Future push(BuildContext context) => context.push(location);
+ @override
void pushReplacement(BuildContext context) =>
context.pushReplacement(location);
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
+mixin _$FeedEditRoute on GoRouteData {
+ static FeedEditRoute _fromState(GoRouterState state) =>
+ FeedEditRoute(feedId: Uri.parse(state.pathParameters['feedId']!)!);
+
+ FeedEditRoute get _self => this as FeedEditRoute;
+
+ @override
+ String get location => GoRouteData.$location(
+ '/feeds/edit/${Uri.encodeComponent(_self.feedId.toString())}',
+ );
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
void replace(BuildContext context) => context.replace(location);
}
diff --git a/app/lib/core/routing/routes.settings.dart b/app/lib/core/routing/routes.settings.dart
new file mode 100644
index 00000000..db98116f
--- /dev/null
+++ b/app/lib/core/routing/routes.settings.dart
@@ -0,0 +1,76 @@
+part of 'routes.dart';
+
+@TypedGoRoute(
+ name: 'SettingsRoute',
+ path: '/settings',
+ routes: [
+ TypedGoRoute(
+ name: 'GeneralSettingsRoute',
+ path: 'general',
+ ),
+ TypedGoRoute(name: 'BangSettingsRoute', path: 'bang'),
+ TypedGoRoute(
+ name: 'WebEngineSettingsRoute',
+ path: 'web_engine',
+ routes: [
+ TypedGoRoute(
+ name: 'WebEngineHardeningRoute',
+ path: 'hardening',
+ routes: [
+ TypedGoRoute(
+ name: 'WebEngineHardeningGroupRoute',
+ path: 'group/:group',
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+)
+class SettingsRoute extends GoRouteData with _$SettingsRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const SettingsScreen();
+ }
+}
+
+class GeneralSettingsRoute extends GoRouteData with _$GeneralSettingsRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const GeneralSettingsScreen();
+ }
+}
+
+class BangSettingsRoute extends GoRouteData with _$BangSettingsRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const BangSettingsScreen();
+ }
+}
+
+class WebEngineSettingsRoute extends GoRouteData with _$WebEngineSettingsRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const WebEngineSettingsScreen();
+ }
+}
+
+class WebEngineHardeningRoute extends GoRouteData
+ with _$WebEngineHardeningRoute {
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const WebEngineHardeningScreen();
+ }
+}
+
+class WebEngineHardeningGroupRoute extends GoRouteData
+ with _$WebEngineHardeningGroupRoute {
+ final String group;
+
+ const WebEngineHardeningGroupRoute({required this.group});
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return WebEngineHardeningGroupScreen(groupName: group);
+ }
+}
diff --git a/app/lib/core/routing/dialog_page.dart b/app/lib/core/routing/widgets/dialog_page.dart
similarity index 73%
rename from app/lib/core/routing/dialog_page.dart
rename to app/lib/core/routing/widgets/dialog_page.dart
index 4a598c87..09ef3489 100644
--- a/app/lib/core/routing/dialog_page.dart
+++ b/app/lib/core/routing/widgets/dialog_page.dart
@@ -27,14 +27,14 @@ class DialogPage extends Page {
@override
Route createRoute(BuildContext context) => DialogRoute(
- context: context,
- settings: this,
- builder: builder,
- anchorPoint: anchorPoint,
- barrierColor: barrierColor,
- barrierDismissible: barrierDismissible,
- barrierLabel: barrierLabel,
- useSafeArea: useSafeArea,
- themes: themes,
- );
+ context: context,
+ settings: this,
+ builder: builder,
+ anchorPoint: anchorPoint,
+ barrierColor: barrierColor,
+ barrierDismissible: barrierDismissible,
+ barrierLabel: barrierLabel,
+ useSafeArea: useSafeArea,
+ themes: themes,
+ );
}
diff --git a/app/lib/data/database/converters/color.dart b/app/lib/data/database/converters/color.dart
new file mode 100644
index 00000000..ba12581d
--- /dev/null
+++ b/app/lib/data/database/converters/color.dart
@@ -0,0 +1,32 @@
+import 'dart:ui';
+
+import 'package:drift/drift.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+class ColorJsonConverter implements JsonConverter {
+ const ColorJsonConverter();
+
+ @override
+ Color fromJson(int from) {
+ return Color(from);
+ }
+
+ @override
+ int toJson(Color value) {
+ return value.toARGB32();
+ }
+}
+
+class ColorConverter extends TypeConverter {
+ const ColorConverter();
+
+ @override
+ Color fromSql(int fromDb) {
+ return Color(fromDb);
+ }
+
+ @override
+ int toSql(Color value) {
+ return value.toARGB32();
+ }
+}
diff --git a/app/lib/data/database/converters/icon_data.dart b/app/lib/data/database/converters/icon_data.dart
new file mode 100644
index 00000000..ee42abd4
--- /dev/null
+++ b/app/lib/data/database/converters/icon_data.dart
@@ -0,0 +1,48 @@
+import 'dart:convert';
+
+import 'package:drift/drift.dart';
+import 'package:flutter/widgets.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+class IconDataJsonConverter
+ implements JsonConverter> {
+ const IconDataJsonConverter();
+
+ @override
+ IconData fromJson(Map json) {
+ return IconData(
+ json['codePoint'] as int,
+ fontFamily: json['fontFamily'] as String,
+ fontPackage: json['fontPackage'] as String,
+ );
+ }
+
+ @override
+ Map toJson(IconData iconData) {
+ return {
+ 'codePoint': iconData.codePoint,
+ 'fontFamily': iconData.fontFamily,
+ 'fontPackage': iconData.fontPackage,
+ };
+ }
+}
+
+class IconDataTypeConverter implements TypeConverter {
+ const IconDataTypeConverter();
+
+ @override
+ IconData fromSql(String fromDb) {
+ final json = jsonDecode(fromDb) as Map;
+ return const IconDataJsonConverter().fromJson(json);
+ }
+
+ @override
+ String toSql(IconData value) {
+ assert(
+ value.fontFamily != null,
+ 'Font family must be provided to identify icon',
+ );
+
+ return jsonEncode(const IconDataJsonConverter().toJson(value));
+ }
+}
diff --git a/app/lib/data/database/converters/string_list.dart b/app/lib/data/database/converters/string_list.dart
new file mode 100644
index 00000000..15e42a17
--- /dev/null
+++ b/app/lib/data/database/converters/string_list.dart
@@ -0,0 +1,17 @@
+import 'dart:convert';
+
+import 'package:drift/drift.dart';
+
+class StringListConverter extends TypeConverter, String> {
+ const StringListConverter();
+
+ @override
+ List fromSql(String fromDb) {
+ return jsonDecode(fromDb) as List;
+ }
+
+ @override
+ String toSql(List value) {
+ return jsonEncode(value);
+ }
+}
diff --git a/app/lib/data/database/converters/uri.dart b/app/lib/data/database/converters/uri.dart
new file mode 100644
index 00000000..e49d2d85
--- /dev/null
+++ b/app/lib/data/database/converters/uri.dart
@@ -0,0 +1,30 @@
+import 'package:drift/drift.dart';
+import 'package:weblibre/utils/uri_parser.dart' as uri_parser;
+
+class UriConverter extends TypeConverter {
+ const UriConverter();
+
+ @override
+ Uri fromSql(String fromDb) {
+ return uri_parser.tryParseUrl(fromDb, eagerParsing: true)!;
+ }
+
+ @override
+ String toSql(Uri value) {
+ return value.toString();
+ }
+}
+
+class UriConverterNullable extends TypeConverter {
+ const UriConverterNullable();
+
+ @override
+ Uri? fromSql(String? fromDb) {
+ return uri_parser.tryParseUrl(fromDb, eagerParsing: true);
+ }
+
+ @override
+ String? toSql(Uri? value) {
+ return value?.toString();
+ }
+}
diff --git a/app/lib/extensions/database_table_size.dart b/app/lib/data/database/extensions/database_table_size.dart
similarity index 88%
rename from app/lib/extensions/database_table_size.dart
rename to app/lib/data/database/extensions/database_table_size.dart
index f9efb902..f5c949d0 100644
--- a/app/lib/extensions/database_table_size.dart
+++ b/app/lib/data/database/extensions/database_table_size.dart
@@ -1,6 +1,6 @@
import 'package:drift/drift.dart';
-extension TableSIze on DatabaseConnectionUser {
+extension TableSize on DatabaseConnectionUser {
SingleSelectable tableSize(TableInfo table) {
return customSelect(
'SELECT SUM(pgsize) /(1024.0 * 1024.0)AS pgsize_mb FROM dbstat WHERE name = ?1',
diff --git a/app/lib/data/database/functions/lexo_rank_functions.dart b/app/lib/data/database/functions/lexo_rank_functions.dart
new file mode 100644
index 00000000..aecd7522
--- /dev/null
+++ b/app/lib/data/database/functions/lexo_rank_functions.dart
@@ -0,0 +1,59 @@
+import 'package:lexo_rank/lexo_rank.dart';
+import 'package:lexo_rank/lexo_rank/lexo_rank_bucket.dart';
+import 'package:nullability/nullability.dart';
+import 'package:sqlite3/common.dart';
+
+String _nextRankOrMiddle(List args) {
+ final parsedBucket = LexoRankBucket.resolve(args[0]! as int);
+
+ if (args[1] != null) {
+ final parsedRank = LexoRank.parse(args[1]! as String);
+
+ return parsedRank.genNext().value;
+ } else {
+ return LexoRank.middle(bucket: parsedBucket).value;
+ }
+}
+
+String _previousRankOrMiddle(List args) {
+ final parsedBucket = LexoRankBucket.resolve(args[0]! as int);
+
+ if (args[1] != null) {
+ final parsedRank = LexoRank.parse(args[1]! as String);
+
+ return parsedRank.genPrev().value;
+ } else {
+ return LexoRank.middle(bucket: parsedBucket).value;
+ }
+}
+
+String _reorderAfter(List args) {
+ final first = args[0].mapNotNull((arg) => LexoRank.parse(arg as String));
+ final last = args[1].mapNotNull((arg) => LexoRank.parse(arg as String));
+
+ if (first == null) {
+ throw Exception('Tab not found');
+ } else if (last == null) {
+ return first.genNext().value;
+ } else {
+ return first.genBetween(last).value;
+ }
+}
+
+void registerLexorankFunctions(CommonDatabase database) {
+ database.createFunction(
+ functionName: 'lexo_rank_next',
+ argumentCount: const AllowedArgumentCount(2),
+ function: _nextRankOrMiddle,
+ );
+ database.createFunction(
+ functionName: 'lexo_rank_previous',
+ argumentCount: const AllowedArgumentCount(2),
+ function: _previousRankOrMiddle,
+ );
+ database.createFunction(
+ functionName: 'lexo_rank_reorder_after',
+ argumentCount: const AllowedArgumentCount(2),
+ function: _reorderAfter,
+ );
+}
diff --git a/app/lib/data/models/drag_data.dart b/app/lib/data/models/drag_data.dart
new file mode 100644
index 00000000..6a07cedc
--- /dev/null
+++ b/app/lib/data/models/drag_data.dart
@@ -0,0 +1,32 @@
+import 'package:fast_equatable/fast_equatable.dart';
+
+sealed class DropTargetData with FastEquatable {}
+
+final class ContainerDropData extends DropTargetData {
+ final String tabId;
+
+ ContainerDropData(this.tabId);
+
+ @override
+ List get hashParameters => [tabId];
+}
+
+final class DeleteDropData extends DropTargetData {
+ final String tabId;
+
+ DeleteDropData(this.tabId);
+
+ @override
+ List get hashParameters => [tabId];
+}
+
+sealed class DragTargetData with FastEquatable {}
+
+final class TabDragData extends DragTargetData {
+ final String tabId;
+
+ TabDragData(this.tabId);
+
+ @override
+ List get hashParameters => [tabId];
+}
diff --git a/app/lib/data/models/received_intent_parameter.dart b/app/lib/data/models/received_intent_parameter.dart
new file mode 100644
index 00000000..db5c0b16
--- /dev/null
+++ b/app/lib/data/models/received_intent_parameter.dart
@@ -0,0 +1,11 @@
+import 'package:fast_equatable/fast_equatable.dart';
+
+class ReceivedIntentParameter with FastEquatable {
+ final String? content;
+ final String? tool;
+
+ ReceivedIntentParameter(this.content, this.tool);
+
+ @override
+ List get hashParameters => [content, tool];
+}
diff --git a/app/lib/data/models/web_page_info.dart b/app/lib/data/models/web_page_info.dart
new file mode 100644
index 00000000..8856e5af
--- /dev/null
+++ b/app/lib/data/models/web_page_info.dart
@@ -0,0 +1,22 @@
+import 'package:copy_with_extension/copy_with_extension.dart';
+import 'package:fast_equatable/fast_equatable.dart';
+import 'package:nullability/nullability.dart';
+import 'package:weblibre/features/geckoview/domain/entities/browser_icon.dart';
+
+part 'web_page_info.g.dart';
+
+@CopyWith()
+class WebPageInfo with FastEquatable {
+ final Uri url;
+ final String? title;
+ final BrowserIcon? favicon;
+ final Set? feeds;
+
+ bool get isPageInfoComplete =>
+ title.isNotEmpty && favicon != null && feeds != null;
+
+ WebPageInfo({required this.url, this.title, this.favicon, this.feeds});
+
+ @override
+ List get hashParameters => [url, title, favicon, feeds];
+}
diff --git a/app/lib/data/models/web_page_info.g.dart b/app/lib/data/models/web_page_info.g.dart
new file mode 100644
index 00000000..296ae1fd
--- /dev/null
+++ b/app/lib/data/models/web_page_info.g.dart
@@ -0,0 +1,88 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'web_page_info.dart';
+
+// **************************************************************************
+// CopyWithGenerator
+// **************************************************************************
+
+abstract class _$WebPageInfoCWProxy {
+ WebPageInfo url(Uri url);
+
+ WebPageInfo title(String? title);
+
+ WebPageInfo favicon(BrowserIcon? favicon);
+
+ WebPageInfo feeds(Set? feeds);
+
+ /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `WebPageInfo(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
+ ///
+ /// Usage
+ /// ```dart
+ /// WebPageInfo(...).copyWith(id: 12, name: "My name")
+ /// ````
+ WebPageInfo call({
+ Uri url,
+ String? title,
+ BrowserIcon? favicon,
+ Set? feeds,
+ });
+}
+
+/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfWebPageInfo.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfWebPageInfo.copyWith.fieldName(...)`
+class _$WebPageInfoCWProxyImpl implements _$WebPageInfoCWProxy {
+ const _$WebPageInfoCWProxyImpl(this._value);
+
+ final WebPageInfo _value;
+
+ @override
+ WebPageInfo url(Uri url) => this(url: url);
+
+ @override
+ WebPageInfo title(String? title) => this(title: title);
+
+ @override
+ WebPageInfo favicon(BrowserIcon? favicon) => this(favicon: favicon);
+
+ @override
+ WebPageInfo feeds(Set? feeds) => this(feeds: feeds);
+
+ @override
+ /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `WebPageInfo(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
+ ///
+ /// Usage
+ /// ```dart
+ /// WebPageInfo(...).copyWith(id: 12, name: "My name")
+ /// ````
+ WebPageInfo call({
+ Object? url = const $CopyWithPlaceholder(),
+ Object? title = const $CopyWithPlaceholder(),
+ Object? favicon = const $CopyWithPlaceholder(),
+ Object? feeds = const $CopyWithPlaceholder(),
+ }) {
+ return WebPageInfo(
+ url: url == const $CopyWithPlaceholder()
+ ? _value.url
+ // ignore: cast_nullable_to_non_nullable
+ : url as Uri,
+ title: title == const $CopyWithPlaceholder()
+ ? _value.title
+ // ignore: cast_nullable_to_non_nullable
+ : title as String?,
+ favicon: favicon == const $CopyWithPlaceholder()
+ ? _value.favicon
+ // ignore: cast_nullable_to_non_nullable
+ : favicon as BrowserIcon?,
+ feeds: feeds == const $CopyWithPlaceholder()
+ ? _value.feeds
+ // ignore: cast_nullable_to_non_nullable
+ : feeds as Set?,
+ );
+ }
+}
+
+extension $WebPageInfoCopyWith on WebPageInfo {
+ /// Returns a callable class that can be used as follows: `instanceOfWebPageInfo.copyWith(...)` or like so:`instanceOfWebPageInfo.copyWith.fieldName(...)`.
+ // ignore: library_private_types_in_public_api
+ _$WebPageInfoCWProxy get copyWith => _$WebPageInfoCWProxyImpl(this);
+}
diff --git a/app/lib/domain/entities/equatable_image.dart b/app/lib/domain/entities/equatable_image.dart
new file mode 100644
index 00000000..c76a6aa4
--- /dev/null
+++ b/app/lib/domain/entities/equatable_image.dart
@@ -0,0 +1,16 @@
+import 'dart:ui';
+
+class EquatableImage {
+ final Image value;
+ final int _imageHash;
+
+ EquatableImage(this.value, {required int hash}) : _imageHash = hash;
+
+ @override
+ int get hashCode => _imageHash.hashCode;
+
+ @override
+ bool operator ==(Object other) {
+ return other is EquatableImage && other._imageHash == _imageHash;
+ }
+}
diff --git a/app/lib/domain/entities/received_parameter.dart b/app/lib/domain/entities/received_parameter.dart
deleted file mode 100644
index 0f4b1697..00000000
--- a/app/lib/domain/entities/received_parameter.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-class ReceivedParameter {
- final String? content;
- final String? tool;
-
- ReceivedParameter(this.content, this.tool);
-}
diff --git a/app/lib/domain/entities/web_page_info.dart b/app/lib/domain/entities/web_page_info.dart
deleted file mode 100644
index 89464a2d..00000000
--- a/app/lib/domain/entities/web_page_info.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:flutter_inappwebview/flutter_inappwebview.dart';
-
-class WebPageInfo {
- final Uri url;
- final String? title;
- final Favicon? favicon;
-
- WebPageInfo({
- required this.url,
- required this.title,
- required this.favicon,
- });
-
- factory WebPageInfo.fromJson(Map json) {
- return WebPageInfo(
- url: Uri.parse(json['url'] as String),
- title: json['title'] as String?,
- favicon: switch (json['favicon']) {
- final Map favicon => Favicon.fromMap(favicon),
- _ => null
- },
- );
- }
-
- Map toJson() {
- return {
- 'url': url.toString(),
- 'title': title,
- 'favicon': favicon?.toJson(),
- };
- }
-}
diff --git a/app/lib/domain/services/app_initialization.dart b/app/lib/domain/services/app_initialization.dart
index 30e22a2c..44aff073 100644
--- a/app/lib/domain/services/app_initialization.dart
+++ b/app/lib/domain/services/app_initialization.dart
@@ -1,17 +1,11 @@
import 'dart:async';
import 'package:exceptions/exceptions.dart';
-import 'package:lensai/features/about/data/repositories/package_info_repository.dart';
-import 'package:lensai/features/bangs/data/models/bang.dart';
-import 'package:lensai/features/bangs/domain/repositories/sync.dart';
-import 'package:lensai/features/content_block/data/models/host.dart';
-import 'package:lensai/features/content_block/domain/repositories/sync.dart';
-import 'package:lensai/features/search_browser/domain/services/session.dart';
-import 'package:lensai/features/settings/data/models/settings.dart';
-import 'package:lensai/features/settings/data/repositories/settings_repository.dart';
-import 'package:lensai/features/topics/data/providers.dart';
-import 'package:lensai/features/web_view/domain/providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:weblibre/core/providers/format.dart';
+import 'package:weblibre/features/about/data/repositories/package_info_repository.dart';
+import 'package:weblibre/features/bangs/data/models/bang_group.dart';
+import 'package:weblibre/features/bangs/domain/repositories/sync.dart';
part 'app_initialization.g.dart';
@@ -25,78 +19,32 @@ class AppInitializationService extends _$AppInitializationService {
Future _initPackageInfo() {
//Ensure Package info is loaded
- state = Result.success(
- (
- initialized: false,
- stage: 'Loading Package Info...',
- errors: List.empty(),
- ),
- );
+ state = Result.success((
+ initialized: false,
+ stage: 'Loading Package Info...',
+ errors: List.empty(),
+ ));
return ref.read(packageInfoProvider.future);
}
Future>> _initBangs() {
- state = Result.success(
- (
- initialized: false,
- stage: 'Synchronizing Bangs...',
- errors: List.empty(),
- ),
- );
+ state = Result.success((
+ initialized: false,
+ stage: 'Synchronizing Bangs...',
+ errors: List.empty(),
+ ));
return ref
.read(bangSyncRepositoryProvider.notifier)
.syncBangGroups(syncInterval: const Duration(days: 7));
}
- FutureOr>> _initHosts(Settings settings) {
- if (settings.enableContentBlocking) {
- state = Result.success(
- (
- initialized: false,
- stage: 'Synchronizing Ad & Content Blocking Lists...',
- errors: List.empty(),
- ),
- );
-
- return ref.read(hostSyncRepositoryProvider.notifier).syncHostSources(
- sources: settings.enableHostList,
- syncInterval: const Duration(days: 7),
- );
- }
-
- return {};
- }
-
- Future _initIncognito(Settings settings) async {
- state = Result.success(
- (
- initialized: false,
- stage: 'Enforcing Privacy...',
- errors: List.empty(),
- ),
- );
-
- if (settings.incognitoMode) {
- await ref.read(sessionServiceProvider.notifier).clearAllData();
- //Delete all unsasigned tabs
- await ref.read(tabDatabaseProvider).tabDao.deleteTopicTabs(null);
- }
-
- if (settings.kagiSession case final String session) {
- if (session.isNotEmpty) {
- await ref.read(sessionServiceProvider.notifier).setKagiSession(session);
- }
- }
- }
-
Future initialize() async {
state = await Result.fromAsync(() async {
- final settings = await ref.read(settingsRepositoryProvider.future);
final errors = [];
- unawaited(ref.read(readerabilityScriptProvider.future));
+ await ref.read(formatProvider.future);
await _initPackageInfo();
@@ -105,22 +53,17 @@ class AppInitializationService extends _$AppInitializationService {
result.onFailure(errors.add);
}
- final hostSyncResults = await _initHosts(settings);
- for (final MapEntry(value: result) in hostSyncResults.entries) {
- result.onFailure(errors.add);
- }
-
- await _initIncognito(settings);
-
return (initialized: true, stage: null, errors: errors);
});
}
@override
Result<({bool initialized, String? stage, List errors})>
- build() {
- return Result.success(
- (initialized: false, stage: null, errors: List.empty()),
- );
+ build() {
+ return Result.success((
+ initialized: false,
+ stage: null,
+ errors: List.empty(),
+ ));
}
}
diff --git a/app/lib/domain/services/app_initialization.g.dart b/app/lib/domain/services/app_initialization.g.dart
index 809183f6..558293e8 100644
--- a/app/lib/domain/services/app_initialization.g.dart
+++ b/app/lib/domain/services/app_initialization.g.dart
@@ -7,28 +7,27 @@ part of 'app_initialization.dart';
// **************************************************************************
String _$appInitializationServiceHash() =>
- r'dadcf205d32efa61eb2a0ff1c9b3d49658b76a56';
+ r'5e537f916825d6c5f660cf62ff133c2ef00ab091';
/// See also [AppInitializationService].
@ProviderFor(AppInitializationService)
-final appInitializationServiceProvider = NotifierProvider<
- AppInitializationService,
- Result<
- ({
- bool initialized,
- String? stage,
- List errors
- })>>.internal(
- AppInitializationService.new,
- name: r'appInitializationServiceProvider',
- debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
- ? null
- : _$appInitializationServiceHash,
- dependencies: null,
- allTransitiveDependencies: null,
-);
+final appInitializationServiceProvider =
+ NotifierProvider<
+ AppInitializationService,
+ Result<({bool initialized, String? stage, List errors})>
+ >.internal(
+ AppInitializationService.new,
+ name: r'appInitializationServiceProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$appInitializationServiceHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+ );
-typedef _$AppInitializationService = Notifier<
- Result<({bool initialized, String? stage, List errors})>>;
+typedef _$AppInitializationService =
+ Notifier<
+ Result<({bool initialized, String? stage, List errors})>
+ >;
// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/domain/services/generic_website.dart b/app/lib/domain/services/generic_website.dart
index 24f01f35..799594bf 100644
--- a/app/lib/domain/services/generic_website.dart
+++ b/app/lib/domain/services/generic_website.dart
@@ -1,146 +1,383 @@
+import 'dart:async';
+import 'dart:ui';
+
import 'package:exceptions/exceptions.dart';
import 'package:flutter/foundation.dart';
-import 'package:flutter_inappwebview/flutter_inappwebview.dart';
+import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:html/dom.dart';
import 'package:html/parser.dart' as html_parser;
-import 'package:http/http.dart' as http;
-import 'package:lensai/core/http_error_handler.dart';
-import 'package:lensai/domain/entities/web_page_info.dart';
-import 'package:lensai/extensions/web_uri_favicon.dart';
-import 'package:lensai/features/web_view/utils/favicon_helper.dart';
+import 'package:http/io_client.dart';
+import 'package:nullability/nullability.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:socks5_proxy/socks_client.dart';
import 'package:universal_io/io.dart';
+import 'package:weblibre/core/http_error_handler.dart';
+import 'package:weblibre/data/models/web_page_info.dart';
+import 'package:weblibre/features/geckoview/domain/entities/browser_icon.dart';
+import 'package:weblibre/features/user/domain/repositories/cache.dart';
+import 'package:weblibre/features/web_feed/utils/feed_finder.dart';
+import 'package:weblibre/presentation/controllers/website_title.dart';
+import 'package:weblibre/utils/lru_cache.dart';
part 'generic_website.g.dart';
-@Riverpod(keepAlive: true)
-class GenericWebsiteService extends _$GenericWebsiteService {
- late http.Client _client;
- final Map _httpsCache;
+const _typeMap = {
+ "manifest": IconType.manifestIcon,
+ "icon": IconType.favicon,
+ "shortcut icon": IconType.favicon,
+ "fluid-icon": IconType.fluidIcon,
+ "apple-touch-icon": IconType.appleTouchIcon,
+ "image_src": IconType.imageSrc,
+ "apple-touch-icon image_src": IconType.appleTouchIcon,
+ "apple-touch-icon-precomposed": IconType.appleTouchIcon,
+ "og:image": IconType.openGraph,
+ "og:image:url": IconType.openGraph,
+ "og:image:secure_url": IconType.openGraph,
+ "twitter:image": IconType.twitter,
+ "msapplication-TileImage": IconType.microsoftTile,
+};
- GenericWebsiteService() : _httpsCache = {};
+Iterable sizesToList(String? sizes) sync* {
+ if (sizes != null) {
+ final splitted = sizes
+ .split(' ')
+ .where((size) => size.contains('x'))
+ .toList();
- @override
- void build() {
- _client = http.Client();
- }
+ for (final size in splitted) {
+ final dimensions = size.split('x');
+ if (dimensions.length == 2) {
+ final height = int.tryParse(dimensions[0]);
+ final width = int.tryParse(dimensions[1]);
- static Iterable _extractFavicons(Uri url, Document document) sync* {
- final links = document.querySelectorAll(
- 'link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]',
- );
-
- for (final link in links) {
- final href = link.attributes['href'];
- if (href != null) {
- // Attempt to parse height and width if available
- int? height;
- int? width;
- if (link.attributes['sizes'] case final String sizes) {
- final dimensions = sizes.split('x');
- if (dimensions.length == 2) {
- height = int.tryParse(dimensions[0]);
- width = int.tryParse(dimensions[1]);
- }
+ if (width != null && height != null) {
+ yield ResourceSize(height: height, width: width);
}
-
- yield Favicon(
- url: WebUri.uri(url.resolve(href)),
- rel: link.attributes['rel'],
- width: width,
- height: height,
- );
}
}
}
+}
- Future> getInfo(Uri url) async {
- return Result.fromAsync(
- () async {
- final response =
- await _client.get(url).timeout(const Duration(seconds: 10));
- return await compute(
- (args) {
- final document = html_parser.parse(args[0]);
- final url = Uri.parse(args[1]);
+@Riverpod(keepAlive: true)
+class GenericWebsiteService extends _$GenericWebsiteService {
+ final GeckoIconService _iconsService;
- final title = document.querySelector('title')?.text;
- final favicon = choseFavicon(_extractFavicons(url, document)) ??
- //In case the icon can not get extracted, we use the resolver
- //of duckduckgo
- Favicon(
- url: WebUri.uri(url.genericFavicon()),
- );
+ //Global icon cache
+ late CacheRepository _cacheRepository;
+ //Local decoded icon cache
+ final LRUCache _browserIconCache;
- return WebPageInfo(url: url, title: title, favicon: favicon)
- .toJson();
- },
- [response.body, url.toString()],
- ).then(WebPageInfo.fromJson);
- },
- exceptionHandler: handleHttpError,
+ GenericWebsiteService()
+ : _iconsService = GeckoIconService(),
+ _browserIconCache = LRUCache(50);
+
+ @override
+ void build() {
+ _cacheRepository = ref.watch(cacheRepositoryProvider.notifier);
+ }
+
+ static Map _serializeResource(Resource resource) {
+ return {
+ 'url': resource.url,
+ 'type': resource.type,
+ 'sizes': resource.sizes.nonNulls.map((s) => [s.height, s.width]).toList(),
+ 'mimeType': resource.mimeType,
+ 'maskable': resource.maskable,
+ };
+ }
+
+ static Resource _deserializeResource(Map resource) {
+ return Resource(
+ url: resource['url'] as String,
+ type: resource['type'] as IconType,
+ mimeType: resource['mimeType'] as String?,
+ sizes: (resource['sizes'] as List>)
+ .map((s) => ResourceSize(height: s[0], width: s[1]))
+ .toList(),
+ maskable: resource['maskable'] as bool,
);
}
- Future