Twitter Web Exporter

Export tweets, bookmarks, lists and much more from Twitter(X) web app.

As of 2024-04-11. See the latest version.

// ==UserScript==
// @name         Twitter Web Exporter
// @namespace    https://github.com/prinsss
// @version      1.0.10
// @author       prin <[email protected]>
// @description  Export tweets, bookmarks, lists and much more from Twitter(X) web app.
// @license      MIT
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABmklEQVR4Ae3XA4wcARSA4dq2bUQ1g9pRbVtBzai2otpug9pxUttn2753/3m9Ozq/5NsdvvfGM6VKoshE8/ORFbAMbxCGWHzDHjS2sXxPlM0eKYclGoq3w1eIHVGYikaYg6e4ZppgAgQrVBSvDw+IEylIhSAATUyTHIYgFdsUNnAGosAfDMccLMtOchli4g7quFC8FhIhCsRD8Bk1sxMdgVjwxRyUdtDABIgKH9DQNNEkiB1fMB9VbDSwEKLQJ1S1TFQRXhAHYnADy9ETdTEeotAze7tzNJIhCiRBFLpnq/hmzMR65UkVO2WrgaOQPLLW3u6XPDLAVgOl8R5isEhUtHcSdkEoxEBXnN3ZuuMbxCDDnTVQF52xBcEQHX1BaWcNtDLwMpzg6tNtN0RnD5U8XsviGkQnYWih9CWjNBbDHaJBMsZqec8rjV54B1EoFXO0Fh+DrxCFEjBTTdFy6IvNGu4Hf9FXSdGheAUvjZdgLPajqtp3+jl4jVSIAgHYjRZ6fWC0wSpcwScEQZCMUPzEfezEYJQrVRKFOdIAZGq1QBG8EiYAAAAASUVORK5CYII=
// @homepage     https://github.com/prinsss/twitter-web-exporter
// @homepageURL  https://github.com/prinsss/twitter-web-exporter
// @supportURL   https://github.com/prinsss/twitter-web-exporter/issues
// @match        *://twitter.com/*
// @match        *://x.com/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/preact.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/hooks/dist/hooks.umd.js
// @require      https://cdn.jsdelivr.net/npm/@preact/[email protected]/dist/signals-core.min.js
// @require      https://cdn.jsdelivr.net/npm/@preact/[email protected]/dist/signals.min.js
// @require      https://cdn.jsdelivr.net/npm/@tanstack/[email protected]/build/umd/index.production.js
// @grant        GM_addStyle
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

(t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const o=document.createElement("style");o.textContent=t,document.head.append(o)})(` #twe-root *,#twe-root :before,#twe-root :after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}#twe-root :before,#twe-root :after{--tw-content: ""}#twe-root,#twe-root :host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}#twe-root body{margin:0;line-height:inherit}#twe-root hr{height:0;color:inherit;border-top-width:1px}#twe-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}#twe-root h1,#twe-root h2,#twe-root h3,#twe-root h4,#twe-root h5,#twe-root h6{font-size:inherit;font-weight:inherit}#twe-root a{color:inherit;text-decoration:inherit}#twe-root b,#twe-root strong{font-weight:bolder}#twe-root code,#twe-root kbd,#twe-root samp,#twe-root pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}#twe-root small{font-size:80%}#twe-root sub,#twe-root sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#twe-root sub{bottom:-.25em}#twe-root sup{top:-.5em}#twe-root table{text-indent:0;border-color:inherit;border-collapse:collapse}#twe-root button,#twe-root input,#twe-root optgroup,#twe-root select,#twe-root textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}#twe-root button,#twe-root select{text-transform:none}#twe-root button,#twe-root [type=button],#twe-root [type=reset],#twe-root [type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}#twe-root :-moz-focusring{outline:auto}#twe-root :-moz-ui-invalid{box-shadow:none}#twe-root progress{vertical-align:baseline}#twe-root ::-webkit-inner-spin-button,#twe-root ::-webkit-outer-spin-button{height:auto}#twe-root [type=search]{-webkit-appearance:textfield;outline-offset:-2px}#twe-root ::-webkit-search-decoration{-webkit-appearance:none}#twe-root ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}#twe-root summary{display:list-item}#twe-root blockquote,#twe-root dl,#twe-root dd,#twe-root h1,#twe-root h2,#twe-root h3,#twe-root h4,#twe-root h5,#twe-root h6,#twe-root hr,#twe-root figure,#twe-root p,#twe-root pre{margin:0}#twe-root fieldset{margin:0;padding:0}#twe-root legend{padding:0}#twe-root ol,#twe-root ul,#twe-root menu{list-style:none;margin:0;padding:0}#twe-root dialog{padding:0}#twe-root textarea{resize:vertical}#twe-root input::-moz-placeholder,#twe-root textarea::-moz-placeholder{opacity:1;color:#9ca3af}#twe-root input::placeholder,#twe-root textarea::placeholder{opacity:1;color:#9ca3af}#twe-root button,#twe-root [role=button]{cursor:pointer}#twe-root :disabled{cursor:default}#twe-root img,#twe-root svg,#twe-root video,#twe-root canvas,#twe-root audio,#twe-root iframe,#twe-root embed,#twe-root object{display:block;vertical-align:middle}#twe-root img,#twe-root video{max-width:100%;height:auto}#twe-root [hidden]{display:none}#twe-root,#twe-root [data-theme]{background-color:var(--fallback-b1,oklch(var(--b1)/1));color:var(--fallback-bc,oklch(var(--bc)/1))}@supports not (color: oklch(0 0 0)){#twe-root{color-scheme:light;--fallback-p: #491eff;--fallback-pc: #d4dbff;--fallback-s: #ff41c7;--fallback-sc: #fff9fc;--fallback-a: #00cfbd;--fallback-ac: #00100d;--fallback-n: #2b3440;--fallback-nc: #d7dde4;--fallback-b1: #ffffff;--fallback-b2: #e5e6e6;--fallback-b3: #e5e6e6;--fallback-bc: #1f2937;--fallback-in: #00b3f0;--fallback-inc: #000000;--fallback-su: #00ca92;--fallback-suc: #000000;--fallback-wa: #ffc22d;--fallback-wac: #000000;--fallback-er: #ff6f70;--fallback-erc: #000000}@media (prefers-color-scheme: dark){#twe-root{color-scheme:dark;--fallback-p: #7582ff;--fallback-pc: #050617;--fallback-s: #ff71cf;--fallback-sc: #190211;--fallback-a: #00c7b5;--fallback-ac: #000e0c;--fallback-n: #2a323c;--fallback-nc: #a6adbb;--fallback-b1: #1d232a;--fallback-b2: #191e24;--fallback-b3: #15191e;--fallback-bc: #a6adbb;--fallback-in: #00b3f0;--fallback-inc: #000000;--fallback-su: #00ca92;--fallback-suc: #000000;--fallback-wa: #ffc22d;--fallback-wac: #000000;--fallback-er: #ff6f70;--fallback-erc: #000000}}}#twe-root{-webkit-tap-highlight-color:transparent}#twe-root{color-scheme:light;--in: .7206 .191 231.6;--su: 64.8% .15 160;--wa: .8471 .199 83.87;--er: .7176 .221 22.18;--pc: .152344 .017892 200.026556;--sc: .15787 .020249 356.29965;--ac: .158762 .029206 78.618794;--nc: .847148 .013247 313.189598;--inc: 0 0 0;--suc: 0 0 0;--wac: 0 0 0;--erc: 0 0 0;--rounded-box: 16px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--p: .76172 .089459 200.026556;--s: .789351 .101246 356.29965;--a: .793811 .146032 78.618794;--n: .235742 .066235 313.189598;--b1: .977882 .00418 56.375637;--b2: .939822 .007638 61.449292;--b3: .915861 .006811 53.440502;--bc: .235742 .066235 313.189598;--rounded-btn: 30.4px;--tab-border: 2px;--tab-radius: 11.2px}@media (prefers-color-scheme: dark){#twe-root{color-scheme:dark;--b2: .268053 .020556 277.508664;--b3: .247877 .019009 277.508664;--pc: .150922 .036614 346.812432;--sc: .148405 .029709 301.883095;--ac: .166785 .024826 66.558491;--nc: .878891 .006515 275.524078;--inc: .176526 .018676 212.846491;--suc: .174199 .043903 148.024881;--wac: .191068 .026849 112.757109;--erc: .136441 .041266 24.430965;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .754611 .18307 346.812432;--s: .742023 .148546 301.883095;--a: .833927 .124132 66.558491;--n: .394456 .032576 275.524078;--b1: .288229 .022103 277.508664;--bc: .977477 .007913 106.545019;--in: .88263 .09338 212.846491;--su: .870995 .219516 148.024881;--wa: .955338 .134246 112.757109;--er: .682204 .206328 24.430965}}#twe-root [data-theme=cupcake]{color-scheme:light;--in: .7206 .191 231.6;--su: 64.8% .15 160;--wa: .8471 .199 83.87;--er: .7176 .221 22.18;--pc: .152344 .017892 200.026556;--sc: .15787 .020249 356.29965;--ac: .158762 .029206 78.618794;--nc: .847148 .013247 313.189598;--inc: 0 0 0;--suc: 0 0 0;--wac: 0 0 0;--erc: 0 0 0;--rounded-box: 16px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--p: .76172 .089459 200.026556;--s: .789351 .101246 356.29965;--a: .793811 .146032 78.618794;--n: .235742 .066235 313.189598;--b1: .977882 .00418 56.375637;--b2: .939822 .007638 61.449292;--b3: .915861 .006811 53.440502;--bc: .235742 .066235 313.189598;--rounded-btn: 30.4px;--tab-border: 2px;--tab-radius: 11.2px}#twe-root [data-theme=dark]{color-scheme:dark;--in: .7206 .191 231.6;--su: 64.8% .15 160;--wa: .8471 .199 83.87;--er: .7176 .221 22.18;--pc: .13138 .0392 275.75;--sc: .1496 .052 342.55;--ac: .14902 .0334 183.61;--inc: 0 0 0;--suc: 0 0 0;--wac: 0 0 0;--erc: 0 0 0;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .6569 .196 275.75;--s: .748 .26 342.55;--a: .7451 .167 183.61;--n: .313815 .021108 254.139175;--nc: .746477 .0216 264.435964;--b1: .253267 .015896 252.417568;--b2: .232607 .013807 253.100675;--b3: .211484 .01165 254.087939;--bc: .746477 .0216 264.435964}#twe-root [data-theme=emerald]{color-scheme:light;--b2: .93 0 0;--b3: .86 0 0;--in: .7206 .191 231.6;--su: 64.8% .15 160;--wa: .8471 .199 83.87;--er: .7176 .221 22.18;--inc: 0 0 0;--suc: 0 0 0;--wac: 0 0 0;--erc: 0 0 0;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .766626 .135433 153.450024;--pc: .333872 .040618 162.240129;--s: .613028 .202368 261.294233;--sc: 1 0 0;--a: .727725 .149783 33.200363;--ac: 0 0 0;--n: .355192 .032071 262.988584;--nc: .984625 .001706 247.838921;--b1: 1 0 0;--bc: .355192 .032071 262.988584;--animation-btn: 0;--animation-input: 0;--btn-focus-scale: 1}#twe-root [data-theme=cyberpunk]{color-scheme:light;--b2: .878943 .16647 104.32;--b3: .812786 .15394 104.32;--in: .7206 .191 231.6;--su: 64.8% .15 160;--wa: .8471 .199 83.87;--er: .7176 .221 22.18;--bc: .18902 .0358 104.32;--pc: .14844 .0418 6.35;--sc: .16666 .0368 204.72;--ac: .14372 .04352 310.43;--inc: 0 0 0;--suc: 0 0 0;--wac: 0 0 0;--erc: 0 0 0;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;--p: .7422 .209 6.35;--s: .8333 .184 204.72;--a: .7186 .2176 310.43;--n: .2304 .065 269.31;--nc: .9451 .179 104.32;--b1: .9451 .179 104.32;--rounded-box: 0;--rounded-btn: 0;--rounded-badge: 0;--tab-radius: 0}#twe-root [data-theme=valentine]{color-scheme:light;--b2: .880567 .024834 337.06289;--b3: .814288 .022964 337.06289;--pc: .137239 .030755 15.066527;--sc: .143942 .029258 293.189609;--ac: .142537 .014961 197.828857;--inc: .90923 .043042 262.880917;--suc: .12541 .033982 149.213788;--wac: .133168 .031484 58.31834;--erc: .14614 .0414 27.33;--rounded-box: 16px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--p: .686197 .153774 15.066527;--s: .71971 .14629 293.189609;--a: .712685 .074804 197.828857;--n: .546053 .143342 358.004839;--nc: .902701 .037202 336.955191;--b1: .946846 .026703 337.06289;--bc: .373085 .081131 4.606426;--in: .54615 .215208 262.880917;--su: .627052 .169912 149.213788;--wa: .66584 .157422 58.31834;--er: .7307 .207 27.33;--rounded-btn: 30.4px;--tab-radius: 11.2px}#twe-root [data-theme=lofi]{color-scheme:light;--inc: .15908 .0206 205.9;--suc: .18026 .0306 164.14;--wac: .17674 .027 79.94;--erc: .15732 .03 28.47;--border-btn: 1px;--tab-border: 1px;--p: .159066 0 0;--pc: 1 0 0;--s: .21455 .001566 17.278957;--sc: 1 0 0;--a: .268618 0 0;--ac: 1 0 0;--n: 0 0 0;--nc: 1 0 0;--b1: 1 0 0;--b2: .961151 0 0;--b3: .92268 .001082 17.17934;--bc: 0 0 0;--in: .7954 .103 205.9;--su: .9013 .153 164.14;--wa: .8837 .135 79.94;--er: .7866 .15 28.47;--rounded-box: 4px;--rounded-btn: 2px;--rounded-badge: 2px;--tab-radius: 2px;--animation-btn: 0;--animation-input: 0;--btn-focus-scale: 1}#twe-root [data-theme=dracula]{color-scheme:dark;--b2: .268053 .020556 277.508664;--b3: .247877 .019009 277.508664;--pc: .150922 .036614 346.812432;--sc: .148405 .029709 301.883095;--ac: .166785 .024826 66.558491;--nc: .878891 .006515 275.524078;--inc: .176526 .018676 212.846491;--suc: .174199 .043903 148.024881;--wac: .191068 .026849 112.757109;--erc: .136441 .041266 24.430965;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .754611 .18307 346.812432;--s: .742023 .148546 301.883095;--a: .833927 .124132 66.558491;--n: .394456 .032576 275.524078;--b1: .288229 .022103 277.508664;--bc: .977477 .007913 106.545019;--in: .88263 .09338 212.846491;--su: .870995 .219516 148.024881;--wa: .955338 .134246 112.757109;--er: .682204 .206328 24.430965}#twe-root [data-theme=cmyk]{color-scheme:light;--b2: .93 0 0;--b3: .86 0 0;--bc: .2 0 0;--pc: .143544 .02666 239.443325;--sc: .128953 .040552 359.339283;--ac: .188458 .037948 105.306968;--nc: .843557 0 0;--inc: .136952 .0189 217.284104;--suc: .893898 .032505 321.406278;--wac: .142473 .031969 52.023412;--erc: .124027 .041677 28.717543;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .717722 .133298 239.443325;--s: .644766 .202758 359.339283;--a: .942289 .189741 105.306968;--n: .217787 0 0;--b1: 1 0 0;--in: .684759 .094499 217.284104;--su: .46949 .162524 321.406278;--wa: .712364 .159843 52.023412;--er: .620133 .208385 28.717543}#twe-root [data-theme=business]{color-scheme:dark;--b2: .226487 0 0;--b3: .20944 0 0;--bc: .848707 0 0;--pc: .883407 .019811 251.473931;--sc: .128185 .005481 229.389418;--ac: .134542 .033545 35.791525;--nc: .854882 .00265 253.041249;--inc: .125233 .028702 240.033697;--suc: .140454 .018919 156.59611;--wac: .154965 .023141 81.519177;--erc: .903221 .029356 29.674507;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .417036 .099057 251.473931;--s: .640924 .027405 229.389418;--a: .67271 .167726 35.791525;--n: .27441 .01325 253.041249;--b1: .243535 0 0;--in: .626163 .143511 240.033697;--su: .702268 .094594 156.59611;--wa: .774824 .115704 81.519177;--er: .516105 .14678 29.674507;--rounded-box: 4px;--rounded-btn: 2px;--rounded-badge: 2px}#twe-root [data-theme=winter]{color-scheme:light;--pc: .91372 .051 257.57;--sc: .885103 .03222 282.339433;--ac: .11988 .038303 335.171434;--nc: .839233 .012704 257.651965;--inc: .176255 .017178 214.515264;--suc: .160988 .015404 197.823719;--wac: .178345 .009167 71.47031;--erc: .146185 .022037 20.076293;--rounded-box: 16px;--rounded-btn: 8px;--rounded-badge: 30.4px;--animation-btn: .25s;--animation-input: .2s;--btn-focus-scale: .95;--border-btn: 1px;--tab-border: 1px;--tab-radius: 8px;--p: .5686 .255 257.57;--s: .425516 .161098 282.339433;--a: .599398 .191515 335.171434;--n: .196166 .063518 257.651965;--b1: 1 0 0;--b2: .974663 .011947 259.822565;--b3: .932686 .016223 262.751375;--bc: .418869 .053885 255.824911;--in: .881275 .085888 214.515264;--su: .804941 .077019 197.823719;--wa: .891725 .045833 71.47031;--er: .730926 .110185 20.076293}#twe-root *,#twe-root :before,#twe-root :after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }#twe-root ::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }#twe-root .alert{display:grid;width:100%;grid-auto-flow:row;align-content:flex-start;align-items:center;justify-items:center;gap:16px;text-align:center;border-radius:var(--rounded-box, 16px);border-width:1px;--tw-border-opacity: 1;border-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));padding:16px;--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--alert-bg: var(--fallback-b2,oklch(var(--b2)/1));--alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1));background-color:var(--alert-bg)}@media (min-width: 640px){#twe-root .alert{grid-auto-flow:column;grid-template-columns:auto minmax(auto,1fr);justify-items:start;text-align:start}}#twe-root .avatar.placeholder>div{display:flex;align-items:center;justify-content:center}@media (hover:hover){#twe-root .label a:hover{--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)))}#twe-root .menu li>*:not(ul):not(.menu-title):not(details):active,#twe-root .menu li>*:not(ul):not(.menu-title):not(details).active,#twe-root .menu li>details>summary:active{--tw-bg-opacity: 1;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-text-opacity: 1;color:var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)))}#twe-root .table tr.hover:hover,#twe-root .table tr.hover:nth-child(2n):hover{--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))}#twe-root .\\!table tr.hover:hover,#twe-root .\\!table tr.hover:nth-child(2n):hover{--tw-bg-opacity: 1 !important;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))!important}#twe-root .table-zebra tr.hover:hover,#twe-root .table-zebra tr.hover:nth-child(2n):hover{--tw-bg-opacity: 1;background-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)))}}#twe-root .btn{display:inline-flex;height:48px;min-height:48px;flex-shrink:0;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-wrap:wrap;align-items:center;justify-content:center;border-radius:var(--rounded-btn, 8px);border-color:transparent;border-color:oklch(var(--btn-color, var(--b2)) / var(--tw-border-opacity));padding-left:16px;padding-right:16px;text-align:center;font-size:14px;line-height:1em;gap:8px;font-weight:600;text-decoration-line:none;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);border-width:var(--border-btn, 1px);animation:button-pop var(--animation-btn, .25s) ease-out;transition-property:color,background-color,border-color,opacity,box-shadow,transform;--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);outline-color:var(--fallback-bc,oklch(var(--bc)/1));background-color:oklch(var(--btn-color, var(--b2)) / var(--tw-bg-opacity));--tw-bg-opacity: 1;--tw-border-opacity: 1}#twe-root .btn-disabled,#twe-root .btn[disabled],#twe-root .btn:disabled{pointer-events:none}#twe-root :where(.btn:is(input[type=checkbox])),#twe-root :where(.btn:is(input[type=radio])){width:auto;-webkit-appearance:none;-moz-appearance:none;appearance:none}#twe-root .btn:is(input[type=checkbox]):after,#twe-root .btn:is(input[type=radio]):after{--tw-content: attr(aria-label);content:var(--tw-content)}#twe-root .card{position:relative;display:flex;flex-direction:column;border-radius:var(--rounded-box, 16px)}#twe-root .card:focus{outline:2px solid transparent;outline-offset:2px}#twe-root .card figure{display:flex;align-items:center;justify-content:center}#twe-root .card.image-full{display:grid}#twe-root .card.image-full:before{position:relative;content:"";z-index:10;border-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));opacity:.75}#twe-root .card.image-full:before,#twe-root .card.image-full>*{grid-column-start:1;grid-row-start:1}#twe-root .card.image-full>figure img{height:100%;-o-object-fit:cover;object-fit:cover}#twe-root .card.image-full>.card-body{position:relative;z-index:20;--tw-text-opacity: 1;color:var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)))}#twe-root .checkbox{flex-shrink:0;--chkbg: var(--fallback-bc,oklch(var(--bc)/1));--chkfg: var(--fallback-b1,oklch(var(--b1)/1));height:24px;width:24px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--rounded-btn, 8px);border-width:1px;border-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));--tw-border-opacity: .2}#twe-root .divider{display:flex;flex-direction:row;align-items:center;align-self:stretch;margin-top:16px;margin-bottom:16px;height:16px;white-space:nowrap}#twe-root .divider:before,#twe-root .divider:after{height:2px;width:100%;flex-grow:1;--tw-content: "";content:var(--tw-content);background-color:var(--fallback-bc,oklch(var(--bc)/.1))}@media (hover: hover){#twe-root .btm-nav>*.disabled:hover,#twe-root .btm-nav>*[disabled]:hover{pointer-events:none;--tw-border-opacity: 0;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-bg-opacity: .1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--tw-text-opacity: .2}#twe-root .btn:hover{--tw-border-opacity: 1;border-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity)));--tw-bg-opacity: 1;background-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)))}@supports (color: color-mix(in oklab,black,black)){#twe-root .btn:hover{background-color:color-mix(in oklab,oklch(var(--btn-color, var(--b2)) / var(--tw-bg-opacity, 1)) 90%,black);border-color:color-mix(in oklab,oklch(var(--btn-color, var(--b2)) / var(--tw-border-opacity, 1)) 90%,black)}}@supports not (color: oklch(0 0 0)){#twe-root .btn:hover{background-color:var(--btn-color, var(--fallback-b2));border-color:var(--btn-color, var(--fallback-b2))}}#twe-root .btn.glass:hover{--glass-opacity: 25%;--glass-border-opacity: 15%}#twe-root .btn-ghost:hover{border-color:transparent}@supports (color: oklch(0 0 0)){#twe-root .btn-ghost:hover{background-color:var(--fallback-bc,oklch(var(--bc)/.2))}}#twe-root .btn-outline.btn-primary:hover{--tw-text-opacity: 1;color:var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)))}@supports (color: color-mix(in oklab,black,black)){#twe-root .btn-outline.btn-primary:hover{background-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black);border-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black)}}#twe-root .btn-outline.btn-secondary:hover{--tw-text-opacity: 1;color:var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)))}@supports (color: color-mix(in oklab,black,black)){#twe-root .btn-outline.btn-secondary:hover{background-color:color-mix(in oklab,var(--fallback-s,oklch(var(--s)/1)) 90%,black);border-color:color-mix(in oklab,var(--fallback-s,oklch(var(--s)/1)) 90%,black)}}#twe-root .btn-disabled:hover,#twe-root .btn[disabled]:hover,#twe-root .btn:disabled:hover{--tw-border-opacity: 0;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-bg-opacity: .2;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--tw-text-opacity: .2}@supports (color: color-mix(in oklab,black,black)){#twe-root .btn:is(input[type=checkbox]:checked):hover,#twe-root .btn:is(input[type=radio]:checked):hover{background-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black);border-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black)}}}#twe-root .footer{display:grid;width:100%;grid-auto-flow:row;place-items:start;-moz-column-gap:16px;column-gap:16px;row-gap:40px;font-size:14px;line-height:20px}#twe-root .footer>*{display:grid;place-items:start;gap:8px}@media (min-width: 48rem){#twe-root .footer{grid-auto-flow:column}#twe-root .footer-center{grid-auto-flow:row dense}}#twe-root .label{display:flex;-webkit-user-select:none;-moz-user-select:none;user-select:none;align-items:center;justify-content:space-between;padding:8px 4px}#twe-root .input{flex-shrink:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:48px;padding-left:16px;padding-right:16px;font-size:16px;line-height:2;line-height:24px;border-radius:var(--rounded-btn, 8px);border-width:1px;border-color:transparent;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .join{display:inline-flex;align-items:stretch;border-radius:var(--rounded-btn, 8px)}#twe-root .join :where(.join-item){border-start-end-radius:0;border-end-end-radius:0;border-end-start-radius:0;border-start-start-radius:0}#twe-root .join .join-item:not(:first-child):not(:last-child),#twe-root .join *:not(:first-child):not(:last-child) .join-item{border-start-end-radius:0;border-end-end-radius:0;border-end-start-radius:0;border-start-start-radius:0}#twe-root .join .join-item:first-child:not(:last-child),#twe-root .join *:first-child:not(:last-child) .join-item{border-start-end-radius:0;border-end-end-radius:0}#twe-root .join .dropdown .join-item:first-child:not(:last-child),#twe-root .join *:first-child:not(:last-child) .dropdown .join-item{border-start-end-radius:inherit;border-end-end-radius:inherit}#twe-root .join :where(.join-item:first-child:not(:last-child)),#twe-root .join :where(*:first-child:not(:last-child) .join-item){border-end-start-radius:inherit;border-start-start-radius:inherit}#twe-root .join .join-item:last-child:not(:first-child),#twe-root .join *:last-child:not(:first-child) .join-item{border-end-start-radius:0;border-start-start-radius:0}#twe-root .join :where(.join-item:last-child:not(:first-child)),#twe-root .join :where(*:last-child:not(:first-child) .join-item){border-start-end-radius:inherit;border-end-end-radius:inherit}@supports not selector(:has(*)){#twe-root :where(.join *){border-radius:inherit}}@supports selector(:has(*)){#twe-root :where(.join *:has(.join-item)){border-radius:inherit}}#twe-root .link{cursor:pointer;text-decoration-line:underline}#twe-root .menu li.disabled{cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;user-select:none;color:var(--fallback-bc,oklch(var(--bc)/.3))}#twe-root .modal{pointer-events:none;position:fixed;top:0;right:0;bottom:0;left:0;margin:0;display:grid;height:100%;max-height:none;width:100%;max-width:none;justify-items:center;padding:0;opacity:0;overscroll-behavior:contain;z-index:999;background-color:transparent;color:inherit;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);transition-property:transform,opacity,visibility;overflow-y:hidden}#twe-root :where(.modal){align-items:center}#twe-root .modal-box{max-height:calc(100vh - 5em);grid-column-start:1;grid-row-start:1;width:91.666667%;max-width:512px;--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-bottom-right-radius:var(--rounded-box, 16px);border-bottom-left-radius:var(--rounded-box, 16px);border-top-left-radius:var(--rounded-box, 16px);border-top-right-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));padding:24px;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1);transition-duration:.2s;box-shadow:#00000040 0 25px 50px -12px;overflow-y:auto;overscroll-behavior:contain}#twe-root .modal-open,#twe-root .modal:target,#twe-root .modal-toggle:checked+.modal,#twe-root .modal[open]{pointer-events:auto;visibility:visible;opacity:1}#twe-root:has(:is(.modal-open,.modal:target,.modal-toggle:checked+.modal,.modal[open])){overflow:hidden}#twe-root .progress{position:relative;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;overflow:hidden;height:8px;border-radius:var(--rounded-box, 16px);background-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .select{display:inline-flex;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:48px;min-height:48px;padding-left:16px;padding-right:40px;font-size:14px;line-height:20px;line-height:2;border-radius:var(--rounded-btn, 8px);border-width:1px;border-color:transparent;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-size:4px 4px,4px 4px;background-repeat:no-repeat}#twe-root .select[multiple]{height:auto}#twe-root .\\!table{position:relative!important;width:100%!important;border-radius:var(--rounded-box, 16px)!important;text-align:left!important;font-size:14px!important;line-height:20px!important}#twe-root .table{position:relative;width:100%;border-radius:var(--rounded-box, 16px);text-align:left;font-size:14px;line-height:20px}#twe-root .\\!table :where(.table-pin-rows thead tr){position:sticky!important;top:0!important;z-index:1!important;--tw-bg-opacity: 1 !important;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))!important}#twe-root .table :where(.table-pin-rows thead tr){position:sticky;top:0;z-index:1;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .\\!table :where(.table-pin-rows tfoot tr){position:sticky!important;bottom:0!important;z-index:1!important;--tw-bg-opacity: 1 !important;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))!important}#twe-root .table :where(.table-pin-rows tfoot tr){position:sticky;bottom:0;z-index:1;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .\\!table :where(.table-pin-cols tr th){position:sticky!important;left:0!important;right:0!important;--tw-bg-opacity: 1 !important;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))!important}#twe-root .table :where(.table-pin-cols tr th){position:sticky;left:0;right:0;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .table-zebra tbody tr:nth-child(2n) :where(.table-pin-cols tr th){--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))}#twe-root .timeline{position:relative;display:flex}#twe-root :where(.timeline>li){position:relative;display:grid;flex-shrink:0;align-items:center;grid-template-rows:var(--timeline-row-start, minmax(0, 1fr)) auto var( --timeline-row-end, minmax(0, 1fr) );grid-template-columns:var(--timeline-col-start, minmax(0, 1fr)) auto var( --timeline-col-end, minmax(0, 1fr) )}#twe-root .timeline>li>hr{width:100%;border-width:0px}#twe-root :where(.timeline>li>hr):first-child{grid-column-start:1;grid-row-start:2}#twe-root :where(.timeline>li>hr):last-child{grid-column-start:3;grid-column-end:none;grid-row-start:2;grid-row-end:auto}#twe-root .toggle{flex-shrink:0;--tglbg: var(--fallback-b1,oklch(var(--b1)/1));--handleoffset: 24px;--handleoffsetcalculator: calc(var(--handleoffset) * -1);--togglehandleborder: 0 0;height:24px;width:48px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--rounded-badge, 30.4px);border-width:1px;border-color:currentColor;background-color:currentColor;color:var(--fallback-bc,oklch(var(--bc)/.5));transition:background,box-shadow var(--animation-input, .2s) ease-out;box-shadow:var(--handleoffsetcalculator) 0 0 2px var(--tglbg) inset,0 0 0 2px var(--tglbg) inset,var(--togglehandleborder)}#twe-root .alert-error{border-color:var(--fallback-er,oklch(var(--er)/.2));--tw-text-opacity: 1;color:var(--fallback-erc,oklch(var(--erc)/var(--tw-text-opacity)));--alert-bg: var(--fallback-er,oklch(var(--er)/1));--alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1))}#twe-root .btm-nav>*:where(.active){border-top-width:2px;--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .btm-nav>*.disabled,#twe-root .btm-nav>*[disabled]{pointer-events:none;--tw-border-opacity: 0;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-bg-opacity: .1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--tw-text-opacity: .2}#twe-root .btm-nav>* .label{font-size:16px;line-height:24px}#twe-root .btn:active:hover,#twe-root .btn:active:focus{animation:button-pop 0s ease-out;transform:scale(var(--btn-focus-scale, .97))}@supports not (color: oklch(0 0 0)){#twe-root .btn{background-color:var(--btn-color, var(--fallback-b2));border-color:var(--btn-color, var(--fallback-b2))}#twe-root .btn-primary{--btn-color: var(--fallback-p)}#twe-root .btn-secondary{--btn-color: var(--fallback-s)}#twe-root .btn-neutral{--btn-color: var(--fallback-n)}}@supports (color: color-mix(in oklab,black,black)){#twe-root .btn-outline.btn-primary.btn-active{background-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black);border-color:color-mix(in oklab,var(--fallback-p,oklch(var(--p)/1)) 90%,black)}#twe-root .btn-outline.btn-secondary.btn-active{background-color:color-mix(in oklab,var(--fallback-s,oklch(var(--s)/1)) 90%,black);border-color:color-mix(in oklab,var(--fallback-s,oklch(var(--s)/1)) 90%,black)}}#twe-root .btn:focus-visible{outline-style:solid;outline-width:2px;outline-offset:2px}#twe-root .btn-primary{--tw-text-opacity: 1;color:var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));outline-color:var(--fallback-p,oklch(var(--p)/1))}@supports (color: oklch(0 0 0)){#twe-root .btn-primary{--btn-color: var(--p)}#twe-root .btn-secondary{--btn-color: var(--s)}#twe-root .btn-neutral{--btn-color: var(--n)}}#twe-root .btn-secondary{--tw-text-opacity: 1;color:var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)));outline-color:var(--fallback-s,oklch(var(--s)/1))}#twe-root .btn-neutral{--tw-text-opacity: 1;color:var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));outline-color:var(--fallback-n,oklch(var(--n)/1))}#twe-root .btn.glass{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);outline-color:currentColor}#twe-root .btn.glass.btn-active{--glass-opacity: 25%;--glass-border-opacity: 15%}#twe-root .btn-ghost{border-width:1px;border-color:transparent;background-color:transparent;color:currentColor;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);outline-color:currentColor}#twe-root .btn-ghost.btn-active{border-color:transparent;background-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .btn-outline.btn-primary{--tw-text-opacity: 1;color:var(--fallback-p,oklch(var(--p)/var(--tw-text-opacity)))}#twe-root .btn-outline.btn-primary.btn-active{--tw-text-opacity: 1;color:var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)))}#twe-root .btn-outline.btn-secondary{--tw-text-opacity: 1;color:var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity)))}#twe-root .btn-outline.btn-secondary.btn-active{--tw-text-opacity: 1;color:var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)))}#twe-root .btn.btn-disabled,#twe-root .btn[disabled],#twe-root .btn:disabled{--tw-border-opacity: 0;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-bg-opacity: .2;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));--tw-text-opacity: .2}#twe-root .btn:is(input[type=checkbox]:checked),#twe-root .btn:is(input[type=radio]:checked){--tw-border-opacity: 1;border-color:var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity)));--tw-bg-opacity: 1;background-color:var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)));--tw-text-opacity: 1;color:var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)))}#twe-root .btn:is(input[type=checkbox]:checked):focus-visible,#twe-root .btn:is(input[type=radio]:checked):focus-visible{outline-color:var(--fallback-p,oklch(var(--p)/1))}@keyframes button-pop{0%{transform:scale(var(--btn-focus-scale, .98))}40%{transform:scale(1.02)}to{transform:scale(1)}}#twe-root .card :where(figure:first-child){overflow:hidden;border-start-start-radius:inherit;border-start-end-radius:inherit;border-end-start-radius:unset;border-end-end-radius:unset}#twe-root .card :where(figure:last-child){overflow:hidden;border-start-start-radius:unset;border-start-end-radius:unset;border-end-start-radius:inherit;border-end-end-radius:inherit}#twe-root .card:focus-visible{outline:2px solid currentColor;outline-offset:2px}#twe-root .card.bordered{border-width:1px;--tw-border-opacity: 1;border-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)))}#twe-root .card.compact .card-body{padding:16px;font-size:14px;line-height:20px}#twe-root .card.image-full :where(figure){overflow:hidden;border-radius:inherit}#twe-root .checkbox:focus{box-shadow:none}#twe-root .checkbox:focus-visible{outline-style:solid;outline-width:2px;outline-offset:2px;outline-color:var(--fallback-bc,oklch(var(--bc)/1))}#twe-root .checkbox:checked,#twe-root .checkbox[checked=true],#twe-root .checkbox[aria-checked=true]{background-repeat:no-repeat;animation:checkmark var(--animation-input, .2s) ease-out;background-color:var(--chkbg);background-image:linear-gradient(-45deg,transparent 65%,var(--chkbg) 65.99%),linear-gradient(45deg,transparent 75%,var(--chkbg) 75.99%),linear-gradient(-45deg,var(--chkbg) 40%,transparent 40.99%),linear-gradient(45deg,var(--chkbg) 30%,var(--chkfg) 30.99%,var(--chkfg) 40%,transparent 40.99%),linear-gradient(-45deg,var(--chkfg) 50%,var(--chkbg) 50.99%)}#twe-root .checkbox:indeterminate{--tw-bg-opacity: 1;background-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)));background-repeat:no-repeat;animation:checkmark var(--animation-input, .2s) ease-out;background-image:linear-gradient(90deg,transparent 80%,var(--chkbg) 80%),linear-gradient(-90deg,transparent 80%,var(--chkbg) 80%),linear-gradient(0deg,var(--chkbg) 43%,var(--chkfg) 43%,var(--chkfg) 57%,var(--chkbg) 57%)}#twe-root .checkbox:disabled{cursor:not-allowed;border-color:transparent;--tw-bg-opacity: 1;background-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)));opacity:.2}@keyframes checkmark{0%{background-position-y:5px}50%{background-position-y:-2px}to{background-position-y:0}}#twe-root .divider:not(:empty){gap:16px}#twe-root .label-text{font-size:14px;line-height:20px;--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)))}#twe-root .input input:focus{outline:2px solid transparent;outline-offset:2px}#twe-root .input[list]::-webkit-calendar-picker-indicator{line-height:1em}#twe-root .input-bordered{border-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .input:focus,#twe-root .input:focus-within{box-shadow:none;border-color:var(--fallback-bc,oklch(var(--bc)/.2));outline-style:solid;outline-width:2px;outline-offset:2px;outline-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .input-disabled,#twe-root .input:disabled,#twe-root .input[disabled]{cursor:not-allowed;--tw-border-opacity: 1;border-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));color:var(--fallback-bc,oklch(var(--bc)/.4))}#twe-root .input-disabled::-moz-placeholder,#twe-root .input:disabled::-moz-placeholder,#twe-root .input[disabled]::-moz-placeholder{color:var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));--tw-placeholder-opacity: .2}#twe-root .input-disabled::placeholder,#twe-root .input:disabled::placeholder,#twe-root .input[disabled]::placeholder{color:var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));--tw-placeholder-opacity: .2}#twe-root .input::-webkit-date-and-time-value{text-align:inherit}#twe-root .join>:where(*:not(:first-child)){margin-top:0;margin-bottom:0;margin-inline-start:-1px}#twe-root .join-item:focus{isolation:isolate}#twe-root .link:focus{outline:2px solid transparent;outline-offset:2px}#twe-root .link:focus-visible{outline:2px solid currentColor;outline-offset:2px}#twe-root .loading{pointer-events:none;display:inline-block;aspect-ratio:1 / 1;width:24px;background-color:currentColor;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E")}#twe-root .loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E")}#twe-root .menu li>*:not(ul):not(.menu-title):not(details):active,#twe-root .menu li>*:not(ul):not(.menu-title):not(details).active,#twe-root .menu li>details>summary:active{--tw-bg-opacity: 1;background-color:var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));--tw-text-opacity: 1;color:var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)))}#twe-root .mockup-phone .display{overflow:hidden;border-radius:40px;margin-top:-25px}#twe-root .mockup-browser .mockup-browser-toolbar .input{position:relative;margin-left:auto;margin-right:auto;display:block;height:28px;width:384px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));padding-left:32px;direction:ltr}#twe-root .mockup-browser .mockup-browser-toolbar .input:before{content:"";position:absolute;left:8px;top:50%;aspect-ratio:1 / 1;height:12px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:9999px;border-width:2px;border-color:currentColor;opacity:.6}#twe-root .mockup-browser .mockup-browser-toolbar .input:after{content:"";position:absolute;left:20px;top:50%;height:8px;--tw-translate-y: 25%;--tw-rotate: -45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:9999px;border-width:1px;border-color:currentColor;opacity:.6}#twe-root .modal:not(dialog:not(.modal-open)),#twe-root .modal::backdrop{background-color:#0006;animation:modal-pop .2s ease-out}#twe-root .modal-backdrop{z-index:-1;grid-column-start:1;grid-row-start:1;display:grid;align-self:stretch;justify-self:stretch;color:transparent}#twe-root .modal-open .modal-box,#twe-root .modal-toggle:checked+.modal .modal-box,#twe-root .modal:target .modal-box,#twe-root .modal[open] .modal-box{--tw-translate-y: 0px;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes modal-pop{0%{opacity:0}}#twe-root .progress::-moz-progress-bar{border-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)))}#twe-root .progress-primary::-moz-progress-bar{border-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)))}#twe-root .progress-secondary::-moz-progress-bar{border-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity)))}#twe-root .progress:indeterminate{--progress-color: var(--fallback-bc,oklch(var(--bc)/1));background-image:repeating-linear-gradient(90deg,var(--progress-color) -1%,var(--progress-color) 10%,transparent 10%,transparent 90%);background-size:200%;background-position-x:15%;animation:progress-loading 5s ease-in-out infinite}#twe-root .progress-primary:indeterminate{--progress-color: var(--fallback-p,oklch(var(--p)/1))}#twe-root .progress-secondary:indeterminate{--progress-color: var(--fallback-s,oklch(var(--s)/1))}#twe-root .progress::-webkit-progress-bar{border-radius:var(--rounded-box, 16px);background-color:transparent}#twe-root .progress::-webkit-progress-value{border-radius:var(--rounded-box, 16px);--tw-bg-opacity: 1;background-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)))}#twe-root .progress-primary::-webkit-progress-value{--tw-bg-opacity: 1;background-color:var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)))}#twe-root .progress-secondary::-webkit-progress-value{--tw-bg-opacity: 1;background-color:var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity)))}#twe-root .progress:indeterminate::-moz-progress-bar{background-color:transparent;background-image:repeating-linear-gradient(90deg,var(--progress-color) -1%,var(--progress-color) 10%,transparent 10%,transparent 90%);background-size:200%;background-position-x:15%;animation:progress-loading 5s ease-in-out infinite}@keyframes progress-loading{50%{background-position-x:-115%}}@keyframes radiomark{0%{box-shadow:0 0 0 12px var(--fallback-b1,oklch(var(--b1)/1)) inset,0 0 0 12px var(--fallback-b1,oklch(var(--b1)/1)) inset}50%{box-shadow:0 0 0 3px var(--fallback-b1,oklch(var(--b1)/1)) inset,0 0 0 3px var(--fallback-b1,oklch(var(--b1)/1)) inset}to{box-shadow:0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset,0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset}}@keyframes rating-pop{0%{transform:translateY(-.125em)}40%{transform:translateY(-.125em)}to{transform:translateY(0)}}#twe-root .select-bordered{border-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .select:focus{box-shadow:none;border-color:var(--fallback-bc,oklch(var(--bc)/.2));outline-style:solid;outline-width:2px;outline-offset:2px;outline-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .select-disabled,#twe-root .select:disabled,#twe-root .select[disabled]{cursor:not-allowed;--tw-border-opacity: 1;border-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));--tw-text-opacity: .2}#twe-root .select-disabled::-moz-placeholder,#twe-root .select:disabled::-moz-placeholder,#twe-root .select[disabled]::-moz-placeholder{color:var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));--tw-placeholder-opacity: .2}#twe-root .select-disabled::placeholder,#twe-root .select:disabled::placeholder,#twe-root .select[disabled]::placeholder{color:var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));--tw-placeholder-opacity: .2}#twe-root .select-multiple,#twe-root .select[multiple],#twe-root .select[size].select:not([size="1"]){background-image:none;padding-right:16px}#twe-root [dir=rtl] .select{background-position:calc(0% + 12px) calc(1px + 50%),calc(0% + 16px) calc(1px + 50%)}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}#twe-root :is([dir=rtl] .\\!table){text-align:right!important}#twe-root :is([dir=rtl] .table){text-align:right}#twe-root .\\!table :where(th,td){padding:12px 16px!important;vertical-align:middle!important}#twe-root .table :where(th,td){padding:12px 16px;vertical-align:middle}#twe-root .table tr.active,#twe-root .table tr.active:nth-child(2n),#twe-root .table-zebra tbody tr:nth-child(2n){--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))}#twe-root .\\!table tr.active,#twe-root .\\!table tr.active:nth-child(2n){--tw-bg-opacity: 1 !important;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))!important}#twe-root .table-zebra tr.active,#twe-root .table-zebra tr.active:nth-child(2n),#twe-root .table-zebra-zebra tbody tr:nth-child(2n){--tw-bg-opacity: 1;background-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)))}#twe-root .table :where(thead,tbody) :where(tr:not(:last-child)),#twe-root .table :where(thead,tbody) :where(tr:first-child:last-child){border-bottom-width:1px;--tw-border-opacity: 1;border-bottom-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)))}#twe-root .\\!table :where(thead,tbody) :where(tr:not(:last-child)),#twe-root .\\!table :where(thead,tbody) :where(tr:first-child:last-child){border-bottom-width:1px!important;--tw-border-opacity: 1 !important;border-bottom-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)))!important}#twe-root .\\!table :where(thead,tfoot){white-space:nowrap!important;font-size:12px!important;line-height:16px!important;font-weight:700!important;color:var(--fallback-bc,oklch(var(--bc)/.6))!important}#twe-root .table :where(thead,tfoot){white-space:nowrap;font-size:12px;line-height:16px;font-weight:700;color:var(--fallback-bc,oklch(var(--bc)/.6))}#twe-root .timeline hr{height:4px}#twe-root :where(.timeline hr){--tw-bg-opacity: 1;background-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)))}#twe-root :where(.timeline:has(.timeline-middle) hr):first-child{border-start-end-radius:var(--rounded-badge, 30.4px);border-end-end-radius:var(--rounded-badge, 30.4px);border-start-start-radius:0px;border-end-start-radius:0px}#twe-root :where(.timeline:has(.timeline-middle) hr):last-child{border-start-start-radius:var(--rounded-badge, 30.4px);border-end-start-radius:var(--rounded-badge, 30.4px);border-start-end-radius:0px;border-end-end-radius:0px}#twe-root :where(.timeline:not(:has(.timeline-middle)) :first-child hr:last-child){border-start-start-radius:var(--rounded-badge, 30.4px);border-end-start-radius:var(--rounded-badge, 30.4px);border-start-end-radius:0px;border-end-end-radius:0px}#twe-root :where(.timeline:not(:has(.timeline-middle)) :last-child hr:first-child){border-start-end-radius:var(--rounded-badge, 30.4px);border-end-end-radius:var(--rounded-badge, 30.4px);border-start-start-radius:0px;border-end-start-radius:0px}@keyframes toast-pop{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}#twe-root [dir=rtl] .toggle{--handleoffsetcalculator: calc(var(--handleoffset) * 1)}#twe-root .toggle:focus-visible{outline-style:solid;outline-width:2px;outline-offset:2px;outline-color:var(--fallback-bc,oklch(var(--bc)/.2))}#twe-root .toggle:hover{background-color:currentColor}#twe-root .toggle:checked,#twe-root .toggle[checked=true],#twe-root .toggle[aria-checked=true]{background-image:none;--handleoffsetcalculator: var(--handleoffset);--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)))}#twe-root [dir=rtl] .toggle:checked,#twe-root [dir=rtl] .toggle[checked=true],#twe-root [dir=rtl] .toggle[aria-checked=true]{--handleoffsetcalculator: calc(var(--handleoffset) * -1)}#twe-root .toggle:indeterminate{--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));box-shadow:calc(var(--handleoffset) / 2) 0 0 2px var(--tglbg) inset,calc(var(--handleoffset) / -2) 0 0 2px var(--tglbg) inset,0 0 0 2px var(--tglbg) inset}#twe-root [dir=rtl] .toggle:indeterminate{box-shadow:calc(var(--handleoffset) / 2) 0 0 2px var(--tglbg) inset,calc(var(--handleoffset) / -2) 0 0 2px var(--tglbg) inset,0 0 0 2px var(--tglbg) inset}#twe-root .toggle-primary:focus-visible{outline-color:var(--fallback-p,oklch(var(--p)/1))}#twe-root .toggle-primary:checked,#twe-root .toggle-primary[checked=true],#twe-root .toggle-primary[aria-checked=true]{border-color:var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity)));--tw-border-opacity: .1;--tw-bg-opacity: 1;background-color:var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)));--tw-text-opacity: 1;color:var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)))}#twe-root .toggle-secondary:focus-visible{outline-color:var(--fallback-s,oklch(var(--s)/1))}#twe-root .toggle-secondary:checked,#twe-root .toggle-secondary[checked=true],#twe-root .toggle-secondary[aria-checked=true]{border-color:var(--fallback-s,oklch(var(--s)/var(--tw-border-opacity)));--tw-border-opacity: .1;--tw-bg-opacity: 1;background-color:var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity)));--tw-text-opacity: 1;color:var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)))}#twe-root .toggle:disabled{cursor:not-allowed;--tw-border-opacity: 1;border-color:var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));background-color:transparent;opacity:.3;--togglehandleborder: 0 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset, var(--handleoffsetcalculator) 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset}#twe-root .btm-nav-xs>*:where(.active){border-top-width:1px}#twe-root .btm-nav-sm>*:where(.active){border-top-width:2px}#twe-root .btm-nav-md>*:where(.active){border-top-width:2px}#twe-root .btm-nav-lg>*:where(.active){border-top-width:4px}#twe-root .btn-xs{height:24px;min-height:24px;padding-left:8px;padding-right:8px;font-size:12px}#twe-root .btn-sm{height:32px;min-height:32px;padding-left:12px;padding-right:12px;font-size:14px}#twe-root .btn-square:where(.btn-xs){height:24px;width:24px;padding:0}#twe-root .btn-square:where(.btn-sm){height:32px;width:32px;padding:0}#twe-root .btn-circle:where(.btn-xs){height:24px;width:24px;border-radius:9999px;padding:0}#twe-root .btn-circle:where(.btn-sm){height:32px;width:32px;border-radius:9999px;padding:0}#twe-root [type=checkbox].checkbox-sm{height:20px;width:20px}#twe-root .input-xs{height:24px;padding-left:8px;padding-right:8px;font-size:12px;line-height:16px;line-height:1.625}#twe-root .input-sm{height:32px;padding-left:12px;padding-right:12px;font-size:14px;line-height:32px}#twe-root .join.join-vertical{flex-direction:column}#twe-root .join.join-vertical .join-item:first-child:not(:last-child),#twe-root .join.join-vertical *:first-child:not(:last-child) .join-item{border-end-start-radius:0;border-end-end-radius:0;border-start-start-radius:inherit;border-start-end-radius:inherit}#twe-root .join.join-vertical .join-item:last-child:not(:first-child),#twe-root .join.join-vertical *:last-child:not(:first-child) .join-item{border-start-start-radius:0;border-start-end-radius:0;border-end-start-radius:inherit;border-end-end-radius:inherit}#twe-root .join.join-horizontal{flex-direction:row}#twe-root .join.join-horizontal .join-item:first-child:not(:last-child),#twe-root .join.join-horizontal *:first-child:not(:last-child) .join-item{border-end-end-radius:0;border-start-end-radius:0;border-end-start-radius:inherit;border-start-start-radius:inherit}#twe-root .join.join-horizontal .join-item:last-child:not(:first-child),#twe-root .join.join-horizontal *:last-child:not(:first-child) .join-item{border-end-start-radius:0;border-start-start-radius:0;border-end-end-radius:inherit;border-start-end-radius:inherit}#twe-root .select-sm{height:32px;min-height:32px;padding-left:12px;padding-right:32px;font-size:14px;line-height:32px}#twe-root [dir=rtl] .select-sm{padding-left:32px;padding-right:12px}#twe-root .select-xs{height:24px;min-height:24px;padding-left:8px;padding-right:32px;font-size:12px;line-height:16px;line-height:1.625}#twe-root [dir=rtl] .select-xs{padding-left:32px;padding-right:8px}#twe-root .tooltip{position:relative;display:inline-block;--tooltip-offset: calc(100% + 1px + var(--tooltip-tail, 0px))}#twe-root .tooltip:before{position:absolute;pointer-events:none;z-index:1;content:var(--tw-content);--tw-content: attr(data-tip)}#twe-root .tooltip:before,#twe-root .tooltip-top:before{transform:translate(-50%);top:auto;left:50%;right:auto;bottom:var(--tooltip-offset)}#twe-root .tooltip-bottom:before{transform:translate(-50%);top:var(--tooltip-offset);left:50%;right:auto;bottom:auto}#twe-root .card-compact .card-body{padding:16px;font-size:14px;line-height:20px}#twe-root .card-compact .card-title{margin-bottom:4px}#twe-root .join.join-vertical>:where(*:not(:first-child)){margin-left:0;margin-right:0;margin-top:-1px}#twe-root .join.join-horizontal>:where(*:not(:first-child)){margin-top:0;margin-bottom:0;margin-inline-start:-1px}#twe-root .modal-top :where(.modal-box){width:100%;max-width:none;--tw-translate-y: -40px;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-bottom-right-radius:var(--rounded-box, 16px);border-bottom-left-radius:var(--rounded-box, 16px);border-top-left-radius:0;border-top-right-radius:0}#twe-root .modal-middle :where(.modal-box){width:91.666667%;max-width:512px;--tw-translate-y: 0px;--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-top-left-radius:var(--rounded-box, 16px);border-top-right-radius:var(--rounded-box, 16px);border-bottom-right-radius:var(--rounded-box, 16px);border-bottom-left-radius:var(--rounded-box, 16px)}#twe-root .modal-bottom :where(.modal-box){width:100%;max-width:none;--tw-translate-y: 40px;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-top-left-radius:var(--rounded-box, 16px);border-top-right-radius:var(--rounded-box, 16px);border-bottom-right-radius:0;border-bottom-left-radius:0}#twe-root .table-xs :not(thead):not(tfoot) tr{font-size:12px;line-height:16px}#twe-root .table-xs :where(th,td){padding:4px 8px}#twe-root .tooltip{position:relative;display:inline-block;text-align:center;--tooltip-tail: 3px;--tooltip-color: var(--fallback-n,oklch(var(--n)/1));--tooltip-text-color: var(--fallback-nc,oklch(var(--nc)/1));--tooltip-tail-offset: calc(100% + 1px - var(--tooltip-tail))}#twe-root .tooltip:before,#twe-root .tooltip:after{opacity:0;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-delay:.1s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}#twe-root .tooltip:after{position:absolute;content:"";border-style:solid;border-width:var(--tooltip-tail, 0);width:0;height:0;display:block}#twe-root .tooltip:before{max-width:320px;border-radius:4px;padding:4px 8px;font-size:14px;line-height:20px;background-color:var(--tooltip-color);color:var(--tooltip-text-color);width:-moz-max-content;width:max-content}#twe-root .tooltip.tooltip-open:before{opacity:1;transition-delay:75ms}#twe-root .tooltip.tooltip-open:after{opacity:1;transition-delay:75ms}#twe-root .tooltip:hover:before{opacity:1;transition-delay:75ms}#twe-root .tooltip:hover:after{opacity:1;transition-delay:75ms}#twe-root .tooltip:has(:focus-visible):after,#twe-root .tooltip:has(:focus-visible):before{opacity:1;transition-delay:75ms}#twe-root .tooltip:not([data-tip]):hover:before,#twe-root .tooltip:not([data-tip]):hover:after{visibility:hidden;opacity:0}#twe-root .tooltip:after,#twe-root .tooltip-top:after{transform:translate(-50%);border-color:var(--tooltip-color) transparent transparent transparent;top:auto;left:50%;right:auto;bottom:var(--tooltip-tail-offset)}#twe-root .tooltip-bottom:after{transform:translate(-50%);border-color:transparent transparent var(--tooltip-color) transparent;top:var(--tooltip-tail-offset);left:50%;right:auto;bottom:auto}#twe-root .static{position:static}#twe-root .fixed{position:fixed}#twe-root .absolute{position:absolute}#twe-root .relative{position:relative}#twe-root .bottom-0{bottom:0}#twe-root .bottom-0\\.5{bottom:2px}#twe-root .left-0{left:0}#twe-root .left-0\\.5{left:2px}#twe-root .left-8{left:32px}#twe-root .left-\\[-20px\\]{left:-20px}#twe-root .right-3{right:12px}#twe-root .top-3{top:12px}#twe-root .top-8{top:32px}#twe-root .top-\\[60\\%\\]{top:60%}#twe-root .m-0{margin:0}#twe-root .my-3{margin-top:12px;margin-bottom:12px}#twe-root .my-\\[2px\\]{margin-top:2px;margin-bottom:2px}#twe-root .mb-0{margin-bottom:0}#twe-root .mb-1{margin-bottom:4px}#twe-root .mb-2{margin-bottom:8px}#twe-root .ml-0{margin-left:0}#twe-root .ml-0\\.5{margin-left:2px}#twe-root .ml-1{margin-left:4px}#twe-root .ml-4{margin-left:16px}#twe-root .mr-2{margin-right:8px}#twe-root .mr-3{margin-right:12px}#twe-root .mt-0{margin-top:0}#twe-root .mt-2{margin-top:8px}#twe-root .mt-3{margin-top:12px}#twe-root .mt-6{margin-top:24px}#twe-root .block{display:block}#twe-root .inline{display:inline}#twe-root .flex{display:flex}#twe-root .inline-flex{display:inline-flex}#twe-root .\\!table{display:table!important}#twe-root .table{display:table}#twe-root .contents{display:contents}#twe-root .h-12{height:48px}#twe-root .h-2{height:8px}#twe-root .h-28{height:112px}#twe-root .h-4{height:16px}#twe-root .h-52{height:208px}#twe-root .h-6{height:24px}#twe-root .h-8{height:32px}#twe-root .h-9{height:36px}#twe-root .h-full{height:100%}#twe-root .max-h-48{max-height:192px}#twe-root .max-h-\\[400px\\]{max-height:400px}#twe-root .max-h-\\[500px\\]{max-height:500px}#twe-root .w-1\\/2{width:50%}#twe-root .w-12{width:48px}#twe-root .w-20{width:80px}#twe-root .w-24{width:96px}#twe-root .w-32{width:128px}#twe-root .w-36{width:144px}#twe-root .w-4{width:16px}#twe-root .w-48{width:192px}#twe-root .w-52{width:208px}#twe-root .w-60{width:240px}#twe-root .w-80{width:320px}#twe-root .w-9{width:36px}#twe-root .w-auto{width:auto}#twe-root .w-full{width:100%}#twe-root .w-max{width:-moz-max-content;width:max-content}#twe-root .max-w-4xl{max-width:896px}#twe-root .max-w-full{max-width:100%}#twe-root .max-w-lg{max-width:512px}#twe-root .max-w-sm{max-width:384px}#twe-root .max-w-xl{max-width:576px}#twe-root .max-w-xs{max-width:320px}#twe-root .flex-shrink-0,#twe-root .shrink-0{flex-shrink:0}#twe-root .flex-grow,#twe-root .grow{flex-grow:1}#twe-root .origin-\\[bottom_center\\]{transform-origin:bottom center}#twe-root .translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#twe-root .translate-x-\\[-500px\\]{--tw-translate-x: -500px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#twe-root .transform-none{transform:none}@keyframes ping{75%,to{transform:scale(2);opacity:0}}#twe-root .animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}#twe-root .cursor-pointer{cursor:pointer}#twe-root .select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}#twe-root .resize{resize:both}#twe-root .flex-row{flex-direction:row}#twe-root .flex-col{flex-direction:column}#twe-root .items-start{align-items:flex-start}#twe-root .items-center{align-items:center}#twe-root .justify-start{justify-content:flex-start}#twe-root .justify-end{justify-content:flex-end}#twe-root .justify-center{justify-content:center}#twe-root .justify-between{justify-content:space-between}#twe-root .gap-2{gap:8px}#twe-root .space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(4px * var(--tw-space-x-reverse));margin-left:calc(4px * calc(1 - var(--tw-space-x-reverse)))}#twe-root .space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(8px * var(--tw-space-x-reverse));margin-left:calc(8px * calc(1 - var(--tw-space-x-reverse)))}#twe-root .overflow-hidden{overflow:hidden}#twe-root .overflow-scroll{overflow:scroll}#twe-root .overflow-x-scroll{overflow-x:scroll}#twe-root .overflow-y-scroll{overflow-y:scroll}#twe-root .overscroll-none{overscroll-behavior:none}#twe-root .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#twe-root .whitespace-nowrap{white-space:nowrap}#twe-root .whitespace-pre{white-space:pre}#twe-root .whitespace-pre-wrap{white-space:pre-wrap}#twe-root .break-all{word-break:break-all}#twe-root .rounded{border-radius:4px}#twe-root .rounded-box{border-radius:var(--rounded-box, 16px)}#twe-root .rounded-full{border-radius:9999px}#twe-root .rounded-md{border-radius:6px}#twe-root .border{border-width:1px}#twe-root .border-solid{border-style:solid}#twe-root .border-neutral-content{--tw-border-opacity: 1;border-color:var(--fallback-nc,oklch(var(--nc)/var(--tw-border-opacity)))}#twe-root .border-opacity-50{--tw-border-opacity: .5}#twe-root .bg-base-100{--tw-bg-opacity: 1;background-color:var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)))}#twe-root .bg-base-200{--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))}#twe-root .bg-base-300{--tw-bg-opacity: 1;background-color:var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)))}#twe-root .bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity))}#twe-root .bg-primary{--tw-bg-opacity: 1;background-color:var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)))}#twe-root .bg-secondary{--tw-bg-opacity: 1;background-color:var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity)))}#twe-root .bg-transparent{background-color:transparent}#twe-root .bg-opacity-30{--tw-bg-opacity: .3}#twe-root .fill-base-content{fill:var(--fallback-bc,oklch(var(--bc)/1))}#twe-root .object-contain{-o-object-fit:contain;object-fit:contain}#twe-root .object-cover{-o-object-fit:cover;object-fit:cover}#twe-root .p-0{padding:0}#twe-root .p-2{padding:8px}#twe-root .p-3{padding:12px}#twe-root .px-0{padding-left:0;padding-right:0}#twe-root .px-0\\.5{padding-left:2px;padding-right:2px}#twe-root .px-1{padding-left:4px;padding-right:4px}#twe-root .px-2{padding-left:8px;padding-right:8px}#twe-root .px-4{padding-left:16px;padding-right:16px}#twe-root .py-2{padding-top:8px;padding-bottom:8px}#twe-root .py-2\\.5{padding-top:10px;padding-bottom:10px}#twe-root .py-3{padding-top:12px;padding-bottom:12px}#twe-root .text-center{text-align:center}#twe-root .align-top{vertical-align:top}#twe-root .align-middle{vertical-align:middle}#twe-root .font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}#twe-root .text-base{font-size:16px;line-height:24px}#twe-root .text-sm{font-size:14px;line-height:20px}#twe-root .text-xl{font-size:20px;line-height:28px}#twe-root .text-xs{font-size:12px;line-height:16px}#twe-root .font-bold{font-weight:700}#twe-root .font-medium{font-weight:500}#twe-root .font-semibold{font-weight:600}#twe-root .leading-4{line-height:16px}#twe-root .leading-5{line-height:20px}#twe-root .leading-6{line-height:24px}#twe-root .leading-8{line-height:32px}#twe-root .leading-\\[48px\\]{line-height:48px}#twe-root .leading-loose{line-height:2}#twe-root .leading-none{line-height:1}#twe-root .leading-normal{line-height:1.5}#twe-root .text-base-content{--tw-text-opacity: 1;color:var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)))}#twe-root .text-error{--tw-text-opacity: 1;color:var(--fallback-er,oklch(var(--er)/var(--tw-text-opacity)))}#twe-root .text-success{--tw-text-opacity: 1;color:var(--fallback-su,oklch(var(--su)/var(--tw-text-opacity)))}#twe-root .text-warning{--tw-text-opacity: 1;color:var(--fallback-wa,oklch(var(--wa)/var(--tw-text-opacity)))}#twe-root .text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}#twe-root .text-opacity-50{--tw-text-opacity: .5}#twe-root .text-opacity-60{--tw-text-opacity: .6}#twe-root .text-opacity-70{--tw-text-opacity: .7}#twe-root .opacity-50{opacity:.5}#twe-root .opacity-75{opacity:.75}#twe-root .shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}#twe-root .filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#twe-root .transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}#twe-root .transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}#twe-root .transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}#twe-root .duration-200{transition-duration:.2s}#twe-root .duration-500{transition-duration:.5s}#twe-root .rounded-box-half{border-radius:calc(var(--rounded-box) / 2)}#twe-root .table-border-bc :where(thead,tbody) :where(tr:not(:last-child)),#twe-root .table-border-bc :where(thead,tbody) :where(tr:first-child:last-child){--tw-border-opacity: 20%;border-bottom-width:1px;border-bottom-color:var(--fallback-bc, oklch(var(--bc) / var(--tw-border-opacity)))}#twe-root .table-padding-sm :where(th,td){padding:8px 12px}#twe-root .no-scrollbar::-webkit-scrollbar{display:none}#twe-root .no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}#twe-root .before\\:max-w-max:before{content:var(--tw-content);max-width:-moz-max-content;max-width:max-content}#twe-root .before\\:whitespace-pre-line:before{content:var(--tw-content);white-space:pre-line}#twe-root .hover\\:bg-base-200:hover{--tw-bg-opacity: 1;background-color:var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)))}#twe-root .group:hover .group-hover\\:translate-x-\\[5px\\]{--tw-translate-x: 5px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#twe-root .group:hover .group-hover\\:rotate-\\[20deg\\]{--tw-rotate: 20deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#twe-root .group:hover .group-hover\\:opacity-90{opacity:.9}@media (min-width: 640px){#twe-root .sm\\:max-w-screen-sm{max-width:640px}}@media (min-width: 768px){#twe-root .md\\:max-w-screen-md{max-width:768px}#twe-root .md\\:max-w-screen-sm{max-width:640px}}#twe-root .\\[\\&\\>path\\]\\:stroke-0>path{stroke-width:0} `);

(function (preact, hooks, signals, dayjs, tableCore) {
  'use strict';

  var __defProp = Object.defineProperty;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __publicField = (obj, key, value) => {
    __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
    return value;
  };
  var defaultAttributes = {
    xmlns: "http://www.w3.org/2000/svg",
    width: 24,
    height: 24,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    "stroke-width": 2,
    "stroke-linecap": "round",
    "stroke-linejoin": "round"
  };
  var __defProp2 = Object.defineProperty;
  var __defProps = Object.defineProperties;
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
  var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __spreadValues = (a, b) => {
    for (var prop in b || (b = {}))
      if (__hasOwnProp.call(b, prop))
        __defNormalProp2(a, prop, b[prop]);
    if (__getOwnPropSymbols)
      for (var prop of __getOwnPropSymbols(b)) {
        if (__propIsEnum.call(b, prop))
          __defNormalProp2(a, prop, b[prop]);
      }
    return a;
  };
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  var __objRest = (source, exclude) => {
    var target = {};
    for (var prop in source)
      if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
        target[prop] = source[prop];
    if (source != null && __getOwnPropSymbols)
      for (var prop of __getOwnPropSymbols(source)) {
        if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
          target[prop] = source[prop];
      }
    return target;
  };
  var createPreactComponent = (iconName, iconNamePascal, iconNode) => {
    const Component2 = (_a) => {
      var _b = _a, { color = "currentColor", size = 24, stroke = 2, children } = _b, rest = __objRest(_b, ["color", "size", "stroke", "children"]);
      return preact.h(
        "svg",
        __spreadValues(__spreadProps(__spreadValues({}, defaultAttributes), {
          width: size,
          height: size,
          stroke: color,
          "stroke-width": stroke,
          class: `tabler-icon tabler-icon-${iconName}`
        }), rest),
        [...iconNode.map(([tag, attrs]) => preact.h(tag, attrs)), ...preact.toChildArray(children)]
      );
    };
    Component2.displayName = `${iconNamePascal}`;
    return Component2;
  };
  var IconArrowUpRight = createPreactComponent("arrow-up-right", "IconArrowUpRight", [
    ["path", { d: "M17 7l-10 10", key: "svg-0" }],
    ["path", { d: "M8 7l9 0l0 9", key: "svg-1" }]
  ]);
  var IconBrandGithubFilled = createPreactComponent(
    "brand-github-filled",
    "IconBrandGithubFilled",
    [
      [
        "path",
        {
          d: "M5.315 2.1c.791 -.113 1.9 .145 3.333 .966l.272 .161l.16 .1l.397 -.083a13.3 13.3 0 0 1 4.59 -.08l.456 .08l.396 .083l.161 -.1c1.385 -.84 2.487 -1.17 3.322 -1.148l.164 .008l.147 .017l.076 .014l.05 .011l.144 .047a1 1 0 0 1 .53 .514a5.2 5.2 0 0 1 .397 2.91l-.047 .267l-.046 .196l.123 .163c.574 .795 .93 1.728 1.03 2.707l.023 .295l.007 .272c0 3.855 -1.659 5.883 -4.644 6.68l-.245 .061l-.132 .029l.014 .161l.008 .157l.004 .365l-.002 .213l-.003 3.834a1 1 0 0 1 -.883 .993l-.117 .007h-6a1 1 0 0 1 -.993 -.883l-.007 -.117v-.734c-1.818 .26 -3.03 -.424 -4.11 -1.878l-.535 -.766c-.28 -.396 -.455 -.579 -.589 -.644l-.048 -.019a1 1 0 0 1 .564 -1.918c.642 .188 1.074 .568 1.57 1.239l.538 .769c.76 1.079 1.36 1.459 2.609 1.191l.001 -.678l-.018 -.168a5.03 5.03 0 0 1 -.021 -.824l.017 -.185l.019 -.12l-.108 -.024c-2.976 -.71 -4.703 -2.573 -4.875 -6.139l-.01 -.31l-.004 -.292a5.6 5.6 0 0 1 .908 -3.051l.152 -.222l.122 -.163l-.045 -.196a5.2 5.2 0 0 1 .145 -2.642l.1 -.282l.106 -.253a1 1 0 0 1 .529 -.514l.144 -.047l.154 -.03z",
          fill: "currentColor",
          key: "svg-0",
          strokeWidth: "0"
        }
      ]
    ]
  );
  var IconChevronLeftPipe = createPreactComponent(
    "chevron-left-pipe",
    "IconChevronLeftPipe",
    [
      ["path", { d: "M7 6v12", key: "svg-0" }],
      ["path", { d: "M18 6l-6 6l6 6", key: "svg-1" }]
    ]
  );
  var IconChevronLeft = createPreactComponent("chevron-left", "IconChevronLeft", [
    ["path", { d: "M15 6l-6 6l6 6", key: "svg-0" }]
  ]);
  var IconChevronRightPipe = createPreactComponent(
    "chevron-right-pipe",
    "IconChevronRightPipe",
    [
      ["path", { d: "M6 6l6 6l-6 6", key: "svg-0" }],
      ["path", { d: "M17 5v13", key: "svg-1" }]
    ]
  );
  var IconChevronRight = createPreactComponent("chevron-right", "IconChevronRight", [
    ["path", { d: "M9 6l6 6l-6 6", key: "svg-0" }]
  ]);
  var IconCircleCheck = createPreactComponent("circle-check", "IconCircleCheck", [
    ["path", { d: "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", key: "svg-0" }],
    ["path", { d: "M9 12l2 2l4 -4", key: "svg-1" }]
  ]);
  var IconCircleDashed = createPreactComponent("circle-dashed", "IconCircleDashed", [
    ["path", { d: "M8.56 3.69a9 9 0 0 0 -2.92 1.95", key: "svg-0" }],
    ["path", { d: "M3.69 8.56a9 9 0 0 0 -.69 3.44", key: "svg-1" }],
    ["path", { d: "M3.69 15.44a9 9 0 0 0 1.95 2.92", key: "svg-2" }],
    ["path", { d: "M8.56 20.31a9 9 0 0 0 3.44 .69", key: "svg-3" }],
    ["path", { d: "M15.44 20.31a9 9 0 0 0 2.92 -1.95", key: "svg-4" }],
    ["path", { d: "M20.31 15.44a9 9 0 0 0 .69 -3.44", key: "svg-5" }],
    ["path", { d: "M20.31 8.56a9 9 0 0 0 -1.95 -2.92", key: "svg-6" }],
    ["path", { d: "M15.44 3.69a9 9 0 0 0 -3.44 -.69", key: "svg-7" }]
  ]);
  var IconExclamationCircle = createPreactComponent(
    "exclamation-circle",
    "IconExclamationCircle",
    [
      ["path", { d: "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", key: "svg-0" }],
      ["path", { d: "M12 9v4", key: "svg-1" }],
      ["path", { d: "M12 16v.01", key: "svg-2" }]
    ]
  );
  var IconHelp = createPreactComponent("help", "IconHelp", [
    ["path", { d: "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", key: "svg-0" }],
    ["path", { d: "M12 17l0 .01", key: "svg-1" }],
    [
      "path",
      { d: "M12 13.5a1.5 1.5 0 0 1 1 -1.5a2.6 2.6 0 1 0 -3 -4", key: "svg-2" }
    ]
  ]);
  var IconInfoCircle = createPreactComponent("info-circle", "IconInfoCircle", [
    ["path", { d: "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", key: "svg-0" }],
    ["path", { d: "M12 9h.01", key: "svg-1" }],
    ["path", { d: "M11 12h1v4h1", key: "svg-2" }]
  ]);
  var IconLink = createPreactComponent("link", "IconLink", [
    ["path", { d: "M9 15l6 -6", key: "svg-0" }],
    [
      "path",
      { d: "M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464", key: "svg-1" }
    ],
    [
      "path",
      {
        d: "M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463",
        key: "svg-2"
      }
    ]
  ]);
  var IconSearch = createPreactComponent("search", "IconSearch", [
    ["path", { d: "M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0", key: "svg-0" }],
    ["path", { d: "M21 21l-6 -6", key: "svg-1" }]
  ]);
  var IconSettings = createPreactComponent("settings", "IconSettings", [
    [
      "path",
      {
        d: "M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z",
        key: "svg-0"
      }
    ],
    ["path", { d: "M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0", key: "svg-1" }]
  ]);
  var IconSortAscending = createPreactComponent("sort-ascending", "IconSortAscending", [
    ["path", { d: "M4 6l7 0", key: "svg-0" }],
    ["path", { d: "M4 12l7 0", key: "svg-1" }],
    ["path", { d: "M4 18l9 0", key: "svg-2" }],
    ["path", { d: "M15 9l3 -3l3 3", key: "svg-3" }],
    ["path", { d: "M18 6l0 12", key: "svg-4" }]
  ]);
  var IconSortDescending = createPreactComponent("sort-descending", "IconSortDescending", [
    ["path", { d: "M4 6l9 0", key: "svg-0" }],
    ["path", { d: "M4 12l7 0", key: "svg-1" }],
    ["path", { d: "M4 18l7 0", key: "svg-2" }],
    ["path", { d: "M15 15l3 3l3 -3", key: "svg-3" }],
    ["path", { d: "M18 6l0 12", key: "svg-4" }]
  ]);
  var IconX = createPreactComponent("x", "IconX", [
    ["path", { d: "M18 6l-12 12", key: "svg-0" }],
    ["path", { d: "M6 6l12 12", key: "svg-1" }]
  ]);
  const logLinesSignal = signals.signal([]);
  class Logger {
    constructor() {
      __publicField(this, "index", 0);
      __publicField(this, "buffer", []);
      __publicField(this, "bufferTimer", null);
    }
    info(line, ...args) {
      console.info("[twitter-web-exporter]", line, ...args);
      this.writeBuffer({
        type: "info",
        line,
        index: this.index++
      });
    }
    warn(line, ...args) {
      console.warn("[twitter-web-exporter]", line, ...args);
      this.writeBuffer({
        type: "warn",
        line,
        index: this.index++
      });
    }
    error(line, ...args) {
      console.error("[twitter-web-exporter]", line, ...args);
      this.writeBuffer({
        type: "error",
        line,
        index: this.index++
      });
    }
    errorWithBanner(msg, err, ...args) {
      this.error(`${msg} (Message: ${(err == null ? void 0 : err.message) ?? "none"})
  This may be a problem caused by Twitter updates.
  Please file an issue on GitHub:
  https://github.com/prinsss/twitter-web-exporter/issues`, ...args);
    }
    debug(...args) {
      console.debug("[twitter-web-exporter]", ...args);
    }
    /**
     * Buffer log lines to reduce the number of signal and DOM updates.
     */
    writeBuffer(log) {
      this.buffer.push(log);
      if (this.bufferTimer) {
        clearTimeout(this.bufferTimer);
      }
      this.bufferTimer = window.setTimeout(() => {
        this.bufferTimer = null;
        this.flushBuffer();
      }, 0);
    }
    /**
     * Flush buffered log lines and update the UI.
     */
    flushBuffer() {
      logLinesSignal.value = [...logLinesSignal.value, ...this.buffer];
      this.buffer = [];
    }
  }
  const logger = new Logger();
  var f = 0;
  function u(e, t, n, o, i, u2) {
    var a, c, p = {};
    for (c in t)
      "ref" == c ? a = t[c] : p[c] = t[c];
    var l = { type: e, props: p, key: n, ref: a, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: --f, __i: -1, __u: 0, __source: i, __self: u2 };
    if ("function" == typeof e && (a = e.defaultProps))
      for (c in a)
        void 0 === p[c] && (p[c] = a[c]);
    return preact.options.vnode && preact.options.vnode(l), l;
  }
  class ErrorBoundary extends preact.Component {
    constructor() {
      super(...arguments);
      __publicField(this, "state", {
        error: null
      });
    }
    static getDerivedStateFromError(err) {
      return {
        error: err.message
      };
    }
    componentDidCatch(err) {
      logger.error(err.message, err);
      this.setState({
        error: err.message
      });
    }
    render() {
      if (this.state.error) {
        return u("div", {
          class: "alert alert-error p-2",
          children: [u(IconExclamationCircle, {}), u("div", {
            children: [u("h3", {
              class: "font-bold leading-normal",
              children: "Something went wrong."
            }), u("p", {
              class: "text-xs",
              children: ["Error: ", this.state.error]
            })]
          })]
        });
      }
      return this.props.children;
    }
  }
  function safeJSONParse(text) {
    try {
      return JSON.parse(text);
    } catch (e) {
      logger.error(e.message);
      return null;
    }
  }
  function useSignal(value) {
    return hooks.useMemo(() => signals.signal(value), []);
  }
  function useSignalState(value) {
    const signal2 = useSignal(value);
    const updateSignal = (newValue) => {
      signal2.value = newValue;
    };
    return [signal2.value, updateSignal, signal2];
  }
  function useToggle(defaultValue = false) {
    const signal2 = useSignal(defaultValue);
    const toggle = () => {
      signal2.value = !signal2.value;
    };
    return [signal2.value, toggle, signal2];
  }
  function cx(...classNames) {
    return classNames.filter(Boolean).join(" ");
  }
  function isEqual(obj1, obj2) {
    return JSON.stringify(obj1) === JSON.stringify(obj2);
  }
  function capitalizeFirstLetter(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
  function xssFilter(str) {
    return str.replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  }
  function strEntitiesToHTML(str, urls) {
    let temp = str;
    if (!(urls == null ? void 0 : urls.length)) {
      return temp;
    }
    for (const {
      url,
      display_url,
      expanded_url
    } of urls) {
      temp = temp.replaceAll(url, `<a class="link" target="_blank" href="${xssFilter(expanded_url)}">${xssFilter(display_url)}</a>`);
    }
    return temp;
  }
  function parseTwitterDateTime(str) {
    const trimmed = str.replace(/^\w+ (.*)$/, "$1");
    return dayjs(trimmed, "MMM DD HH:mm:ss ZZ YYYY", "en");
  }
  function formatDateTime(date, format) {
    if (typeof date === "number" || typeof date === "string") {
      date = dayjs(date);
    }
    return date.format(format);
  }
  function formatVideoDuration(durationInMs) {
    if (typeof durationInMs !== "number" || Number.isNaN(durationInMs)) {
      return "N/A";
    }
    const durationInSeconds = Math.floor(durationInMs / 1e3);
    const minutes = Math.floor(durationInSeconds / 60);
    const seconds = durationInSeconds % 60;
    return `${minutes}:${seconds.toString().padStart(2, "0")}`;
  }
  function ExtensionPanel({
    title,
    description: description2,
    children,
    onClick,
    active,
    indicatorColor = "bg-secondary"
  }) {
    return u("section", {
      class: "module-panel",
      children: [u("div", {
        class: "h-12 flex items-center justify-start",
        children: [u("div", {
          class: "relative flex h-4 w-4 mr-3 shrink-0",
          children: [active && u("span", {
            class: cx("animate-ping absolute inline-flex h-full w-full rounded-full opacity-75", indicatorColor)
          }), u("span", {
            class: cx("relative inline-flex rounded-full h-4 w-4", indicatorColor)
          })]
        }), u("div", {
          class: "flex flex-col flex-grow",
          children: [u("p", {
            class: "text-base m-0 font-medium leading-none",
            children: title
          }), u("p", {
            class: "text-sm text-base-content leading-5 text-opacity-70 m-0",
            children: description2
          })]
        }), u("button", {
          class: "btn btn-sm p-0 w-9 h-9",
          onClick,
          children: u(IconArrowUpRight, {})
        })]
      }), children]
    });
  }
  function Modal({
    show,
    onClose,
    title,
    children,
    class: className = "max-w-4xl md:max-w-screen-md sm:max-w-screen-sm"
  }) {
    if (!show) {
      return u("dialog", {
        class: "modal"
      });
    }
    return u("dialog", {
      class: "modal modal-open",
      open: true,
      children: [u("div", {
        class: cx("modal-box p-3 flex flex-col", className),
        children: [u("header", {
          class: "flex items-center h-9 mb-2",
          children: [u("div", {
            onClick: onClose,
            class: "w-9 h-9 mr-2 cursor-pointer flex justify-center items-center transition-colors duration-200 rounded-full hover:bg-base-200",
            children: u(IconX, {})
          }), u("h2", {
            class: "leading-none text-xl m-0 font-semibold",
            children: title
          })]
        }), u(ErrorBoundary, {
          children
        })]
      }), u("form", {
        method: "dialog",
        class: "modal-backdrop",
        children: u("div", {
          onClick: onClose
        })
      })]
    });
  }
  function SearchArea({
    defaultValue,
    onChange
  }) {
    const inputRef = hooks.useRef(null);
    return u("div", {
      class: "join justify-end my-[2px] w-full max-w-xs absolute top-3 right-3",
      children: [u("input", {
        ref: inputRef,
        type: "text",
        class: "input input-bordered input-sm join-item",
        placeholder: "Search...",
        defaultValue,
        onKeyDown: (e) => {
          var _a;
          if (e.key === "Enter") {
            onChange(((_a = inputRef.current) == null ? void 0 : _a.value) ?? "");
          }
        }
      }), u("button", {
        class: "btn btn-sm join-item",
        onClick: () => {
          var _a;
          return onChange(((_a = inputRef.current) == null ? void 0 : _a.value) ?? "");
        },
        children: u(IconSearch, {
          size: 20
        })
      })]
    });
  }
  /**
   * @license
   * Credit: https://icooon-mono.com/12776-%e7%8c%ab%e3%81%ae%e7%84%a1%e6%96%99%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b32/
   */
  const CatIcon = () => u("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 512 512",
    class: "w-full h-full select-none",
    children: u("g", {
      children: u("path", {
        d: "M461.814,197.514c-2.999-11.335-14.624-18.093-25.958-15.094c-1.866,0.553-13.477,3.649-26.042,14.341 c-6.234,5.349-12.633,12.751-17.361,22.454c-4.748,9.69-7.685,21.577-7.657,35.033c0.013,16.345,4.133,34.895,13.442,56.257 c6.282,14.403,9.144,29.697,9.144,44.846c0.062,25.627-8.438,50.756-21.121,68.283c-6.296,8.777-13.546,15.606-20.816,20.022 c-2.986,1.81-5.943,3.131-8.888,4.181l0.989-5.854c-0.055-17.03-4.05-34.84-13.021-50.528 c-28.356-49.643-66.223-134.741-66.223-134.741l-1.527-4.879c29.47-7.796,58.579-23.408,73.148-54.985 c38.931-84.344-41.08-142.73-41.08-142.73s-25.958-56.222-38.924-54.06c-12.978,2.164-41.094,38.931-41.094,38.931h-23.788h-23.788 c0,0-28.108-36.767-41.08-38.931c-12.979-2.163-38.924,54.06-38.924,54.06s-80.018,58.386-41.087,142.73 c13.822,29.953,40.741,45.572,68.634,53.748l-2.951,9.662c0,0-31.908,81.552-60.279,131.195C37.198,441.092,58.478,512,97.477,512 c29.47,0,79.14,0,101.692,0c7.292,0,11.763,0,11.763,0c22.544,0,72.222,0,101.691,0c12.654,0,23.38-7.547,31.204-19.324 c15.826-0.013,30.81-4.872,43.707-12.758c19.455-11.915,34.708-30.32,45.434-51.896c10.685-21.618,16.856-46.636,16.878-72.672 c0-20.484-3.885-41.619-12.682-61.813c-7.561-17.34-9.918-30.216-9.904-39.29c0.028-7.526,1.5-12.544,3.359-16.414 c1.417-2.889,3.124-5.17,4.983-7.091c2.771-2.868,5.964-4.879,8.349-6.054c1.182-0.595,2.135-0.968,2.674-1.162l0.449-0.152 l-0.007-0.028C458.179,220.189,464.779,208.724,461.814,197.514z"
      })
    })
  });
  var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  const name = "twitter-web-exporter";
  const description = "Export tweets, bookmarks, lists and much more from Twitter(X) web app.";
  const version = "1.0.10";
  const author = "prin <[email protected]>";
  const license = "MIT";
  const homepage = "https://github.com/prinsss/twitter-web-exporter";
  const bugs = "https://github.com/prinsss/twitter-web-exporter/issues";
  const type = "module";
  const scripts = {
    dev: "vite",
    build: "tsc && vite build",
    prepare: "husky install",
    lint: "eslint --ignore-pattern dist --ext .ts,.tsx .",
    commitlint: "commitlint --edit",
    changelog: "git-cliff -o CHANGELOG.md",
    preview: "vite preview"
  };
  const dependencies = {
    "@preact/signals": "1.2.2",
    "@preact/signals-core": "1.5.1",
    "@tabler/icons-preact": "2.44.0",
    "@tanstack/table-core": "8.11.2",
    dayjs: "1.11.10",
    "file-saver": "2.0.5",
    preact: "10.19.3"
  };
  const devDependencies = {
    "@commitlint/cli": "^18.4.4",
    "@commitlint/config-conventional": "^18.4.4",
    "@preact/preset-vite": "^2.7.0",
    "@types/file-saver": "^2.0.7",
    "@types/node": "^20",
    "@typescript-eslint/eslint-plugin": "^6.17.0",
    "@typescript-eslint/parser": "^6.17.0",
    autoprefixer: "^10.4.16",
    daisyui: "^4.4.24",
    eslint: "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.2",
    "git-cliff": "^1.4.0",
    husky: "^8.0.3",
    "postcss-prefix-selector": "^1.16.0",
    "postcss-rem-to-pixel-next": "^5.0.3",
    tailwindcss: "^3.4.0",
    typescript: "^5.3.3",
    vite: "^5.0.10",
    "vite-plugin-monkey": "^3.5.1"
  };
  const packageJson = {
    name,
    description,
    version,
    author,
    license,
    homepage,
    bugs,
    "private": true,
    type,
    scripts,
    dependencies,
    devDependencies
  };
  const DEFAULT_APP_OPTIONS = {
    theme: "system",
    debug: false,
    showControlPanel: true,
    disabledExtensions: [],
    dateTimeFormat: "YYYY-MM-DD HH:mm:ss Z",
    version: packageJson.version
  };
  const THEMES = ["system", "cupcake", "dark", "emerald", "cyberpunk", "valentine", "lofi", "dracula", "cmyk", "business", "winter"];
  const LOCAL_STORAGE_KEY = packageJson.name;
  class AppOptionsManager {
    constructor() {
      __publicField(this, "appOptions", {
        ...DEFAULT_APP_OPTIONS
      });
      __publicField(this, "previous", {
        ...DEFAULT_APP_OPTIONS
      });
      /**
       * Signal for subscribing to option changes.
       */
      __publicField(this, "signal", new signals.Signal(0));
      this.loadAppOptions();
    }
    get(key, defaultValue) {
      return this.appOptions[key] ?? defaultValue;
    }
    set(key, value) {
      this.appOptions[key] = value;
      this.saveAppOptions();
    }
    /**
     * Read app options from local storage.
     */
    loadAppOptions() {
      this.appOptions = {
        ...this.appOptions,
        ...safeJSONParse(localStorage.getItem(LOCAL_STORAGE_KEY) || "{}")
      };
      this.previous = {
        ...this.appOptions
      };
      logger.info("App options loaded", this.appOptions);
      this.signal.value++;
    }
    /**
     * Write app options to local storage.
     */
    saveAppOptions() {
      const oldValue = this.previous;
      const newValue = {
        ...this.appOptions,
        version: packageJson.version
      };
      if (isEqual(oldValue, newValue)) {
        return;
      }
      this.appOptions = newValue;
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.appOptions));
      this.previous = {
        ...this.appOptions
      };
      logger.debug("App options saved", this.appOptions);
      this.signal.value++;
    }
  }
  const appOptionsManager = new AppOptionsManager();
  const xhrOpen = _unsafeWindow.XMLHttpRequest.prototype.open;
  class ExtensionManager {
    constructor() {
      __publicField(this, "extensions", /* @__PURE__ */ new Map());
      __publicField(this, "disabledExtensions", /* @__PURE__ */ new Set());
      __publicField(this, "debugEnabled", false);
      /**
       * Signal for subscribing to extension changes.
       */
      __publicField(this, "signal", new signals.Signal(1));
      this.installHttpHooks();
      this.disabledExtensions = new Set(appOptionsManager.get("disabledExtensions", []));
      if (appOptionsManager.get("debug")) {
        this.debugEnabled = true;
        logger.info("Debug mode enabled");
      }
    }
    /**
     * Register and instantiate a new extension.
     *
     * @param ctor Extension constructor.
     */
    add(ctor) {
      try {
        logger.debug(`Register new extension: ${ctor.name}`);
        const instance = new ctor(this);
        this.extensions.set(instance.name, instance);
      } catch (err) {
        logger.error(`Failed to register extension: ${ctor.name}`, err);
      }
    }
    /**
     * Set up all enabled extensions.
     */
    start() {
      for (const ext of this.extensions.values()) {
        if (this.disabledExtensions.has(ext.name)) {
          this.disable(ext.name);
        } else {
          this.enable(ext.name);
        }
      }
    }
    enable(name2) {
      try {
        this.disabledExtensions.delete(name2);
        appOptionsManager.set("disabledExtensions", [...this.disabledExtensions]);
        const ext = this.extensions.get(name2);
        ext.enabled = true;
        ext.setup();
        logger.debug(`Enabled extension: ${name2}`);
        this.signal.value++;
      } catch (err) {
        logger.error(`Failed to enable extension: ${name2}`, err);
      }
    }
    disable(name2) {
      try {
        this.disabledExtensions.add(name2);
        appOptionsManager.set("disabledExtensions", [...this.disabledExtensions]);
        const ext = this.extensions.get(name2);
        ext.enabled = false;
        ext.dispose();
        logger.debug(`Disabled extension: ${name2}`);
        this.signal.value++;
      } catch (err) {
        logger.error(`Failed to disable extension: ${name2}`, err);
      }
    }
    getExtensions() {
      return [...this.extensions.values()];
    }
    /**
     * Here we hooks the browser's XHR method to intercept Twitter's Web API calls.
     * This need to be done before any XHR request is made.
     */
    installHttpHooks() {
      const manager = this;
      _unsafeWindow.XMLHttpRequest.prototype.open = function(method, url) {
        if (manager.debugEnabled) {
          logger.debug(`XHR initialized`, {
            method,
            url
          });
        }
        const interceptors = manager.getExtensions().filter((ext) => ext.enabled).map((ext) => ext.intercept()).filter((int) => typeof int === "function");
        this.addEventListener("load", () => {
          if (manager.debugEnabled) {
            logger.debug(`XHR finished`, {
              method,
              url,
              interceptors
            });
          }
          interceptors.forEach((func) => {
            func({
              method,
              url
            }, this);
          });
        });
        xhrOpen.apply(this, arguments);
      };
      logger.info("Hooked into XMLHttpRequest");
    }
  }
  class Extension {
    constructor(manager) {
      __publicField(this, "name", "");
      __publicField(this, "enabled", true);
      __publicField(this, "manager");
      this.manager = manager;
    }
    /**
     * Optionally run side effects when enabled.
     */
    setup() {
    }
    /**
     * Optionally clear side effects when disabled.
     */
    dispose() {
    }
    /**
     * Intercept HTTP responses.
     */
    intercept() {
      return null;
    }
    /**
     * Render extension UI.
     */
    render() {
      return null;
    }
  }
  const extensionManager = new ExtensionManager();
  function Settings() {
    const currentTheme = useSignal(appOptionsManager.get("theme"));
    const [showSettings, toggleSettings] = useToggle(false);
    const styles = {
      subtitle: "mb-2 text-base-content ml-4 opacity-50 font-semibold text-xs",
      block: "text-sm mb-2 w-full flex px-4 py-2 text-base-content bg-base-200 rounded-box justify-between",
      item: "label cursor-pointer flex justify-between h-8 items-center p-0"
    };
    return u(preact.Fragment, {
      children: [u("div", {
        onClick: toggleSettings,
        class: "w-9 h-9 mr-2 cursor-pointer flex justify-center items-center transition-colors duration-200 rounded-full hover:bg-base-200",
        children: u(IconSettings, {})
      }), u(Modal, {
        title: "Settings",
        show: showSettings,
        onClose: toggleSettings,
        class: "max-w-lg",
        children: [u("p", {
          class: styles.subtitle,
          children: "General"
        }), u("div", {
          class: cx(styles.block, "flex-col"),
          children: [u("label", {
            class: styles.item,
            children: [u("span", {
              class: "label-text",
              children: "Theme"
            }), u("select", {
              class: "select select-xs",
              onChange: (e) => {
                var _a;
                currentTheme.value = ((_a = e.target) == null ? void 0 : _a.value) ?? DEFAULT_APP_OPTIONS.theme;
                appOptionsManager.set("theme", currentTheme.value);
              },
              children: THEMES.map((theme) => u("option", {
                value: theme,
                selected: currentTheme.value === theme,
                children: capitalizeFirstLetter(theme)
              }, theme))
            })]
          }), u("label", {
            class: styles.item,
            children: [u("span", {
              class: "label-text",
              children: "Debug"
            }), u("input", {
              type: "checkbox",
              class: "toggle toggle-primary",
              checked: appOptionsManager.get("debug"),
              onChange: (e) => {
                var _a;
                appOptionsManager.set("debug", (_a = e.target) == null ? void 0 : _a.checked);
              }
            })]
          }), u("label", {
            class: styles.item,
            children: [u("div", {
              class: "flex items-center",
              children: [u("span", {
                class: "label-text",
                children: "Date Time Format"
              }), u("a", {
                href: "https://day.js.org/docs/en/display/format",
                target: "_blank",
                rel: "noopener noreferrer",
                class: "tooltip tooltip-bottom ml-0.5 before:whitespace-pre-line before:max-w-max",
                "data-tip": "Click for more information.\nThis will take effect on both\n previewer and exported files.",
                children: u(IconHelp, {
                  size: 20
                })
              })]
            }), u("input", {
              type: "text",
              class: "input input-bordered input-xs w-48",
              value: appOptionsManager.get("dateTimeFormat"),
              onChange: (e) => {
                var _a;
                appOptionsManager.set("dateTimeFormat", (_a = e.target) == null ? void 0 : _a.value);
              }
            })]
          })]
        }), u("p", {
          class: styles.subtitle,
          children: "Modules"
        }), u("div", {
          class: cx(styles.block, "flex-col"),
          children: extensionManager.getExtensions().map((extension) => u("label", {
            class: styles.item,
            children: [u("span", {
              children: extension.name
            }), u("input", {
              type: "checkbox",
              class: "toggle toggle-secondary",
              checked: extension.enabled,
              onChange: () => {
                extension.enabled ? extensionManager.disable(extension.name) : extensionManager.enable(extension.name);
              }
            })]
          }, extension.name))
        }), u("p", {
          class: styles.subtitle,
          children: "About"
        }), u("div", {
          class: styles.block,
          children: [u("span", {
            class: "label-text",
            children: ["Version ", packageJson.version]
          }), u("a", {
            class: "btn btn-xs btn-ghost",
            target: "_blank",
            href: packageJson.homepage,
            children: [u(IconBrandGithubFilled, {
              class: "[&>path]:stroke-0"
            }), "GitHub"]
          })]
        })]
      })]
    });
  }
  function App() {
    const extensions = useSignal([]);
    const currentTheme = useSignal(appOptionsManager.get("theme"));
    const showControlPanel = useSignal(appOptionsManager.get("showControlPanel"));
    const toggleControlPanel = () => {
      showControlPanel.value = !showControlPanel.value;
      appOptionsManager.set("showControlPanel", showControlPanel.value);
    };
    hooks.useEffect(() => {
      extensionManager.signal.subscribe(() => {
        extensions.value = extensionManager.getExtensions();
      });
      appOptionsManager.signal.subscribe(() => {
        currentTheme.value = appOptionsManager.get("theme");
      });
      logger.debug("App useEffect executed");
    }, []);
    return u(preact.Fragment, {
      children: [u("div", {
        onClick: toggleControlPanel,
        "data-theme": currentTheme.value,
        class: "group w-12 h-12 fixed top-[60%] left-[-20px] cursor-pointer bg-transparent fill-base-content",
        children: u("div", {
          class: "w-full h-full origin origin-[bottom_center] transition-all duration-200 group-hover:translate-x-[5px] group-hover:rotate-[20deg] opacity-50 group-hover:opacity-90",
          children: u(CatIcon, {})
        })
      }), u("section", {
        "data-theme": currentTheme.value,
        class: cx("card card-compact bg-base-100 fixed border shadow-xl w-80 leading-loose text-base-content px-4 py-3 rounded-box border-solid border-neutral-content border-opacity-50 left-8 top-8 transition-transform duration-500", showControlPanel.value ? "translate-x-0 transform-none" : "translate-x-[-500px]"),
        children: [u("header", {
          class: "flex items-center h-9",
          children: [u("h2", {
            class: "font-semibold leading-none text-xl m-0 flex-grow",
            children: "Web Exporter (α)"
          }), u(ErrorBoundary, {
            children: u(Settings, {})
          }), u("div", {
            onClick: toggleControlPanel,
            class: "w-9 h-9 cursor-pointer flex justify-center items-center transition-colors duration-200 rounded-full hover:bg-base-200",
            children: u(IconX, {})
          })]
        }), u("p", {
          class: "text-sm text-base-content text-opacity-70 mb-1 leading-none",
          children: "Refresh or clear to start new captures."
        }), u("div", {
          class: "divider mt-0 mb-0"
        }), u("main", {
          children: extensions.value.map((ext) => {
            const Component2 = ext.render();
            if (ext.enabled && Component2) {
              return u(ErrorBoundary, {
                children: u(Component2, {}, ext.name)
              });
            }
            return null;
          })
        })]
      })]
    });
  }
  const EXPORT_FORMAT = {
    JSON: "JSON",
    HTML: "HTML",
    CSV: "CSV"
  };
  function csvEscapeStr(str) {
    return `"${str.replace(/"/g, '""').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
  }
  function saveFile(filename, content, prependBOM = false) {
    const link = document.createElement("a");
    const blob = new Blob(prependBOM ? [new Uint8Array([239, 187, 191]), content] : [content], {
      type: "text/plain;charset=utf-8"
    });
    const url = URL.createObjectURL(blob);
    link.href = url;
    link.download = filename;
    link.click();
    URL.revokeObjectURL(url);
  }
  async function exportData(data, format, filename) {
    try {
      let content = "";
      let prependBOM = false;
      logger.info(`Exporting to ${format} file: ${filename}`);
      switch (format) {
        case EXPORT_FORMAT.JSON:
          content = await jsonExporter(data);
          break;
        case EXPORT_FORMAT.HTML:
          content = await htmlExporter(data);
          break;
        case EXPORT_FORMAT.CSV:
          prependBOM = true;
          content = await csvExporter(data);
          break;
      }
      saveFile(filename, content, prependBOM);
    } catch (err) {
      logger.errorWithBanner("Failed to export file", err);
    }
  }
  async function jsonExporter(data) {
    return JSON.stringify(data, void 0, "  ");
  }
  async function htmlExporter(data) {
    const table = document.createElement("table");
    const thead = document.createElement("thead");
    const tbody = document.createElement("tbody");
    const headers = Object.keys(data[0] ?? {});
    const headerRow = document.createElement("tr");
    for (const header of headers) {
      const th = document.createElement("th");
      th.textContent = header;
      headerRow.appendChild(th);
    }
    thead.appendChild(headerRow);
    table.appendChild(thead);
    table.className = "table table-striped";
    for (const row of data) {
      const tr = document.createElement("tr");
      for (const header of headers) {
        const td = document.createElement("td");
        const value = row[header];
        if (header === "profile_image_url" || header === "profile_banner_url") {
          const img = document.createElement("img");
          img.src = value;
          img.width = 50;
          td.innerHTML = "";
          td.appendChild(img);
        } else if (header === "media") {
          if ((value == null ? void 0 : value.length) > 0) {
            for (const media of value) {
              const img = document.createElement("img");
              img.src = media.thumbnail;
              img.width = 50;
              const link = document.createElement("a");
              link.href = media.original;
              link.target = "_blank";
              link.style.marginRight = "0.5em";
              link.appendChild(img);
              td.appendChild(link);
            }
          }
        } else if (header === "full_text" || header === "description") {
          const p = document.createElement("p");
          p.innerHTML = value;
          p.style.whiteSpace = "pre-wrap";
          p.style.maxWidth = "640px";
          td.appendChild(p);
        } else if (header === "metadata") {
          const details = document.createElement("details");
          const summary = document.createElement("summary");
          summary.textContent = "Expand";
          details.appendChild(summary);
          const pre = document.createElement("pre");
          pre.textContent = JSON.stringify(value, void 0, "  ");
          details.appendChild(pre);
          td.appendChild(details);
        } else if (header === "url") {
          const link = document.createElement("a");
          link.href = value;
          link.target = "_blank";
          link.textContent = value;
          td.appendChild(link);
        } else {
          td.textContent = typeof value === "string" ? value : JSON.stringify(row[header]);
        }
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    }
    table.appendChild(tbody);
    return `
    <html>
      <head>
        <meta charset="utf-8">
        <title>Exported Data ${(/* @__PURE__ */ new Date()).toISOString()}</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
      </head>
      <body>
        ${table.outerHTML}
      </body>
    </html>
  `;
  }
  async function csvExporter(data) {
    const headers = Object.keys(data[0] ?? {});
    let content = headers.join(",") + "\n";
    for (const row of data) {
      const values = headers.map((header) => {
        const value = row[header];
        if (typeof value === "string") {
          return csvEscapeStr(value);
        }
        if (typeof value === "object") {
          return csvEscapeStr(JSON.stringify(value));
        }
        return value;
      });
      content += values.join(",");
      content += "\n";
    }
    return content;
  }
  function ExportDataModal({
    title,
    table,
    show,
    onClose
  }) {
    const [selectedFormat, setSelectedFormat] = useSignalState(EXPORT_FORMAT.JSON);
    const [loading, setLoading] = useSignalState(false);
    const [includeMetadata, toggleIncludeMetadata] = useToggle(false);
    const [currentProgress, setCurrentProgress] = useSignalState(0);
    const [totalProgress, setTotalProgress] = useSignalState(0);
    const selectedRows = table.getSelectedRowModel().rows;
    const onExport = async () => {
      setLoading(true);
      setTotalProgress(selectedRows.length);
      const allRecords = [];
      for (const row of selectedRows) {
        const allCells = row.getAllCells();
        const record = {};
        for (const cell of allCells) {
          const value = cell.getValue();
          const meta = cell.column.columnDef.meta;
          if ((meta == null ? void 0 : meta.exportable) === false) {
            continue;
          }
          let exportValue = (meta == null ? void 0 : meta.exportValue) ? meta.exportValue(row) : value;
          if (exportValue === void 0) {
            exportValue = null;
          }
          record[(meta == null ? void 0 : meta.exportKey) || cell.column.id] = exportValue;
        }
        if (includeMetadata) {
          record.metadata = row.original;
        }
        allRecords.push(record);
        setCurrentProgress(allRecords.length);
      }
      await exportData(allRecords, selectedFormat, `twitter-${title}-${Date.now()}.${selectedFormat.toLowerCase()}`);
      setLoading(false);
    };
    return u(Modal, {
      class: "max-w-sm md:max-w-screen-sm sm:max-w-screen-sm",
      title: `${title} Data`,
      show,
      onClose,
      children: [u("div", {
        class: "px-4 text-base",
        children: [u("p", {
          class: "text-base-content text-opacity-60 mb-2 leading-5 text-sm",
          children: "Export captured data as JSON/HTML/CSV file. This may take a while depending on the amount of data. The exported file does not include media files such as images and videos but only the URLs."
        }), u("div", {
          class: "flex items-center",
          children: [u("p", {
            class: "mr-2 leading-8",
            children: "Data length:"
          }), u("span", {
            class: "font-mono leading-6 h-6 bg-base-200 px-2 rounded-md",
            children: selectedRows.length
          })]
        }), u("div", {
          class: "flex items-center",
          children: [u("p", {
            class: "mr-2 leading-8",
            children: "Include all metadata:"
          }), u("input", {
            type: "checkbox",
            class: "checkbox checkbox-sm",
            checked: includeMetadata,
            onChange: toggleIncludeMetadata
          })]
        }), u("div", {
          class: "flex",
          children: [u("p", {
            class: "mr-2 leading-8",
            children: "Export as:"
          }), u("select", {
            class: "select select-bordered select-sm w-32",
            onChange: (e) => {
              setSelectedFormat(e.target.value);
            },
            children: Object.values(EXPORT_FORMAT).map((type2) => u("option", {
              selected: type2 === selectedFormat,
              children: type2
            }, type2))
          })]
        }), selectedRows.length > 0 ? null : u("div", {
          class: "flex items-center justify-center h-28 w-full",
          children: u("p", {
            class: "text-base-content text-opacity-50",
            children: "No data selected."
          })
        }), u("div", {
          class: "flex flex-col mt-6",
          children: [u("progress", {
            class: "progress progress-primary w-full",
            value: currentProgress / (totalProgress || 1) * 100,
            max: "100"
          }), u("span", {
            class: "text-sm leading-none mt-2 text-base-content text-opacity-60",
            children: `${currentProgress}/${selectedRows.length}`
          })]
        })]
      }), u("div", {
        class: "flex space-x-2",
        children: [u("span", {
          class: "flex-grow"
        }), u("button", {
          class: "btn",
          onClick: onClose,
          children: "Cancel"
        }), u("button", {
          class: cx("btn btn-primary", loading && "btn-disabled"),
          onClick: onExport,
          children: [loading && u("span", {
            class: "loading loading-spinner"
          }), "Start Export"]
        })]
      })]
    });
  }
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  var FileSaver_min = { exports: {} };
  (function(module, exports) {
    (function(a, b) {
      b();
    })(commonjsGlobal, function() {
      function b(a2, b2) {
        return "undefined" == typeof b2 ? b2 = { autoBom: false } : "object" != typeof b2 && (console.warn("Deprecated: Expected third argument to be a object"), b2 = { autoBom: !b2 }), b2.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a2.type) ? new Blob(["\uFEFF", a2], { type: a2.type }) : a2;
      }
      function c(a2, b2, c2) {
        var d2 = new XMLHttpRequest();
        d2.open("GET", a2), d2.responseType = "blob", d2.onload = function() {
          g(d2.response, b2, c2);
        }, d2.onerror = function() {
          console.error("could not download file");
        }, d2.send();
      }
      function d(a2) {
        var b2 = new XMLHttpRequest();
        b2.open("HEAD", a2, false);
        try {
          b2.send();
        } catch (a3) {
        }
        return 200 <= b2.status && 299 >= b2.status;
      }
      function e(a2) {
        try {
          a2.dispatchEvent(new MouseEvent("click"));
        } catch (c2) {
          var b2 = document.createEvent("MouseEvents");
          b2.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null), a2.dispatchEvent(b2);
        }
      }
      var f2 = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof commonjsGlobal && commonjsGlobal.global === commonjsGlobal ? commonjsGlobal : void 0, a = f2.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent), g = f2.saveAs || ("object" != typeof window || window !== f2 ? function() {
      } : "download" in HTMLAnchorElement.prototype && !a ? function(b2, g2, h2) {
        var i = f2.URL || f2.webkitURL, j = document.createElement("a");
        g2 = g2 || b2.name || "download", j.download = g2, j.rel = "noopener", "string" == typeof b2 ? (j.href = b2, j.origin === location.origin ? e(j) : d(j.href) ? c(b2, g2, h2) : e(j, j.target = "_blank")) : (j.href = i.createObjectURL(b2), setTimeout(function() {
          i.revokeObjectURL(j.href);
        }, 4e4), setTimeout(function() {
          e(j);
        }, 0));
      } : "msSaveOrOpenBlob" in navigator ? function(f3, g2, h2) {
        if (g2 = g2 || f3.name || "download", "string" != typeof f3)
          navigator.msSaveOrOpenBlob(b(f3, h2), g2);
        else if (d(f3))
          c(f3, g2, h2);
        else {
          var i = document.createElement("a");
          i.href = f3, i.target = "_blank", setTimeout(function() {
            e(i);
          });
        }
      } : function(b2, d2, e2, g2) {
        if (g2 = g2 || open("", "_blank"), g2 && (g2.document.title = g2.document.body.innerText = "downloading..."), "string" == typeof b2)
          return c(b2, d2, e2);
        var h2 = "application/octet-stream" === b2.type, i = /constructor/i.test(f2.HTMLElement) || f2.safari, j = /CriOS\/[\d]+/.test(navigator.userAgent);
        if ((j || h2 && i || a) && "undefined" != typeof FileReader) {
          var k = new FileReader();
          k.onloadend = function() {
            var a2 = k.result;
            a2 = j ? a2 : a2.replace(/^data:[^;]*;/, "data:attachment/file;"), g2 ? g2.location.href = a2 : location = a2, g2 = null;
          }, k.readAsDataURL(b2);
        } else {
          var l = f2.URL || f2.webkitURL, m = l.createObjectURL(b2);
          g2 ? g2.location = m : location.href = m, g2 = null, setTimeout(function() {
            l.revokeObjectURL(m);
          }, 4e4);
        }
      });
      f2.saveAs = g.saveAs = g, module.exports = g;
    });
  })(FileSaver_min);
  var FileSaver_minExports = FileSaver_min.exports;
  /**
   * This file zip-stream.ts is copied from StreamSaver.js.
   *
   * @see https://github.com/jimmywarting/StreamSaver.js/blob/master/examples/zip-stream.js
   * @license MIT
   */
  class Crc32 {
    constructor() {
      this.crc = -1;
    }
    append(data) {
      var crc = this.crc | 0;
      var table = this.table;
      for (var offset = 0, len = data.length | 0; offset < len; offset++) {
        crc = crc >>> 8 ^ table[(crc ^ data[offset]) & 255];
      }
      this.crc = crc;
    }
    get() {
      return ~this.crc;
    }
  }
  Crc32.prototype.table = (() => {
    var i;
    var j;
    var t;
    var table = [];
    for (i = 0; i < 256; i++) {
      t = i;
      for (j = 0; j < 8; j++) {
        t = t & 1 ? t >>> 1 ^ 3988292384 : t >>> 1;
      }
      table[i] = t;
    }
    return table;
  })();
  const getDataHelper = (byteLength) => {
    var uint8 = new Uint8Array(byteLength);
    return {
      array: uint8,
      view: new DataView(uint8.buffer)
    };
  };
  const pump = (zipObj) => zipObj.reader.read().then((chunk) => {
    if (chunk.done)
      return zipObj.writeFooter();
    const outputData = chunk.value;
    zipObj.crc.append(outputData);
    zipObj.uncompressedLength += outputData.length;
    zipObj.compressedLength += outputData.length;
    zipObj.ctrl.enqueue(outputData);
  });
  function createWriter(underlyingSource) {
    const files = /* @__PURE__ */ Object.create(null);
    const filenames = [];
    const encoder = new TextEncoder();
    let offset = 0;
    let activeZipIndex = 0;
    let ctrl;
    let activeZipObject, closed;
    function next() {
      activeZipIndex++;
      activeZipObject = files[filenames[activeZipIndex]];
      if (activeZipObject)
        processNextChunk();
      else if (closed)
        closeZip();
    }
    var zipWriter = {
      enqueue(fileLike) {
        if (closed)
          throw new TypeError("Cannot enqueue a chunk into a readable stream that is closed or has been requested to be closed");
        let name2 = fileLike.name.trim();
        const date = new Date(typeof fileLike.lastModified === "undefined" ? Date.now() : fileLike.lastModified);
        if (fileLike.directory && !name2.endsWith("/"))
          name2 += "/";
        if (files[name2])
          throw new Error("File already exists.");
        const nameBuf = encoder.encode(name2);
        filenames.push(name2);
        const zipObject = files[name2] = {
          level: 0,
          ctrl,
          directory: !!fileLike.directory,
          nameBuf,
          comment: encoder.encode(fileLike.comment || ""),
          compressedLength: 0,
          uncompressedLength: 0,
          writeHeader() {
            var header = getDataHelper(26);
            var data = getDataHelper(30 + nameBuf.length);
            zipObject.offset = offset;
            zipObject.header = header;
            if (zipObject.level !== 0 && !zipObject.directory) {
              header.view.setUint16(4, 2048);
            }
            header.view.setUint32(0, 335546376);
            header.view.setUint16(6, (date.getHours() << 6 | date.getMinutes()) << 5 | date.getSeconds() / 2, true);
            header.view.setUint16(8, (date.getFullYear() - 1980 << 4 | date.getMonth() + 1) << 5 | date.getDate(), true);
            header.view.setUint16(22, nameBuf.length, true);
            data.view.setUint32(0, 1347093252);
            data.array.set(header.array, 4);
            data.array.set(nameBuf, 30);
            offset += data.array.length;
            ctrl.enqueue(data.array);
          },
          writeFooter() {
            var footer = getDataHelper(16);
            footer.view.setUint32(0, 1347094280);
            if (zipObject.crc) {
              zipObject.header.view.setUint32(10, zipObject.crc.get(), true);
              zipObject.header.view.setUint32(14, zipObject.compressedLength, true);
              zipObject.header.view.setUint32(18, zipObject.uncompressedLength, true);
              footer.view.setUint32(4, zipObject.crc.get(), true);
              footer.view.setUint32(8, zipObject.compressedLength, true);
              footer.view.setUint32(12, zipObject.uncompressedLength, true);
            }
            ctrl.enqueue(footer.array);
            offset += zipObject.compressedLength + 16;
            next();
          },
          fileLike
        };
        if (!activeZipObject) {
          activeZipObject = zipObject;
          processNextChunk();
        }
      },
      close() {
        if (closed)
          throw new TypeError("Cannot close a readable stream that has already been requested to be closed");
        if (!activeZipObject)
          closeZip();
        closed = true;
      }
    };
    function closeZip() {
      var length = 0;
      var index = 0;
      var indexFilename, file;
      for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
        file = files[filenames[indexFilename]];
        length += 46 + file.nameBuf.length + file.comment.length;
      }
      const data = getDataHelper(length + 22);
      for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
        file = files[filenames[indexFilename]];
        data.view.setUint32(index, 1347092738);
        data.view.setUint16(index + 4, 5120);
        data.array.set(file.header.array, index + 6);
        data.view.setUint16(index + 32, file.comment.length, true);
        if (file.directory) {
          data.view.setUint8(index + 38, 16);
        }
        data.view.setUint32(index + 42, file.offset, true);
        data.array.set(file.nameBuf, index + 46);
        data.array.set(file.comment, index + 46 + file.nameBuf.length);
        index += 46 + file.nameBuf.length + file.comment.length;
      }
      data.view.setUint32(index, 1347093766);
      data.view.setUint16(index + 8, filenames.length, true);
      data.view.setUint16(index + 10, filenames.length, true);
      data.view.setUint32(index + 12, length, true);
      data.view.setUint32(index + 16, offset, true);
      ctrl.enqueue(data.array);
      ctrl.close();
    }
    function processNextChunk() {
      if (!activeZipObject)
        return;
      if (activeZipObject.directory)
        return activeZipObject.writeFooter(activeZipObject.writeHeader());
      if (activeZipObject.reader)
        return pump(activeZipObject);
      if (activeZipObject.fileLike.stream) {
        activeZipObject.crc = new Crc32();
        activeZipObject.reader = activeZipObject.fileLike.stream().getReader();
        activeZipObject.writeHeader();
      } else
        next();
    }
    return new ReadableStream({
      start: (c) => {
        ctrl = c;
        underlyingSource.start && Promise.resolve(underlyingSource.start(zipWriter));
      },
      pull() {
        return processNextChunk() || underlyingSource.pull && Promise.resolve(underlyingSource.pull(zipWriter));
      }
    });
  }
  async function zipStreamDownload(zipFilename, files, onProgress, rateLimit = 1e3) {
    let current = 0;
    const total = files.length;
    const fileIterator = files.values();
    const readableZipStream = createWriter({
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      async pull(ctrl) {
        const fileInfo = fileIterator.next();
        if (fileInfo.done) {
          ctrl.close();
        } else {
          const {
            filename,
            url
          } = fileInfo.value;
          const start = Date.now();
          logger.debug(`Start downloading ${filename} from ${url}`);
          return fetch(url).then((res) => {
            ctrl.enqueue({
              name: filename,
              stream: () => res.body
            });
            onProgress == null ? void 0 : onProgress(++current, total, fileInfo.value);
            logger.debug(`Finished downloading ${filename} in ${Date.now() - start}ms`);
          }).then(() => {
            return new Promise((resolve) => setTimeout(resolve, rateLimit));
          });
        }
      }
    });
    const chunks = [];
    const writableOutputStream = new WritableStream({
      write(chunk) {
        chunks.push(chunk);
      },
      close() {
        logger.info("Zip stream closed.");
      }
    });
    logger.info(`Exporting to ZIP file: ${zipFilename}`);
    await readableZipStream.pipeTo(writableOutputStream);
    const arrayBuffer = await new Blob(chunks).arrayBuffer();
    const blob = new Blob([arrayBuffer]);
    FileSaver_minExports.saveAs(blob, zipFilename);
  }
  function extractDataFromResponse(response, extractInstructionsFromJson, extractDataFromTimelineEntry) {
    const json = JSON.parse(response.responseText);
    const instructions = extractInstructionsFromJson(json);
    const timelineAddEntriesInstruction = instructions.find((i) => i.type === "TimelineAddEntries");
    const newData = [];
    for (const entry of timelineAddEntriesInstruction.entries) {
      if (isTimelineEntryItem(entry)) {
        const data = extractDataFromTimelineEntry(entry);
        if (data) {
          newData.push(data);
        }
      }
    }
    return newData;
  }
  function extractTimelineTweet(itemContent) {
    const tweetUnion = itemContent.tweet_results.result;
    if (!tweetUnion) {
      logger.warn("TimelineTweet is empty. This could happen when the tweet's visibility is limited by Twitter.", itemContent);
      return null;
    }
    return extractTweetUnion(tweetUnion);
  }
  function isTimelineEntryItem(entry) {
    return entry.content.entryType === "TimelineTimelineItem";
  }
  function isTimelineEntryTweet(entry) {
    return isTimelineEntryItem(entry) && entry.entryId.startsWith("tweet-") && entry.content.itemContent.__typename === "TimelineTweet";
  }
  function isTimelineEntryUser(entry) {
    return isTimelineEntryItem(entry) && entry.entryId.startsWith("user-") && entry.content.itemContent.__typename === "TimelineUser";
  }
  function isTimelineEntryModule(entry) {
    return entry.content.entryType === "TimelineTimelineModule";
  }
  function isTimelineEntryConversationThread(entry) {
    return isTimelineEntryModule(entry) && entry.entryId.startsWith("conversationthread-") && Array.isArray(entry.content.items);
  }
  function isTimelineEntryProfileConversation(entry) {
    return isTimelineEntryModule(entry) && entry.entryId.startsWith("profile-conversation-") && Array.isArray(entry.content.items);
  }
  function isTimelineEntryProfileGrid(entry) {
    return isTimelineEntryModule(entry) && entry.entryId.startsWith("profile-grid-") && Array.isArray(entry.content.items);
  }
  function isTimelineEntrySearchGrid(entry) {
    return isTimelineEntryModule(entry) && entry.entryId.startsWith("search-grid-") && Array.isArray(entry.content.items);
  }
  function isTimelineEntryListSearch(entry) {
    return isTimelineEntryModule(entry) && entry.entryId.startsWith("list-search-") && Array.isArray(entry.content.items);
  }
  function extractTweetUnion(tweet) {
    var _a, _b;
    try {
      if (tweet.__typename === "Tweet") {
        return tweet;
      }
      if (tweet.__typename === "TweetWithVisibilityResults") {
        return tweet.tweet;
      }
      if (tweet.__typename === "TweetTombstone") {
        logger.warn(`TweetTombstone received (Reason: ${(_b = (_a = tweet.tombstone) == null ? void 0 : _a.text) == null ? void 0 : _b.text})`, tweet);
        return null;
      }
      if (tweet.__typename === "TweetUnavailable") {
        logger.warn("TweetUnavailable received (Reason: unknown)", tweet);
        return null;
      }
      logger.debug(tweet);
      logger.errorWithBanner("Unknown tweet type received");
    } catch (err) {
      logger.debug(tweet);
      logger.errorWithBanner("Failed to extract tweet", err);
    }
    return null;
  }
  function extractRetweetedTweet(tweet) {
    var _a;
    if ((_a = tweet.legacy.retweeted_status_result) == null ? void 0 : _a.result) {
      return extractTweetUnion(tweet.legacy.retweeted_status_result.result);
    }
    return null;
  }
  function extractQuotedTweet(tweet) {
    var _a;
    if ((_a = tweet.quoted_status_result) == null ? void 0 : _a.result) {
      return extractTweetUnion(tweet.quoted_status_result.result);
    }
    return null;
  }
  function extractTweetUserScreenName(tweet) {
    return tweet.core.user_results.result.legacy.screen_name;
  }
  function extractTweetMedia(tweet) {
    var _a;
    const realTweet = extractRetweetedTweet(tweet) ?? tweet;
    if ((_a = realTweet.legacy.extended_entities) == null ? void 0 : _a.media) {
      return realTweet.legacy.extended_entities.media;
    }
    return realTweet.legacy.entities.media ?? [];
  }
  function extractTweetFullText(tweet) {
    var _a;
    return ((_a = tweet.note_tweet) == null ? void 0 : _a.note_tweet_results.result.text) ?? tweet.legacy.full_text;
  }
  function getMediaIndex(tweet, media) {
    const key = media.media_key;
    return extractTweetMedia(tweet).findIndex((value) => value.media_key === key);
  }
  function getMediaOriginalUrl(media) {
    var _a;
    if (media.type === "video" || media.type === "animated_gif") {
      const variants = ((_a = media.video_info) == null ? void 0 : _a.variants) ?? [];
      let maxBitrateVariant = variants[0];
      for (const variant of variants) {
        if (variant.bitrate && variant.bitrate > ((maxBitrateVariant == null ? void 0 : maxBitrateVariant.bitrate) ?? 0)) {
          maxBitrateVariant = variant;
        }
      }
      return (maxBitrateVariant == null ? void 0 : maxBitrateVariant.url) ?? media.media_url_https;
    }
    return formatTwitterImage(media.media_url_https, "orig");
  }
  function formatTwitterImage(imgUrl, name2 = "medium") {
    const regex = /^(https?:\/\/pbs\.twimg\.com\/media\/.+)\.(\w+)$/;
    const match = imgUrl.match(regex);
    if (!match) {
      return `${imgUrl}?name=${name2}`;
    }
    const [, url, ext] = match;
    return `${url}?format=${ext}&name=${name2}`;
  }
  function getProfileImageOriginalUrl(url) {
    return url.replace(/_normal\.(jpe?g|png|gif)$/, ".$1");
  }
  function getFileExtensionFromUrl(url) {
    const regex = /format=(\w+)|\.(\w+)$|\.(\w+)\?.+$/;
    const match = regex.exec(url);
    return (match == null ? void 0 : match[1]) ?? (match == null ? void 0 : match[2]) ?? (match == null ? void 0 : match[3]) ?? "jpg";
  }
  function getTweetURL(tweet) {
    return `https://twitter.com/${extractTweetUserScreenName(tweet)}/status/${tweet.legacy.id_str}`;
  }
  function getUserURL(user) {
    return `https://twitter.com/${user.legacy.screen_name}`;
  }
  function getInReplyToTweetURL(tweet) {
    return `https://twitter.com/${tweet.legacy.in_reply_to_screen_name}/status/${tweet.legacy.in_reply_to_status_id_str}`;
  }
  const patterns = {
    id: {
      description: "The tweet ID",
      extractor: (tweet) => tweet.rest_id
    },
    screen_name: {
      description: "The username of tweet author",
      extractor: (tweet) => tweet.core.user_results.result.legacy.screen_name
    },
    name: {
      description: "The profile name of tweet author",
      extractor: (tweet) => tweet.core.user_results.result.legacy.name
    },
    index: {
      description: "The media index in tweet (start from 0)",
      extractor: (tweet, media) => String(getMediaIndex(tweet, media))
    },
    num: {
      description: "The order of media in tweet (1/2/3/4)",
      extractor: (tweet, media) => String(getMediaIndex(tweet, media) + 1)
    },
    date: {
      description: "The post date in YYYYMMDD format",
      extractor: (tweet) => parseTwitterDateTime(tweet.legacy.created_at).format("YYYYMMDD")
    },
    time: {
      description: "The post time in HHmmss format",
      extractor: (tweet) => parseTwitterDateTime(tweet.legacy.created_at).format("HHmmss")
    },
    type: {
      description: "The media type (photo/video/animated_gif)",
      extractor: (tweet, media) => media.type
    },
    ext: {
      description: "The file extension of media (jpg/png/mp4)",
      extractor: (tweet, media) => getFileExtensionFromUrl(getMediaOriginalUrl(media))
    }
  };
  const DEFAULT_FILENAME_PATTERN = "{screen_name}_{id}_{type}_{num}_{date}.{ext}";
  const FILENAME_PATTERN_TOOLTIP = Object.entries(patterns).map(([key, value]) => `{${key}} - ${value.description}`).reduce((acc, cur) => acc + cur + "\n", "");
  function extractMedia(data, includeRetweets, filenamePattern) {
    const gallery = /* @__PURE__ */ new Map();
    for (const item of data) {
      if (item.__typename === "Tweet") {
        if (!includeRetweets && item.legacy.retweeted_status_result) {
          continue;
        }
        const tweetMedia = extractTweetMedia(item).map((media) => {
          let filename = filenamePattern;
          for (const [key, value] of Object.entries(patterns)) {
            filename = filename.replace(`{${key}}`, value.extractor(item, media));
          }
          return {
            filename,
            url: getMediaOriginalUrl(media)
          };
        });
        for (const media of tweetMedia) {
          gallery.set(media.filename, media);
        }
      }
      if (item.__typename === "User") {
        if (item.legacy.profile_image_url_https) {
          const ext = getFileExtensionFromUrl(item.legacy.profile_image_url_https);
          const filename = `${item.legacy.screen_name}_profile_image.${ext}`;
          gallery.set(filename, {
            filename,
            url: getProfileImageOriginalUrl(item.legacy.profile_image_url_https)
          });
        }
        if (item.legacy.profile_banner_url) {
          const ext = getFileExtensionFromUrl(item.legacy.profile_banner_url);
          const filename = `${item.legacy.screen_name}_profile_banner.${ext}`;
          gallery.set(filename, {
            filename,
            url: item.legacy.profile_banner_url
          });
        }
      }
    }
    return Array.from(gallery.values());
  }
  function ExportMediaModal({
    title,
    table,
    isTweet,
    show,
    onClose
  }) {
    const [loading, setLoading] = useSignalState(false);
    const [copied, setCopied] = useSignalState(false);
    const [rateLimit, setRateLimit] = useSignalState(1e3);
    const [filenamePattern, setFilenamePattern] = useSignalState(DEFAULT_FILENAME_PATTERN);
    const [includeRetweets, toggleIncludeRetweets] = useToggle(true);
    const [currentProgress, setCurrentProgress] = useSignalState(0);
    const [totalProgress, setTotalProgress] = useSignalState(0);
    const taskStatusSignal = useSignal({});
    const mediaList = extractMedia(table.getSelectedRowModel().rows.map((row) => row.original), includeRetweets, filenamePattern);
    const onProgress = (current, total, value) => {
      setCurrentProgress(current);
      setTotalProgress(total);
      if (value == null ? void 0 : value.filename) {
        const updated = {
          ...taskStatusSignal.value,
          [value.filename]: 100
        };
        taskStatusSignal.value = updated;
      }
    };
    const onExport = async () => {
      try {
        setLoading(true);
        await zipStreamDownload(`twitter-${title}-${Date.now()}-media.zip`, mediaList, onProgress);
        setLoading(false);
      } catch (err) {
        setLoading(false);
        logger.error("Failed to export media. Open DevTools for more details.", err);
      }
    };
    const onCopy = () => {
      const text = mediaList.map((media) => `${media.url}
  out=${media.filename}`).join("\n");
      try {
        navigator.clipboard.writeText(text);
        setCopied(true);
        setTimeout(() => setCopied(false), 2e3);
      } catch (err) {
        logger.error("Failed to copy media URLs. Open DevTools for more details.", err);
      }
    };
    return u(Modal, {
      class: "max-w-sm md:max-w-screen-sm sm:max-w-screen-sm",
      title: `${title} Media`,
      show,
      onClose,
      children: [u("div", {
        class: "px-4 text-base overflow-y-scroll overscroll-none",
        children: [u("p", {
          class: "text-base-content text-opacity-60 leading-5 text-sm",
          children: "Download and save media files from captured data. This may take a while depending on the amount of data. Media that will be downloaded includes: profile images, profile banners (for users), images, videos (for tweets)."
        }), u("div", {
          role: "alert",
          class: "alert text-sm py-2 mt-2 mb-2",
          children: [u(IconInfoCircle, {
            size: 24
          }), u("span", {
            children: "For more than 100 media or large files, it is recommended to copy the URLs and download them with an external download manager such as aria2."
          })]
        }), isTweet && u("div", {
          class: "flex items-center h-9",
          children: [u("div", {
            class: "mr-2 leading-8 flex items-center",
            children: [u("span", {
              children: "Filename template "
            }), u("div", {
              class: "tooltip tooltip-bottom ml-0.5 before:whitespace-pre-line before:max-w-max",
              "data-tip": FILENAME_PATTERN_TOOLTIP,
              children: u(IconHelp, {
                size: 20
              })
            }), u("span", {
              children: ":"
            })]
          }), u("input", {
            type: "text",
            class: "input input-bordered input-sm flex-grow",
            value: filenamePattern,
            onChange: (e) => {
              var _a;
              setFilenamePattern((_a = e == null ? void 0 : e.target) == null ? void 0 : _a.value);
            }
          })]
        }), u("div", {
          class: "flex h-9 justify-between",
          children: [u("div", {
            class: "flex items-center h-9 w-1/2",
            children: [u("p", {
              class: "mr-2 leading-8",
              children: "Rate limit (ms):"
            }), u("input", {
              type: "number",
              class: "input input-bordered input-sm w-32",
              value: rateLimit,
              onChange: (e) => {
                var _a;
                const value = parseInt((_a = e == null ? void 0 : e.target) == null ? void 0 : _a.value);
                setRateLimit(value || 0);
              }
            })]
          }), u("div", {
            class: "flex items-center h-9 w-1/2",
            children: [u("p", {
              class: "mr-2 leading-8",
              children: "Include retweets:"
            }), u("input", {
              type: "checkbox",
              class: "checkbox checkbox-sm",
              checked: includeRetweets,
              onChange: toggleIncludeRetweets
            })]
          })]
        }), u("div", {
          class: "my-3 overflow-x-scroll",
          children: [u("table", {
            class: "table table-xs table-zebra",
            children: [u("thead", {
              children: u("tr", {
                children: [u("th", {}), u("th", {
                  children: "#"
                }), u("th", {
                  children: "File Name"
                }), u("th", {
                  children: "URL"
                })]
              })
            }), u("tbody", {
              children: mediaList.map((media, index) => u("tr", {
                children: [u("td", {
                  children: taskStatusSignal.value[media.filename] ? u(IconCircleCheck, {
                    class: "text-success",
                    size: 14
                  }) : u(IconCircleDashed, {
                    size: 14
                  })
                }), u("th", {
                  children: index + 1
                }), u("td", {
                  children: media.filename
                }), u("td", {
                  children: u("a", {
                    class: "link whitespace-nowrap",
                    href: media.url,
                    target: "_blank",
                    rel: "noopener noreferrer",
                    children: media.url
                  })
                })]
              }))
            })]
          }), mediaList.length > 0 ? null : u("div", {
            class: "flex items-center justify-center h-28 w-full",
            children: u("p", {
              class: "text-base-content text-opacity-50",
              children: "No media selected."
            })
          })]
        }), u("div", {
          class: "flex flex-col mt-6",
          children: [u("progress", {
            class: "progress progress-secondary w-full",
            value: currentProgress / (totalProgress || 1) * 100,
            max: "100"
          }), u("span", {
            class: "text-sm h-2 leading-none mt-2 text-base-content text-opacity-60",
            children: `${currentProgress}/${mediaList.length}`
          })]
        })]
      }), u("div", {
        class: "flex space-x-2 mt-2",
        children: [u("span", {
          class: "flex-grow"
        }), u("button", {
          class: "btn",
          onClick: onClose,
          children: "Cancel"
        }), u("button", {
          class: "btn",
          onClick: onCopy,
          children: copied ? "Copied!" : "Copy URLs"
        }), u("button", {
          class: cx("btn btn-secondary", loading && "btn-disabled"),
          onClick: onExport,
          children: [loading && u("span", {
            class: "loading loading-spinner"
          }), "Start Export"]
        })]
      })]
    });
  }
  function flexRender(Comp, props) {
    return !Comp ? null : isComponent(Comp) ? u(Comp, {
      ...props
    }) : Comp;
  }
  function isComponent(component) {
    return typeof component === "function";
  }
  /**
   * @license MIT
   * https://github.com/TanStack/table/blob/main/packages/react-table/src/index.tsx
   */
  function useReactTable(options2) {
    const resolvedOptions = {
      state: {},
      // Dummy state
      onStateChange: () => {
      },
      // noop
      renderFallbackValue: null,
      ...options2
    };
    const [tableRef] = hooks.useState(() => ({
      current: tableCore.createTable(resolvedOptions)
    }));
    const [state, setState] = hooks.useState(() => tableRef.current.initialState);
    tableRef.current.setOptions((prev) => ({
      ...prev,
      ...options2,
      state: {
        ...state,
        ...options2.state
      },
      // Similarly, we'll maintain both our internal state and any user-provided
      // state.
      onStateChange: (updater) => {
        var _a;
        setState(updater);
        (_a = options2.onStateChange) == null ? void 0 : _a.call(options2, updater);
      }
    }));
    return tableRef.current;
  }
  const columnHelper$1 = tableCore.createColumnHelper();
  const rtSourceAccessor = (row) => {
    const source = extractRetweetedTweet(row);
    return source ? extractTweetUserScreenName(source) : null;
  };
  const quoteSourceAccessor = (row) => {
    const source = extractQuotedTweet(row);
    return source ? extractTweetUserScreenName(source) : null;
  };
  const columns$1 = [columnHelper$1.display({
    id: "select",
    meta: {
      exportable: false
    },
    header: ({
      table
    }) => u("input", {
      type: "checkbox",
      class: "checkbox checkbox-sm align-middle",
      checked: table.getIsAllRowsSelected(),
      indeterminate: table.getIsSomeRowsSelected(),
      onChange: table.getToggleAllRowsSelectedHandler()
    }),
    cell: ({
      row
    }) => u("input", {
      type: "checkbox",
      class: "checkbox checkbox-sm",
      checked: row.getIsSelected(),
      disabled: !row.getCanSelect(),
      indeterminate: row.getIsSomeSelected(),
      onChange: row.getToggleSelectedHandler()
    })
  }), columnHelper$1.accessor("rest_id", {
    meta: {
      exportKey: "id",
      exportHeader: "ID"
    },
    header: () => u("span", {
      children: "ID"
    }),
    cell: (info) => u("p", {
      class: "w-20 break-all font-mono text-xs",
      children: info.getValue()
    })
  }), columnHelper$1.accessor((row) => +parseTwitterDateTime(row.legacy.created_at), {
    id: "created_at",
    meta: {
      exportKey: "created_at",
      exportHeader: "Date",
      exportValue: (row) => formatDateTime(parseTwitterDateTime(row.original.legacy.created_at), appOptionsManager.get("dateTimeFormat"))
    },
    header: () => u("span", {
      children: "Date"
    }),
    cell: (info) => u("p", {
      class: "w-24",
      children: u("a", {
        class: "link",
        target: "_blank",
        href: getTweetURL(info.row.original),
        children: formatDateTime(info.getValue(), appOptionsManager.get("dateTimeFormat"))
      })
    })
  }), columnHelper$1.accessor("legacy.full_text", {
    meta: {
      exportKey: "full_text",
      exportHeader: "Content",
      exportValue: (row) => extractTweetFullText(row.original)
    },
    header: () => u("span", {
      children: "Content"
    }),
    cell: (info) => u("div", {
      children: [u("p", {
        class: "w-60 whitespace-pre-wrap",
        dangerouslySetInnerHTML: {
          __html: strEntitiesToHTML(info.row.original.legacy.full_text, [...info.row.original.legacy.entities.urls, ...info.row.original.legacy.entities.media ?? []])
        }
      }), info.row.original.note_tweet && u("button", {
        class: "link",
        onClick: () => {
          var _a;
          return (_a = info.table.options.meta) == null ? void 0 : _a.setRawDataPreview(extractTweetFullText(info.row.original));
        },
        children: [">>", " Show Full Text"]
      })]
    })
  }), columnHelper$1.accessor((row) => extractTweetMedia(row).length, {
    id: "media",
    meta: {
      exportKey: "media",
      exportHeader: "Media",
      exportValue: (row) => extractTweetMedia(row.original).map((media) => ({
        type: media.type,
        url: media.url,
        thumbnail: formatTwitterImage(media.media_url_https, "thumb"),
        original: getMediaOriginalUrl(media)
      }))
    },
    header: () => u("span", {
      children: "Media"
    }),
    cell: (info) => u("div", {
      class: "flex flex-row items-start space-x-1 w-max",
      children: [extractTweetMedia(info.row.original).map((media) => {
        var _a;
        return u("div", {
          class: "flex-shrink-0 block cursor-pointer relative w-12 h-12 rounded bg-base-300 overflow-hidden",
          onClick: () => {
            var _a2;
            return (_a2 = info.table.options.meta) == null ? void 0 : _a2.setMediaPreview(getMediaOriginalUrl(media));
          },
          children: [u("img", {
            class: "w-full h-full object-cover",
            src: formatTwitterImage(media.media_url_https, "thumb")
          }), media.type !== "photo" && u("div", {
            class: "absolute bottom-0.5 left-0.5 h-4 w-max px-0.5 text-xs text-white bg-black bg-opacity-30 leading-4 text-center rounded",
            children: media.type === "video" ? formatVideoDuration((_a = media.video_info) == null ? void 0 : _a.duration_millis) : "GIF"
          })]
        }, media.media_key);
      }), extractTweetMedia(info.row.original).length ? null : "N/A"]
    })
  }), columnHelper$1.accessor("core.user_results.result.legacy.screen_name", {
    meta: {
      exportKey: "screen_name",
      exportHeader: "Screen Name"
    },
    header: () => u("span", {
      children: "Screen Name"
    }),
    cell: (info) => u("p", {
      class: "whitespace-pre",
      children: u("a", {
        class: "link",
        target: "_blank",
        href: getUserURL(info.row.original.core.user_results.result),
        children: ["@", info.getValue()]
      })
    })
  }), columnHelper$1.accessor("core.user_results.result.legacy.name", {
    meta: {
      exportKey: "name",
      exportHeader: "Profile Name"
    },
    header: () => u("span", {
      children: "Profile Name"
    }),
    cell: (info) => u("p", {
      class: "w-32",
      children: info.getValue()
    })
  }), columnHelper$1.accessor("core.user_results.result.legacy.profile_image_url_https", {
    meta: {
      exportKey: "profile_image_url",
      exportHeader: "Profile Image"
    },
    header: () => u("span", {
      children: "Profile Image"
    }),
    cell: (info) => u("div", {
      class: "cursor-pointer",
      onClick: () => {
        var _a;
        return (_a = info.table.options.meta) == null ? void 0 : _a.setMediaPreview(getProfileImageOriginalUrl(info.getValue()));
      },
      children: u("img", {
        class: "w-12 h-12 rounded",
        src: info.getValue()
      })
    })
  }), columnHelper$1.accessor("legacy.in_reply_to_screen_name", {
    meta: {
      exportKey: "in_reply_to",
      exportHeader: "Replying To",
      exportValue: (row) => row.original.legacy.in_reply_to_status_id_str
    },
    header: () => u("span", {
      children: "Replying To"
    }),
    cell: (info) => u("p", {
      class: "whitespace-pre",
      children: info.row.original.legacy.in_reply_to_status_id_str ? u("a", {
        class: "link",
        target: "_blank",
        href: getInReplyToTweetURL(info.row.original),
        children: ["@", info.getValue()]
      }) : "N/A"
    })
  }), columnHelper$1.accessor(rtSourceAccessor, {
    id: "rt_source",
    meta: {
      exportKey: "retweeted_status",
      exportHeader: "RT Source",
      exportValue: (row) => {
        var _a;
        return (_a = extractRetweetedTweet(row.original)) == null ? void 0 : _a.rest_id;
      }
    },
    header: () => u("span", {
      children: "RT Source"
    }),
    cell: (info) => {
      const source = extractRetweetedTweet(info.row.original);
      return u("p", {
        class: "whitespace-pre",
        children: source ? u("a", {
          class: "link",
          target: "_blank",
          href: getTweetURL(source),
          children: ["@", info.getValue()]
        }) : "N/A"
      });
    }
  }), columnHelper$1.accessor(quoteSourceAccessor, {
    id: "quote_source",
    meta: {
      exportKey: "quoted_status",
      exportHeader: "Quote Source",
      exportValue: (row) => {
        var _a;
        return (_a = extractQuotedTweet(row.original)) == null ? void 0 : _a.rest_id;
      }
    },
    header: () => u("span", {
      children: "Quote Source"
    }),
    cell: (info) => {
      const source = extractQuotedTweet(info.row.original);
      return u("p", {
        class: "whitespace-pre",
        children: source ? u("a", {
          class: "link",
          target: "_blank",
          href: getTweetURL(source),
          children: ["@", info.getValue()]
        }) : "N/A"
      });
    }
  }), columnHelper$1.accessor("legacy.favorite_count", {
    meta: {
      exportKey: "favorite_count",
      exportHeader: "Favorites"
    },
    header: () => u("span", {
      children: "Favorites"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper$1.accessor("legacy.retweet_count", {
    meta: {
      exportKey: "retweet_count",
      exportHeader: "Retweets"
    },
    header: () => u("span", {
      children: "Retweets"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper$1.accessor("legacy.bookmark_count", {
    meta: {
      exportKey: "bookmark_count",
      exportHeader: "Bookmarks"
    },
    header: () => u("span", {
      children: "Bookmarks"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper$1.accessor("legacy.quote_count", {
    meta: {
      exportKey: "quote_count",
      exportHeader: "Quotes"
    },
    header: () => u("span", {
      children: "Quotes"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper$1.accessor("legacy.reply_count", {
    meta: {
      exportKey: "reply_count",
      exportHeader: "Replies"
    },
    header: () => u("span", {
      children: "Replies"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper$1.accessor("views.count", {
    meta: {
      exportKey: "views_count",
      exportHeader: "Views",
      exportValue: (row) => typeof row.original.views.count === "undefined" ? null : +row.original.views.count
    },
    header: () => u("span", {
      children: "Views"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ?? "N/A"
    })
  }), columnHelper$1.accessor("legacy.favorited", {
    meta: {
      exportKey: "favorited",
      exportHeader: "Favorited"
    },
    header: () => u("span", {
      children: "Favorited"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper$1.accessor("legacy.retweeted", {
    meta: {
      exportKey: "retweeted",
      exportHeader: "Retweeted"
    },
    header: () => u("span", {
      children: "Retweeted"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper$1.accessor("legacy.bookmarked", {
    meta: {
      exportKey: "bookmarked",
      exportHeader: "Bookmarked"
    },
    header: () => u("span", {
      children: "Bookmarked"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper$1.display({
    id: "url",
    meta: {
      exportKey: "url",
      exportHeader: "URL",
      exportValue: (row) => getTweetURL(row.original)
    },
    header: () => u("span", {
      children: "URL"
    }),
    cell: (info) => u("a", {
      href: getTweetURL(info.row.original),
      target: "_blank",
      children: u(IconLink, {})
    })
  }), columnHelper$1.display({
    id: "actions",
    meta: {
      exportable: false
    },
    header: () => u("span", {
      children: "Actions"
    }),
    cell: (info) => u("div", {
      class: "flex flex-row items-start space-x-1",
      children: u("button", {
        onClick: () => {
          var _a;
          return (_a = info.table.options.meta) == null ? void 0 : _a.setRawDataPreview(info.row.original);
        },
        class: "btn btn-xs btn-neutral whitespace-nowrap",
        children: "Details"
      })
    })
  })];
  const columnHelper = tableCore.createColumnHelper();
  const columns = [columnHelper.display({
    id: "select",
    meta: {
      exportable: false
    },
    header: ({
      table
    }) => u("input", {
      type: "checkbox",
      class: "checkbox checkbox-sm align-middle",
      checked: table.getIsAllRowsSelected(),
      indeterminate: table.getIsSomeRowsSelected(),
      onChange: table.getToggleAllRowsSelectedHandler()
    }),
    cell: ({
      row
    }) => u("input", {
      type: "checkbox",
      class: "checkbox checkbox-sm",
      checked: row.getIsSelected(),
      disabled: !row.getCanSelect(),
      indeterminate: row.getIsSomeSelected(),
      onChange: row.getToggleSelectedHandler()
    })
  }), columnHelper.accessor("rest_id", {
    meta: {
      exportKey: "id",
      exportHeader: "ID"
    },
    header: () => u("span", {
      children: "ID"
    }),
    cell: (info) => u("p", {
      class: "w-20 break-all font-mono text-xs",
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.screen_name", {
    meta: {
      exportKey: "screen_name",
      exportHeader: "Screen Name"
    },
    header: () => u("span", {
      children: "Screen Name"
    }),
    cell: (info) => u("p", {
      class: "whitespace-pre",
      children: u("a", {
        class: "link",
        target: "_blank",
        href: getUserURL(info.row.original),
        children: ["@", info.getValue()]
      })
    })
  }), columnHelper.accessor("legacy.name", {
    meta: {
      exportKey: "name",
      exportHeader: "Profile Name"
    },
    header: () => u("span", {
      children: "Profile Name"
    }),
    cell: (info) => u("p", {
      class: "w-32",
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.description", {
    meta: {
      exportKey: "description",
      exportHeader: "Description"
    },
    header: () => u("span", {
      children: "Description"
    }),
    cell: (info) => u("p", {
      class: "w-52",
      dangerouslySetInnerHTML: {
        __html: strEntitiesToHTML(info.row.original.legacy.description, info.row.original.legacy.entities.description.urls)
      }
    })
  }), columnHelper.accessor("legacy.profile_image_url_https", {
    meta: {
      exportKey: "profile_image_url",
      exportHeader: "Profile Image"
    },
    header: () => u("span", {
      children: "Profile Image"
    }),
    cell: (info) => u("div", {
      class: "cursor-pointer",
      onClick: () => {
        var _a;
        return (_a = info.table.options.meta) == null ? void 0 : _a.setMediaPreview(getProfileImageOriginalUrl(info.getValue()));
      },
      children: u("img", {
        class: "w-12 h-12 rounded",
        src: info.getValue()
      })
    })
  }), columnHelper.accessor("legacy.profile_banner_url", {
    meta: {
      exportKey: "profile_banner_url",
      exportHeader: "Profile Banner"
    },
    header: () => u("span", {
      children: "Profile Banner"
    }),
    cell: (info) => u("div", {
      class: "cursor-pointer w-36 h-12",
      onClick: () => {
        var _a;
        return (_a = info.table.options.meta) == null ? void 0 : _a.setMediaPreview(info.getValue() ?? "");
      },
      children: info.getValue() ? u("img", {
        class: "w-auto h-12 rounded",
        src: `${info.getValue()}/600x200`
      }) : u("span", {
        class: "leading-[48px]",
        children: "N/A"
      })
    })
  }), columnHelper.accessor("legacy.followers_count", {
    meta: {
      exportKey: "followers_count",
      exportHeader: "Followers"
    },
    header: () => u("span", {
      children: "Followers"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.statuses_count", {
    meta: {
      exportKey: "statuses_count",
      exportHeader: "Statuses"
    },
    header: () => u("span", {
      children: "Statuses"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.favourites_count", {
    meta: {
      exportKey: "favourites_count",
      exportHeader: "Favourites"
    },
    header: () => u("span", {
      children: "Favourites"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.listed_count", {
    meta: {
      exportKey: "listed_count",
      exportHeader: "Listed"
    },
    header: () => u("span", {
      children: "Listed"
    }),
    cell: (info) => u("p", {
      children: info.getValue()
    })
  }), columnHelper.accessor("legacy.verified_type", {
    meta: {
      exportKey: "verified_type",
      exportHeader: "Verified Type"
    },
    header: () => u("span", {
      children: "Verified Type"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ?? "N/A"
    })
  }), columnHelper.accessor("is_blue_verified", {
    meta: {
      exportKey: "is_blue_verified",
      exportHeader: "Blue Verified"
    },
    header: () => u("span", {
      children: "Blue Verified"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper.accessor("legacy.following", {
    meta: {
      exportKey: "following",
      exportHeader: "Following"
    },
    header: () => u("span", {
      children: "Following"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper.accessor("legacy.followed_by", {
    meta: {
      exportKey: "followed_by",
      exportHeader: "Follows You"
    },
    header: () => u("span", {
      children: "Follows You"
    }),
    cell: (info) => u("p", {
      children: info.getValue() ? "YES" : "NO"
    })
  }), columnHelper.accessor((row) => +parseTwitterDateTime(row.legacy.created_at), {
    id: "created_at",
    meta: {
      exportKey: "created_at",
      exportHeader: "Created At",
      exportValue: (row) => formatDateTime(parseTwitterDateTime(row.original.legacy.created_at), appOptionsManager.get("dateTimeFormat"))
    },
    header: () => u("span", {
      children: "Created At"
    }),
    cell: (info) => u("p", {
      class: "w-24",
      children: formatDateTime(info.getValue(), appOptionsManager.get("dateTimeFormat"))
    })
  }), columnHelper.display({
    id: "url",
    meta: {
      exportKey: "url",
      exportHeader: "URL",
      exportValue: (row) => getUserURL(row.original)
    },
    header: () => u("span", {
      children: "URL"
    }),
    cell: (info) => u("a", {
      href: getUserURL(info.row.original),
      target: "_blank",
      children: u(IconLink, {})
    })
  })];
  const Pagination = ({
    table
  }) => {
    const state = table.getState().pagination;
    return u("div", {
      className: "mt-3 flex items-center gap-2",
      children: [u("span", {
        children: "Rows per page:"
      }), u("select", {
        value: state.pageSize,
        onChange: (e) => {
          table.setPageSize(Number(e.target.value));
        },
        className: "select select-sm select-bordered",
        children: [10, 20, 50, 100].map((pageSize) => u("option", {
          value: pageSize,
          children: pageSize
        }, pageSize))
      }), u("span", {
        class: "flex-grow"
      }), u("span", {
        children: [state.pageSize * state.pageIndex + 1, " - ", Math.min(state.pageSize * (state.pageIndex + 1), table.getFilteredRowModel().rows.length), " of ", table.getFilteredRowModel().rows.length, " items"]
      }), u("input", {
        defaultValue: (state.pageIndex + 1).toString(),
        type: "number",
        onInput: (e) => {
          const value = e.target.value;
          table.setPageIndex(value ? Number(value) - 1 : 0);
        },
        className: "input input-bordered w-20 input-sm text-center"
      }), u("div", {
        class: "join",
        children: [u("button", {
          className: "join-item btn btn-sm",
          onClick: () => table.setPageIndex(0),
          disabled: !table.getCanPreviousPage(),
          children: u(IconChevronLeftPipe, {
            size: 20
          })
        }), u("button", {
          className: "join-item btn btn-sm",
          onClick: () => table.previousPage(),
          disabled: !table.getCanPreviousPage(),
          children: u(IconChevronLeft, {
            size: 20
          })
        }), u("button", {
          className: "join-item btn btn-sm",
          onClick: () => table.nextPage(),
          disabled: !table.getCanNextPage(),
          children: u(IconChevronRight, {
            size: 20
          })
        }), u("button", {
          className: "join-item btn btn-sm",
          onClick: () => table.setPageIndex(table.getPageCount() - 1),
          disabled: !table.getCanNextPage(),
          children: u(IconChevronRightPipe, {
            size: 20
          })
        })]
      })]
    });
  };
  function TableView({
    title,
    recordsSignal,
    isTweet
  }) {
    const data = recordsSignal.value;
    const [showExportDataModal, toggleShowExportDataModal] = useToggle();
    const [showExportMediaModal, toggleShowExportMediaModal] = useToggle();
    const [mediaPreview, setMediaPreview] = useSignalState("");
    const [rawDataPreview, setRawDataPreview] = useSignalState(null);
    const table = useReactTable({
      data,
      columns: isTweet ? columns$1 : columns,
      getCoreRowModel: tableCore.getCoreRowModel(),
      getFilteredRowModel: tableCore.getFilteredRowModel(),
      getSortedRowModel: tableCore.getSortedRowModel(),
      getPaginationRowModel: tableCore.getPaginationRowModel(),
      meta: {
        mediaPreview,
        setMediaPreview: (url) => setMediaPreview(url),
        rawDataPreview,
        setRawDataPreview: (data2) => setRawDataPreview(data2)
      }
    });
    hooks.useEffect(() => {
      if (!table.getIsSomeRowsSelected()) {
        table.toggleAllRowsSelected(true);
      }
    }, [table]);
    return u(preact.Fragment, {
      children: [u(SearchArea, {
        defaultValue: table.getState().globalFilter,
        onChange: table.setGlobalFilter
      }), u("main", {
        class: "max-w-full grow overflow-scroll bg-base-200 overscroll-none",
        children: [u("table", {
          class: "table table-pin-rows table-border-bc table-padding-sm",
          children: [u("thead", {
            children: table.getHeaderGroups().map((headerGroup) => u("tr", {
              children: headerGroup.headers.map((header) => u("th", {
                className: header.column.getCanSort() ? "cursor-pointer select-none" : "",
                onClick: header.column.getToggleSortingHandler(),
                children: [flexRender(header.column.columnDef.header, header.getContext()), header.column.getIsSorted() === "asc" && u(IconSortAscending, {
                  size: 15,
                  class: "inline align-top ml-1"
                }), header.column.getIsSorted() === "desc" && u(IconSortDescending, {
                  size: 15,
                  class: "inline align-top ml-1"
                })]
              }, header.id))
            }, headerGroup.id))
          }), u("tbody", {
            children: table.getRowModel().rows.map((row) => u("tr", {
              children: row.getVisibleCells().map((cell) => u("td", {
                children: flexRender(cell.column.columnDef.cell, cell.getContext())
              }, cell.id))
            }, row.id))
          })]
        }), table.getRowModel().rows.length > 0 ? null : u("div", {
          class: "flex items-center justify-center h-52 w-full",
          children: u("p", {
            class: "text-base-content text-opacity-50",
            children: "No data available."
          })
        })]
      }), u(Pagination, {
        table
      }), u("div", {
        class: "flex mt-3 space-x-2",
        children: [u("button", {
          class: "btn btn-neutral btn-ghost",
          onClick: () => {
            recordsSignal.value = [];
          },
          children: "Clear"
        }), u("span", {
          class: "flex-grow"
        }), u("button", {
          class: "btn btn-secondary",
          onClick: toggleShowExportMediaModal,
          children: "Export Media"
        }), u("button", {
          class: "btn btn-primary",
          onClick: toggleShowExportDataModal,
          children: "Export Data"
        })]
      }), u(ExportDataModal, {
        title,
        table,
        show: showExportDataModal,
        onClose: toggleShowExportDataModal
      }), u(ExportMediaModal, {
        title,
        table,
        isTweet,
        show: showExportMediaModal,
        onClose: toggleShowExportMediaModal
      }), u(Modal, {
        title: "JSON View",
        class: "max-w-xl",
        show: !!rawDataPreview,
        onClose: () => setRawDataPreview(null),
        children: u("main", {
          class: "max-w-full max-h-[500px] overflow-scroll overscroll-none",
          children: typeof rawDataPreview === "string" ? u("p", {
            class: "whitespace-pre-wrap",
            children: rawDataPreview
          }) : u("pre", {
            class: "text-xs leading-none",
            children: JSON.stringify(rawDataPreview, null, 2)
          })
        })
      }), u(Modal, {
        title: "Media View",
        class: "max-w-xl",
        show: !!mediaPreview,
        onClose: () => setMediaPreview(""),
        children: u("main", {
          class: "max-w-full",
          children: mediaPreview.includes(".mp4") ? u("video", {
            controls: true,
            class: "w-full max-h-[400px] object-contain",
            src: mediaPreview
          }) : u("img", {
            class: "w-full max-h-[400px] object-contain",
            src: mediaPreview
          })
        })
      })]
    });
  }
  function ModuleUI({
    title,
    recordsSignal,
    isTweet
  }) {
    const [showModal, toggleShowModal] = useToggle();
    return u(ExtensionPanel, {
      title,
      description: `Captured: ${recordsSignal.value.length}`,
      active: recordsSignal.value.length > 0,
      onClick: toggleShowModal,
      indicatorColor: isTweet ? "bg-primary" : "bg-secondary",
      children: u(Modal, {
        title,
        show: showModal,
        onClose: toggleShowModal,
        children: u(TableView, {
          title,
          show: showModal,
          recordsSignal,
          isTweet
        })
      })
    });
  }
  const bookmarksSignal = signals.signal([]);
  const BookmarksInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/Bookmarks/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.bookmark_timeline_v2.timeline.instructions, (entry) => extractTimelineTweet(entry.content.itemContent));
      bookmarksSignal.value = [...bookmarksSignal.value, ...newData];
      logger.info(`Bookmarks: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("Bookmarks: Failed to parse API response", err);
    }
  };
  function BookmarksPanel() {
    return u(ModuleUI, {
      title: "Bookmarks",
      recordsSignal: bookmarksSignal,
      isTweet: true
    });
  }
  class BookmarksModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "BookmarksModule");
    }
    intercept() {
      return BookmarksInterceptor;
    }
    render() {
      return BookmarksPanel;
    }
  }
  const followersSignal = signals.signal([]);
  const FollowersInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/(BlueVerified)*Followers/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.user.result.timeline.timeline.instructions, (entry) => entry.content.itemContent.user_results.result);
      followersSignal.value = [...followersSignal.value, ...newData];
      logger.info(`Followers: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("Followers: Failed to parse API response", err);
    }
  };
  function FollowersPanel() {
    return u(ModuleUI, {
      title: "Followers",
      recordsSignal: followersSignal
    });
  }
  class FollowersModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "FollowersModule");
    }
    intercept() {
      return FollowersInterceptor;
    }
    render() {
      return FollowersPanel;
    }
  }
  const followingSignal = signals.signal([]);
  const FollowingInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/Following/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.user.result.timeline.timeline.instructions, (entry) => entry.content.itemContent.user_results.result);
      followingSignal.value = [...followingSignal.value, ...newData];
      logger.info(`Following: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("Following: Failed to parse API response", err);
    }
  };
  function FollowingPanel() {
    return u(ModuleUI, {
      title: "Following",
      recordsSignal: followingSignal
    });
  }
  class FollowingModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "FollowingModule");
    }
    intercept() {
      return FollowingInterceptor;
    }
    render() {
      return FollowingPanel;
    }
  }
  const likesSignal = signals.signal([]);
  const LikesInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/Likes/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.user.result.timeline_v2.timeline.instructions, (entry) => extractTimelineTweet(entry.content.itemContent));
      likesSignal.value = [...likesSignal.value, ...newData];
      logger.info(`Likes: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("Likes: Failed to parse API response", err);
    }
  };
  function LikesPanel() {
    return u(ModuleUI, {
      title: "Likes",
      recordsSignal: likesSignal,
      isTweet: true
    });
  }
  class LikesModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "LikesModule");
    }
    intercept() {
      return LikesInterceptor;
    }
    render() {
      return LikesPanel;
    }
  }
  const listMembersSignal = signals.signal([]);
  const ListMembersInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/ListMembers/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.list.members_timeline.timeline.instructions, (entry) => entry.content.itemContent.user_results.result);
      listMembersSignal.value = [...listMembersSignal.value, ...newData];
      logger.info(`ListMembers: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("ListMembers: Failed to parse API response", err);
    }
  };
  function ListMembersPanel() {
    return u(ModuleUI, {
      title: "ListMembers",
      recordsSignal: listMembersSignal
    });
  }
  class ListMembersModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "ListMembersModule");
    }
    intercept() {
      return ListMembersInterceptor;
    }
    render() {
      return ListMembersPanel;
    }
  }
  const listSubscribersSignal = signals.signal([]);
  const ListSubscribersInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/ListSubscribers/.test(req.url)) {
      return;
    }
    try {
      const newData = extractDataFromResponse(res, (json) => json.data.list.subscribers_timeline.timeline.instructions, (entry) => entry.content.itemContent.user_results.result);
      listSubscribersSignal.value = [...listSubscribersSignal.value, ...newData];
      logger.info(`ListSubscribers: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("ListSubscribers: Failed to parse API response", err);
    }
  };
  function ListSubscribersPanel() {
    return u(ModuleUI, {
      title: "ListSubscribers",
      recordsSignal: listSubscribersSignal
    });
  }
  class ListSubscribersModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "ListSubscribersModule");
    }
    intercept() {
      return ListSubscribersInterceptor;
    }
    render() {
      return ListSubscribersPanel;
    }
  }
  const colors = {
    info: "text-base-content",
    warn: "text-warning",
    error: "text-error"
  };
  function Logs({
    lines
  }) {
    const reversed = lines.value.slice().reverse();
    return u("pre", {
      class: "leading-none text-xs max-h-48 bg-base-200 overflow-y-scroll m-0 px-1 py-2.5 no-scrollbar rounded-box-half",
      children: reversed.map((line) => u("span", {
        class: colors[line.type],
        children: ["#", line.index, " ", line.line, "\n"]
      }, line.index))
    });
  }
  function RuntimeLogsPanel() {
    return u(preact.Fragment, {
      children: [u("div", {
        class: "divider mt-0 mb-1"
      }), u(Logs, {
        lines: logLinesSignal
      })]
    });
  }
  class RuntimeLogsModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "RuntimeLogsModule");
    }
    render() {
      return RuntimeLogsPanel;
    }
  }
  const searchTimelineSignal = signals.signal([]);
  const SearchTimelineInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/SearchTimeline/.test(req.url)) {
      return;
    }
    try {
      const json = JSON.parse(res.responseText);
      const instructions = json.data.search_by_raw_query.search_timeline.timeline.instructions;
      const newTweets = [];
      const newUsers = [];
      const newLists = [];
      const timelineAddEntriesInstruction = instructions.find((i) => i.type === "TimelineAddEntries");
      const timelineAddToModuleInstruction = instructions.find((i) => i.type === "TimelineAddToModule");
      for (const entry of timelineAddEntriesInstruction.entries) {
        if (isTimelineEntryTweet(entry)) {
          const tweet = extractTimelineTweet(entry.content.itemContent);
          if (tweet) {
            newTweets.push(tweet);
          }
        }
        if (isTimelineEntrySearchGrid(entry)) {
          const tweetsInSearchGrid = entry.content.items.map((i) => extractTimelineTweet(i.item.itemContent)).filter((t) => !!t);
          newTweets.push(...tweetsInSearchGrid);
        }
        if (isTimelineEntryUser(entry)) {
          const user = entry.content.itemContent.user_results.result;
          newUsers.push(user);
        }
        if (isTimelineEntryListSearch(entry)) {
          const lists = entry.content.items.map((i) => i.item.itemContent.list);
          newLists.push(...lists);
        }
      }
      if (timelineAddToModuleInstruction) {
        const items = timelineAddToModuleInstruction.moduleItems.map((i) => i.item.itemContent);
        const tweets = items.filter((i) => i.__typename === "TimelineTweet").map((t) => extractTimelineTweet(t)).filter((t) => !!t);
        newTweets.push(...tweets);
        const lists = items.filter((i) => i.__typename === "TimelineTwitterList").map((i) => i.list);
        newLists.push(...lists);
      }
      searchTimelineSignal.value = [...searchTimelineSignal.value, ...newTweets];
      logger.info(`SearchTimeline: ${newTweets.length} items received`);
      if (newLists.length > 0) {
        logger.warn(`SearchList: ${newLists.length} lists received but ignored (Reason: not implemented)`, newLists);
      }
      if (newUsers.length > 0) {
        logger.warn(`SearchUser: ${newUsers.length} users received but ignored (Reason: not implemented)`, newUsers);
      }
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("SearchTimeline: Failed to parse API response", err);
    }
  };
  function SearchTimelinePanel() {
    return u(ModuleUI, {
      title: "SearchTimeline",
      recordsSignal: searchTimelineSignal,
      isTweet: true
    });
  }
  class SearchTimelineModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "SearchTimelineModule");
    }
    intercept() {
      return SearchTimelineInterceptor;
    }
    render() {
      return SearchTimelinePanel;
    }
  }
  const tweetDetailSignal = signals.signal([]);
  const TweetDetailInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/TweetDetail/.test(req.url)) {
      return;
    }
    try {
      const json = JSON.parse(res.responseText);
      const instructions = json.data.threaded_conversation_with_injections_v2.instructions;
      const newData = [];
      const timelineAddEntriesInstruction = instructions.find((i) => i.type === "TimelineAddEntries");
      const timelineAddEntriesInstructionEntries = (timelineAddEntriesInstruction == null ? void 0 : timelineAddEntriesInstruction.entries) ?? [];
      for (const entry of timelineAddEntriesInstructionEntries) {
        if (isTimelineEntryTweet(entry)) {
          const tweet = extractTimelineTweet(entry.content.itemContent);
          if (tweet) {
            newData.push(tweet);
          }
        }
        if (isTimelineEntryConversationThread(entry)) {
          const tweetsInConversation = entry.content.items.map((i) => {
            if (i.entryId.includes("-tweet-")) {
              return extractTimelineTweet(i.item.itemContent);
            }
          });
          newData.push(...tweetsInConversation.filter((t) => !!t));
        }
      }
      const timelineAddToModuleInstruction = instructions.find((i) => i.type === "TimelineAddToModule");
      if (timelineAddToModuleInstruction) {
        const tweetsInConversation = timelineAddToModuleInstruction.moduleItems.map((i) => extractTimelineTweet(i.item.itemContent)).filter((t) => !!t);
        newData.push(...tweetsInConversation);
      }
      tweetDetailSignal.value = [...tweetDetailSignal.value, ...newData];
      logger.info(`TweetDetail: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("TweetDetail: Failed to parse API response", err);
    }
  };
  function TweetDetailPanel() {
    return u(ModuleUI, {
      title: "TweetDetail",
      recordsSignal: tweetDetailSignal,
      isTweet: true
    });
  }
  class TweetDetailModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "TweetDetailModule");
    }
    intercept() {
      return TweetDetailInterceptor;
    }
    render() {
      return TweetDetailPanel;
    }
  }
  const userMediaSignal = signals.signal([]);
  const UserMediaInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/UserMedia/.test(req.url)) {
      return;
    }
    try {
      const json = JSON.parse(res.responseText);
      const instructions = json.data.user.result.timeline_v2.timeline.instructions;
      const newData = [];
      const timelineAddEntriesInstruction = instructions.find((i) => i.type === "TimelineAddEntries");
      for (const entry of timelineAddEntriesInstruction.entries) {
        if (isTimelineEntryProfileGrid(entry)) {
          const tweetsInSearchGrid = entry.content.items.map((i) => extractTimelineTweet(i.item.itemContent)).filter((t) => !!t);
          newData.push(...tweetsInSearchGrid);
        }
      }
      const timelineAddToModuleInstruction = instructions.find((i) => i.type === "TimelineAddToModule");
      if (timelineAddToModuleInstruction) {
        const tweetsInProfileGrid = timelineAddToModuleInstruction.moduleItems.map((i) => extractTimelineTweet(i.item.itemContent)).filter((t) => !!t);
        newData.push(...tweetsInProfileGrid);
      }
      userMediaSignal.value = [...userMediaSignal.value, ...newData];
      logger.info(`UserMedia: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("UserMedia: Failed to parse API response", err);
    }
  };
  function UserMediaPanel() {
    return u(ModuleUI, {
      title: "UserMedia",
      recordsSignal: userMediaSignal,
      isTweet: true
    });
  }
  class UserMediaModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "UserMediaModule");
    }
    intercept() {
      return UserMediaInterceptor;
    }
    render() {
      return UserMediaPanel;
    }
  }
  const userTweetsSignal = signals.signal([]);
  const UserTweetsInterceptor = (req, res) => {
    if (!/\/graphql\/.+\/UserTweets/.test(req.url)) {
      return;
    }
    try {
      const json = JSON.parse(res.responseText);
      const instructions = json.data.user.result.timeline_v2.timeline.instructions;
      const newData = [];
      const timelinePinEntryInstruction = instructions.find((i) => i.type === "TimelinePinEntry");
      if (timelinePinEntryInstruction) {
        const tweet = extractTimelineTweet(timelinePinEntryInstruction.entry.content.itemContent);
        if (tweet) {
          newData.push(tweet);
        }
      }
      const timelineAddEntriesInstruction = instructions.find((i) => i.type === "TimelineAddEntries");
      for (const entry of timelineAddEntriesInstruction.entries) {
        if (isTimelineEntryTweet(entry)) {
          const tweet = extractTimelineTweet(entry.content.itemContent);
          if (tweet) {
            newData.push(tweet);
          }
        }
        if (isTimelineEntryProfileConversation(entry)) {
          const tweetsInConversation = entry.content.items.map((i) => extractTimelineTweet(i.item.itemContent)).filter((t) => !!t);
          newData.push(...tweetsInConversation);
        }
      }
      userTweetsSignal.value = [...userTweetsSignal.value, ...newData];
      logger.info(`UserTweets: ${newData.length} items received`);
    } catch (err) {
      logger.debug(req.method, req.url, res.status, res.responseText);
      logger.errorWithBanner("UserTweets: Failed to parse API response", err);
    }
  };
  function UserTweetsPanel() {
    return u(ModuleUI, {
      title: "UserTweets",
      recordsSignal: userTweetsSignal,
      isTweet: true
    });
  }
  class UserTweetsModule extends Extension {
    constructor() {
      super(...arguments);
      __publicField(this, "name", "UserTweetsModule");
    }
    intercept() {
      return UserTweetsInterceptor;
    }
    render() {
      return UserTweetsPanel;
    }
  }
  extensionManager.add(FollowersModule);
  extensionManager.add(FollowingModule);
  extensionManager.add(ListMembersModule);
  extensionManager.add(ListSubscribersModule);
  extensionManager.add(BookmarksModule);
  extensionManager.add(LikesModule);
  extensionManager.add(UserTweetsModule);
  extensionManager.add(UserMediaModule);
  extensionManager.add(TweetDetailModule);
  extensionManager.add(SearchTimelineModule);
  extensionManager.add(RuntimeLogsModule);
  extensionManager.start();
  function mountApp() {
    const root = document.createElement("div");
    root.id = "twe-root";
    document.body.append(root);
    preact.render(u(App, {}), root);
  }
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", mountApp);
  } else {
    mountApp();
  }

})(preact, preactHooks, preactSignals, dayjs, TableCore);