From e0a1db690f8af6d72507a255e8025cdc3f57902a Mon Sep 17 00:00:00 2001 From: nimbold <11913706+nimbold@users.noreply.github.com> Date: Wed, 3 Jun 2026 23:50:26 +0330 Subject: [PATCH] build: migrate extension to git submodule --- .gitmodules | 3 + Extensions/Firefox | 1 + Extensions/Firefox/background.js | 110 ---------- Extensions/Firefox/content.js | 37 ---- Extensions/Firefox/icons/icon-128.png | Bin 18899 -> 0 bytes Extensions/Firefox/icons/icon-48.png | Bin 3737 -> 0 bytes Extensions/Firefox/manifest.json | 30 --- Extensions/Firefox/popup/popup.html | 62 ------ Extensions/Firefox/popup/popup.js | 88 -------- Extensions/Firefox/popup/styles.css | 282 -------------------------- README.md | 12 +- 11 files changed, 15 insertions(+), 610 deletions(-) create mode 100644 .gitmodules create mode 160000 Extensions/Firefox delete mode 100644 Extensions/Firefox/background.js delete mode 100644 Extensions/Firefox/content.js delete mode 100644 Extensions/Firefox/icons/icon-128.png delete mode 100644 Extensions/Firefox/icons/icon-48.png delete mode 100644 Extensions/Firefox/manifest.json delete mode 100644 Extensions/Firefox/popup/popup.html delete mode 100644 Extensions/Firefox/popup/popup.js delete mode 100644 Extensions/Firefox/popup/styles.css diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..56470c6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Extensions/Firefox"] + path = Extensions/Firefox + url = https://github.com/nimbold/Firelink-Extension.git diff --git a/Extensions/Firefox b/Extensions/Firefox new file mode 160000 index 0000000..fcb619e --- /dev/null +++ b/Extensions/Firefox @@ -0,0 +1 @@ +Subproject commit fcb619e73ced0d97194a148c26df593a1d3c6903 diff --git a/Extensions/Firefox/background.js b/Extensions/Firefox/background.js deleted file mode 100644 index d01ca1a..0000000 --- a/Extensions/Firefox/background.js +++ /dev/null @@ -1,110 +0,0 @@ -// background.js -const FIRELINK_SERVER_URL = "http://localhost:6412/download"; - -// Default settings -const defaultSettings = { - globalCapture: false, - siteToggles: {} // hostname -> boolean (true if capture is disabled for this site) -}; - -// Initialize settings -chrome.runtime.onInstalled.addListener(() => { - chrome.storage.local.get(['globalCapture', 'siteToggles'], (result) => { - if (result.globalCapture === undefined) { - chrome.storage.local.set(defaultSettings); - } - }); - - // Create context menus - chrome.contextMenus.create({ - id: "download-with-firelink", - title: "Download with Firelink", - contexts: ["link"] - }); - - chrome.contextMenus.create({ - id: "download-selected-with-firelink", - title: "Download selected with Firelink", - contexts: ["selection"] - }); -}); - -// Function to send URLs to Firelink -async function sendToFirelink(urls, referer = "") { - try { - const payload = { - urls: Array.isArray(urls) ? urls : [urls], - referer: referer - }; - - // Attempt to send to Firelink local server - await fetch(FIRELINK_SERVER_URL, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(payload) - }); - console.log("Successfully sent to Firelink:", payload); - } catch (error) { - console.error("Failed to send to Firelink:", error); - // Fallback logic could go here - } -} - -// Handle context menu clicks -chrome.contextMenus.onClicked.addListener((info, tab) => { - if (info.menuItemId === "download-with-firelink") { - if (info.linkUrl) { - sendToFirelink([info.linkUrl], tab.url); - } - } else if (info.menuItemId === "download-selected-with-firelink") { - // We need to inject a script to get the selected HTML/links - chrome.scripting.executeScript({ - target: { tabId: tab.id }, - files: ["content.js"] - }, () => { - // Send a message to the content script to perform the extraction - chrome.tabs.sendMessage(tab.id, { action: "extractSelectionLinks" }, (response) => { - if (response && response.links && response.links.length > 0) { - sendToFirelink(response.links, tab.url); - } else { - // Fallback: If no links were found by the content script, try to parse the raw text - if (info.selectionText) { - const urlRegex = /(https?:\/\/[^\s]+)/g; - const matches = info.selectionText.match(urlRegex); - if (matches && matches.length > 0) { - sendToFirelink(matches, tab.url); - } - } - } - }); - }); - } -}); - -// Listen for downloads -chrome.downloads.onCreated.addListener((downloadItem) => { - chrome.storage.local.get(['globalCapture', 'siteToggles'], (settings) => { - const globalCapture = settings.globalCapture || false; - const siteToggles = settings.siteToggles || {}; - - let hostname = ""; - try { - hostname = new URL(downloadItem.referrer || downloadItem.url).hostname; - } catch (e) { - // Invalid URL - } - - // Check if capture is disabled for this specific site - const siteCaptureDisabled = siteToggles[hostname] === true; - - if (globalCapture && !siteCaptureDisabled) { - // Cancel the browser download - chrome.downloads.cancel(downloadItem.id, () => { - // Send to Firelink - sendToFirelink([downloadItem.url], downloadItem.referrer); - }); - } - }); -}); diff --git a/Extensions/Firefox/content.js b/Extensions/Firefox/content.js deleted file mode 100644 index 661941a..0000000 --- a/Extensions/Firefox/content.js +++ /dev/null @@ -1,37 +0,0 @@ -// content.js -chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { - if (request.action === "extractSelectionLinks") { - const selection = window.getSelection(); - if (!selection || selection.rangeCount === 0) { - sendResponse({ links: [] }); - return; - } - - const links = new Set(); - - // Extract a tags from the selected range - for (let i = 0; i < selection.rangeCount; i++) { - const range = selection.getRangeAt(i); - const container = document.createElement("div"); - container.appendChild(range.cloneContents()); - - const anchors = container.querySelectorAll("a"); - anchors.forEach(a => { - if (a.href) { - // ensure the link is a full URL by using the current document's base URI if it's relative - try { - const url = new URL(a.getAttribute('href'), document.baseURI).href; - links.add(url); - } catch (e) { - // Invalid URL, fallback to just checking if it looks like a valid protocol - if (a.href.startsWith("http")) { - links.add(a.href); - } - } - } - }); - } - - sendResponse({ links: Array.from(links) }); - } -}); diff --git a/Extensions/Firefox/icons/icon-128.png b/Extensions/Firefox/icons/icon-128.png deleted file mode 100644 index 2e50ae623d6baf289bf554a3177d8f151e7674b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18899 zcmV)nK%KvdP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91fS>~a1ONa40RR91fB*mh07#AmcK`rD07*naRCodHeRs zIU%_>bATia2@;JU(xeI)1QeVHoLZ?e2o-D{p0fgl+O3E}46%y;_cufJifz4!Z`?HX?|9yGzEYk{PmaKo zBk<%1JUIgYpN_!f|3$wK9z1yF+}zxi)9vXqwx^RTrqju}+uPe`Pms#?wp==Aby6TL zMS^Vh?D3v}aSP zuTvm3Ny0e%OxcFb)|PcN&ln~oolYOXm~p#vx>Y{9zPA?5$glu`YSIS(8- zaByj9*NYMGD=^`o55fy36Lc&3?#ax7z;v>TqyS=~VGD^d6mjDC-(tvfK@j8rwht@v zrM*jYkTDHhmtdID34;kt4l7qg~fj`nNGh0 zd-^^d3K=OF+n%eH8-v^Siq;|2WHVkEEuIWe!xV68n>?|>8bvq-e+XzWf>6MyEM^{{ ztdbh_HbvPEMdGu`Qh^~$zg5P{P&~j;Cq!n^idb?-B8W#*j5|&rTPr~S^7{JfkK*+3 z$+Y}z%DK-5oY+e)x%}%E7Z(1@-2B{25YUoiM5onx7EytL_IL)I#+0cJEB+51W#s9T za3X+itn7hlDNIfme3BqH;zigDGb%yCPf`gRJ`*R)%26xBz{N8RmMx+!4IK)}9l;}@d$1V!5V+5iaHr7Rg`f)2OU4+Mm@&4yBE8CA2z)R_oKDE&X|T0w|x z22^aAqeT}!2mK7vTts6hFllgO%`AEaG0-y>0+7O+>eWUqD|PzPwbpjo+}is2jg7T8 z-+%x8#}o2I$%E&dj926-l!jX#vs~GyBI(k0n zI>C?!MS5nlXBB15tWmCsfxZ6+Vh2Ad0-~#;1r`dbGgMfQP4U#p2Q-WYSJs)*i2rk3 zI!9b&hJ(>CNPL=tx6rZH!imu{ZZf?NcNf3w#L2}CC2^RqF>31zGEO7F_Ootmf$&e74SF%G?&dkkmdl<B&hx&psco0>1UoQibxsqeuoK7Pe35iU8rn^{o@2AzN=ge}Ctj}Dl{Drc_O@gS0rvREj+S!X>63Evo3_i|UE766gVF8;d}otX5s;afGZvT0 zKlGc1LDz~-k(RwEIPIue)pm*)Py~fqQ}gJ6hl!KvtIt3Gz-yp7WokAf$ORW%e&O!j zb03&ar{|^k;3_EtAQHy3Z=@p`nmeU18>qmoP$HnL zvs_%5mUq2%wH!INU0(B3i{&wt^K%jDz&9B?@==K56a+Q&FBmWe^i8cLVP>w75mQsf zS}j7;`LhHzVJ3dLNUxO*6)8|`KQvh{UvSUid+zA9SwH19z0C8Xwmv&ha2kv7hu?Xfj%eTB@ zu3UD`q`do2`6M1kk+92icG7ULb9#H%qK(N@$W+oO4O@kiQM*#r5tljB*uorwri0uK z6^e%-{|_b>0YVKAjCO5KHqSeH^ysg4fLh&g0bF|N)2^ADPX0A$=1GXL*WifUWPv%2}$zn{icAn5*NlqM?_HE8La7cj+s;;C6CW zEi15}kvBmb(lC-LV(55;gN~sPVms9Mp8_Nv?hoOK`ooWIl(IT0uY38lTyr_E2dt;D znAInBN{Uuv6Rm#atCCJ?qw~)R<0dL)s*(n+N|pLX5eBJXGwQ^|#<5S66cahcec{5w z&Q-SSv&##p?ynNG8h{ULpj@psHElNbp<}i^iX2Q%= zx0=9RQ&r8pG{~X@*{mgzouTBd?OI@(*eJB|dCg04OaIhL7nPX>FgLgGO58&1qh6u( z{RC0v?kcs~#qO$e>UF`R(XZ$T!G$pNiAtkEBWH|4ZV9v*M5zb?^)*4KHV(mrAtjo$ z_&h~h+1xH$tJ~#EuGucnyc9CZ#5bJfecSdaVat-PCIPY#xrjz1 z41M54$a=IpajK-7lwEj|`&B&+>*EE0Bmd+T?pyYdWo#%cg%_qMD2uAZY`M)mHQio{ zV11Pw@UCbUY1dH%PMT1=j$HqPH~Cr8oH|yR+yVLDzh_$Z<3xv#)udlq+$t}6&K4E` zfi?(uGt64@*|Gh|YA`}Z53scX9TRWaTw|_S!4{D_4Cu2DRgX%dvQGrdj-W27z)(}>Z(4gAx}j$VWk;VF{CX)n!W6Obw0?EOlc>zs2gy| z-?ikzgS3f@jSJ7(ET`?+l-mgw0cZY;p1xU@7rWkqR!8VOOv_j5JMIifQ_#!1dRH}^ z0v?@Ann$U=``xfr4?9*s;Y-atT@9UWvwvmsEWEgbIc{mN0OseHpNS*DX<9&<3<5#q zIBT_;v&P{2G;a4g*Yg(3Eldb}Rd-`}x>pQwHSO`Lu64eLolggiz>#D;p7GbA-Dm@vICaiqis;6` z1k9GPXnJ7wG|RCO#(n?BM!B|^j}}0=TCZ`@d$ORKvAATO5>r`{@*L>IBvD`?*7blm z*q}VIu4w@pzH{E-EzV$}Di>1^OCrj+Gn~F>tK9T#T=K6WK0Xe{5n+3CQuZ%T%9*$V z(yMyn5@VQip`tC~C{<7p?LZpDv7jnS=_GM2&1fo22x9Q%O1ggO5yO;NS8G_5*To^A z{IkX#4^MWl45^C20+?)1E;TVHjhkD{-321mft!nI0Z4s#tjw#L|r_s%0-ZlYzAQL zB{Bh2=yaN(0ipS_1C70bBUT8~TaU_N4^lv?&qiUT70`!$v{%75EPJ_ zphy`Bo1IuK!f8i*W2e-~vfvJ5KHYoE%Qnihc<9GdKV9bYQlCUB0mNv0;ErioTW_p% z-k8ZRr!^?+h6o#^hGlM!&y(+Z5*Z!AR*#VSe}Jh^45~>h3`dNDJ{dcZ4jQA2Kz&^a z_HyIV6{I<{YP(e)9fB^Rc7<4MDx%&Q zjj9ANWoZh_$U2r&#?<6)QxdXXr8+cG+K!DLw8JT2=sI1rGSB_O&BO!&MwW}Ax?!cm zSzfgw?jeH!5xu@Q0Km`!W|Xma3WUueLPrybc<4W8|91JIuUNxp+goK57ypcIJ8oeV zDR`y}lk$lpbLAuV%#{T$0P-ukma*OStm!?<0@|h_wX;Bz<5t;%+(=8)*5en0Ha@Ko z8n&*shPadkUsWOME=Fse4^9ESqOWT(5sx@Xii-ZJ?s%%NI@`oqr+_OUDk#`RZR#uK z*!PjbCweEFAq`{o znAEUTFJul|B{T>WpBE$;QY*kfs&9eP1L zjIUALe*aXre~vXq45Q}L1!M7MeRa7*#c>Z56xEm=Ut=T^tuV9J)_q-&z=$jBhAOv+ zOFR+;Z4pshH3AG406rDBRS-9*Sb`BnHZjl*LwOhy$$H`v1+eC3U_>wl!v#a>Fxi(5 zxiP`ivl<$6hcDtz-@RSF{290c#G_wNK9G>phC8}WuV_qAc?b*O(Gz+9pZx#`d<*j| z)g6`2NDxx>n~mH;ZXhYV)gt&4j?$78G!x5{s1l?>*rfv#RhCm4H@?9F&=D~P$X$-O zIbxZ*s=a&oJ^G!JHqor-sR)Q-ZG;4dJ*w68MM(-(X2Srtkh3yWl?`0!Uv*%sTz=L@ z*~S{s+UEM^mVHE-ivVA>jx~}Cal7!r(T&gCEEk=_@7;}Ec$j0I$3%czsS7B=OHI|& zJYm9gjZTq^yV4Gcx>gd-#!2Q%*;%kUSO99Y8L7}p07+l307wIFjC*?c;)=D{goS-yBRi4;xskKn+p$#H&*Hm=?9W(+-852sY+gNj)-3ow!J4Kha z0qBas0+3vXv-D~*i8><(5(3>$dC)ya8RpQbCkK3}WWBGEO_nul4k^myqX}EB>&a&v za{Q<4Y3E|*DdeU(WCc3uk+Hw~lR;DYh&EgU(B*v8$%q}*^dJ~2FRQcmK*kP@)e zxy4)psRE&T&7d|SV?~*JhjivjTVjo;1e-8s6GPhe4r(108_SdoS|GB4pLEjWQJ-A^ z9iZ9-aqz zKRELOFkqFRZRqBKf6>(&{+191p96N|)7Hx}4jv0fFfW|~wP2`~7Bx#Cf3W%hw`@~kCc31#396Iay>0#Iox-iooTFrq)baf*X zI6`Yss`r_-iJ~SYOxD^{n->XK`B2-pA7dO}oCZU!bd9WdIbY5Hjj2kQv$V0Zt>7)HOZrjHxp1#%!f6 z>QXuuTFfS5Tij#)>;e$C9oRHYqGeSI6$)P=SC^r)+9Bs;RPaDcX%19&peHv+m;lQ* z^_^V)n6ZOUDY4$kIJtTFXUUn=)h_GUXs71@IAWZ(U0!#?dO3-Yg!k^6mb3QH;gvBg zgmc&ZqNuPofz^&FdqQQ4DPpEf8*`*8j&?7rqFR9#^+rmx38T{cmMF(d6g`i%%x4z> zg!Vy$+z3UqXqtu<*HYMQh-J!&>ao7kPfPLjYS{Q6tZ6M-pU6>~MD)eIH(qk~nfSjagBqaEzMW`?6zjut?ploKIa;6sm80;MQD zk@jQ`?=jH<^`g7a2gFyys^s_yOlvXJih^ia8?68`1pHza@I10t5(IPSgZyeE6e5Hw zIaQ)xFv5>A`mr$16TB|iTHP$?EUlNH`5L@3z6cB+BAt#qgztO-E)aP=p}r)cIg^&& zW45i3Aa@`ddODp`Y0K758Oun$GTineqbTWOk}y#0KdPK2CJm9R$_ER8gXmN%v;9d3 z9FjA5LyAeJsj>q^&y2lC?5!i~5T4M#9+s*}5Mr45A<5%eh|G%1DbCby#KBlum~x>zV-V(5VbPj|$v)E4hW2MJ_*Mz5E0g!2-@K zo5V!QxUxSi*)jJiK&h*1_d|5gw5K@c)q^7%-g22J+2 zru0vNY~`-1v*n4WnEPC&s729J3149xDAPCFRHE#KG(=*q8nUc&XMFYrm?gaK^92{; zjbGYfip9uGd2g0U~yI3T>H&;}Jx2`9J8>z}_?o_85OEW!c{ z1C=uEI>a{hF4d@6#z=wsQ#Dx;TQpD)lIF43LyGaCuICaW9H~f>bb)fP03-)ezQSR} zra#GZ--ov10uXwI648*+tQA~oS*d|L%Bl-S_;9VZyKeG>o4re$<%O5vN)0c4Jnh`6 z4$;Em(7&QV#ePp))>$} z2cyn{gmN&bp-~}em4GZ|6{vws3TKk15+&i?=AF$P%ryjqy?kZ?#N@|xRafRvGu^od ziLXdiI=IJ#M%Z-Cz!FViV%6$+t!UGdh|wTfBsm#0e<*plfBt2ggY%%6V? zd(fSUcAI#Za{#EW0|Agu2T^j7aPs45!0!#{g%B+aU|_e2wf4M=Hp-Xst^ocy3icS` zu>iE~lh#%YbTcVsQPMU=)ec6j4y^!*8kh9YVREcH1|o(>fMi$cZbg;YnN))u*mW?- zlSM-mWDGS;H2IxL%&hbtRwJ`}gqj9gRQPf4w}1XhnQ|A!BysP|FLmIDz;xlJ35|2U z*_gZ5yAG#N;Ya{=Zj|df(yLC3fUlH&$1SlG zr&)`cHX~`qC~@jgQochPE&u`mBvg3WI25UvjZ&q}O6^n+jL!8U)#V8_lzo7LQ)jY7 z*_;#am{zd&eaX|;%L^~(OCQFruH(&L?7@5zcmTI-*PI6sFXBYfE+nV;jUfC+6rS~C zqd)rJX@emj7V&~WC3tnMfK$Qs2iD7_XY#hNx1}roYo+5J=F|&R#ge#XF49mV5Av9&h}jl`@CDky zrSR8rFFzaK0mO5GZ5#kJTTo80LRN4z_@}?WTz=`#7s@f<@N;smrgy76EryVtO5YLH2y5phwGLPNyM{Yb(&fkllf1yqZ(})G|(|@#7ZvKM> zeP3W12RmLT-1Weuy#C$0%ZHCF`3OO(+_)IHyT|R~MAsT@V*~ePr*DD7ajBcMi{w6{ z;qkAOIWUA89yNBH5(|T+FGh+Et_WmLJX^s--(B*X-%T($aPd(vM_k4Y)78SGB*CnL zS#GF~;;aPXPIcJNU_(wC=(?5+*4zTPD!+WoB2FD12D;`X@yXt!E7S6eAHs?NiFOiFYVrY!BZ3|a*9Bqu zS-ZB%63hkzE@J2-u^$vUca1%3eX~jhg2|Bg>4V>=q)v(qP z9{7y5?_^2_v~{{@F{+j@yRQS&#H^Xwht{T{w6!w+lu*a}?g?Jpz~}bQI;l_U^u$h# zcpQwce1A7S&%YjT1M`a>{9zC=x+@%lIK5_l*ie{h47zYKEQ{XAm0-+FH# zU3btl(YYF*3GBjYfUk^g;6o?Sh*C$)-j?=El;!ZD(f5A{9{}6jL);&YJzm6yHMrTY z>ViJUDWEByy#}Br80un3SsF_p%Y${ubxv0xy?ZKX>|~8|i(8&nESpK_V^!1R3I_cZ zxVXFU3|#o}PbP7XL?Utt`So~vM|(cn8Xz7WNQ#j=18?~(<2!&WID&9FX|TdE?;6hD z0}Grc+G!HDnpHYr9VM&GXa}1n4kZ;0N@PpnO9H{u#&pc9gv3ai1Jz=@Stk$F6)T?& zDS1=MIz2?A7K2lOq%=(9EW=^7sz5-6>48S+{0A|^qPFjQAgZ6#5ht`rgOeQG;@=*8 zM*me;^4t%h9?n36y;d9V`0}EU6R!=vQS##MV%!!!|Dw&pZwuFm0Au1a@>k(GKZDKK z{eXx(0K}H31zqeybqt>m@L^P+OzFJI*^Zu$RM|IUq4a+iVdDuPPQoaRhYkZ|Y_qV= z?P`>CRw|!e0G(1*#T`9ablD0% z^&=KKnsO6g^pRltjD^LZ4`MyyPfNsZ7vEUYjQ6Gc=l zU=B>eRMvJ%4b2bhn&He{K=l(A35Clcm)Z=Z1rvbiyyjG*p<%OuoGPg)Wjh3trEiNF zJU{op?)(jWeH(+E6On|PeAwjVpyVXhSHQr}JA%tj-!2DF!%HNzgN!a&|GcMc=yw4a zzB)xd)sfK`Y~@q3&;jsqeA>vk7$0r(F*MmT(PWU=zuc(k>U6tff}B1W?=S^B^(2zs zC9!HMXCt12bObX;06DN#2V<4Op`x`kD#lkBDz)d*U7QCa9jAoEBwV0aY3gsm3KOI9Q|0Tzu|)jCWfI*6*lO^vcv?6 zN+htrQR8YT)*QpQKRX-&#KkO}Ig%=MC3M&i4Md?mrvvLy$hH-Mqy=Rbw?idqppl%V z>j{KdiGSngDY)&@y+0>LoB4FUW}9Hic`D%h{4Pn379Rdg%F(r{Canz-ULZY=eE}0% zA7qiI-)e(${%MKr^6<%N`S1htWdTNvnG>+JJzw5{&nEWbbuzBYW(EwJOfIA4nc?(0 zLELc7hEjg=*-KpyDSdU-Md?!|dWQuO>P7P{F}K9?2k}tWUgPL^^tMf+vOCTN;G*!?6G| zb}XA_&1zk2mh*1m1NYCBPvOXcswSTXYq(Ik_Kel?@+hGH29;lUF)gvW%{ z2R>AD1HUN6<bDe{fDs!a{>7G{iuYHlfaEYZDGVZsusHb01n&z&%sm6bNIunbLC|J z1~C;j7G>q;BEWV6PZ|I8&_cmC$Ld7#ebnb2M24%yYtLLOmz;(#n=*z-wV!C$;gYTc zC0L@ABS1|^Dp9gu>RZUVHb>ljhR3iQ`U@KrGYdeRX`eHOwne1wy+%i>z7f;FfjAcK z31%UN^_GZBtTj1Q_LY6-FMQw5mpp+Mg5ZAQv!2v_sMLYzffG|5JPaYgzK(6ol@oY+ zs1KDS6&$YMq#Fm~c`bLe@_r2sEB~si=UZ)<>h$DfLqDE^Bd*4_@IcNOd8=} z7_$57p0cH6MXl#}Sdh6nvZb;YfkSLTnd27Cfmt?23&2q3o)YBf*cMi_K1Gt6GMl?; zq+LToAvXnvEJU)Pyc6U!OGI4N+b^-ahzl|S{_GHUIr0LmBLUQyT;8I|o*d%wxtTxt z#+OFs_{?*Vf=pJ1RwFv13QP0iRXZKjOq*xU}4|<#8J0@ zka3__w&u#qE?FtpV9(#=gC@lDY(B4`QTVC#8e>RMa1;}&I%OfMio{Tmx-=u6Vi;8w zW!ZpKI^D~fk@@IRFfV;XV+0A6pwxRsoMu1Sj3B-C(3y^*KX;3KTw1dxg`%`;#)y?ADhGGI{xB$ zxf>q_z5UiH&duSBb}*vdNlfUE|H*Rsj?ddD^KiU@7fbMsf^yAScn5H@sp|t?WAHYC z{?5X?2z#+u9>P(BkCv~%N6J5l&mp!}d7bV3>XO}?h(p134((H&?EJG@$0X3|kIb!U z{cChP*@z37E@Z=qF%K?mgJQ4%NLIfbp@3Q>c`gY_rv0v^d#74K z)8EB=6`uS5&g~23k@)?dLwNG`-cK%;Z@YTMpY_u)%{W6iI`CUT_W<|R@7!1J#`gpH zvIgVlUj*Zwgud@@hsxP+ek}Z+JC|@_x2%D}pJK;d;avHSt5?fUTz?FUjokEwi$!pq zv#?&CgT4J7cQ2O%d$-Hmp8r_65EH(RI}EK5EZ#HlCu;K=fsQl|p{`?+u@48L4O8eV zo|Op20l7_nQ9v(9U^paBn%!*F(o3~ATP5u{p`KLhNZ#6P^(otFO&w(XFO@B;mX+G* zc@Qk*`|y)3UwQFy4CES)s1B94T)%MJvhU@wchwGx3u_!DUETi3eEH;~6MR(bH-)I+ zRk{8;C;-ICM45f_$iR0Cc^$BTllvSH|NGD!p7lqMF{$~e8BY?*_dI*OTzAe|`GvoI ztUUibOg{b?rCuG!wF*mo_M`f4g_qA5FM% zFDGsl&l&isBfe}@&fSGm0+!$48UubdfV=LDweqf;j+HMwbG@u_@`2Z;g#tcaqf~b> zM(8|`MjkIUa{fA`$IRo@jaF1ybW+vX?!65F$t)uV*V5n=zzY}b0?1m}gtArlGzw}O z9#(2lGB9Wm6r!35v~sZmEgj)MpXXePPw(as)R$khQhpAvaOFi8pS=CthnLGs4z88U z_u_*cT`0m_e*Im+tM+e}pTF^Fx$7u??J zZt=EI;_pFW0Y#VSI}_|^dinxZ0T$dkuImsA}hjsHX5W>@l@8L`>8NrmhUMQ$(Z_ouI}|2|Iv5%(}iwH*0O1 z(E{KpAmSL2gctCr#wzvNgs7fAYvPL(%?GG$G(_6?rGd3 zufxUGFWhjnT!vG^$|jBs*yTTiKkp(;P7o&{CPIr4bsrIolT!t1Pmo56&Lv)p#@2l`@+@(&#JJa8RB?6=^12Y3TbF4Ze!)GMhpM@Uel(p9!9KD3gduEFMv zlb@+6+(u4Ss#B;%o(+_Ybv8vDQAjU-2{>^4=OlT@kaBt!N_JP<)!OX(malp7zP)CJ!g(ky=Y^g_~*$pZELYNkcBrEIv;n0Qc01pXb8i>7DD{= z!-4zs3EazL5j+!nJYV_dy5WPC^YPPdH$V5$a?`nsxIn}yg0FEYP;(HdSQ!=%C7e{& zfpIVB)L6Quifxr#OpqxYLb@$w?i=vJ5fFF~@EV%#e(h6>x|$aeiR~nd@J=}tAXdC} zu*o=1K~Tl^%O-7G>gyqeh*F;-8j`h{1wdd=A-5v1w0D*vv1~ShOF@F@t*>`YL3bN~AfEouSioE~2MX&$cHaf`-}a5s6827HZ8Txe^?!VzVd8BZb{guj47iNrv- z0C@Q49!^+5eFUMLKqOT0A1R0k#{Wf(C=dO=hX+V}3h0F0hAa*KL|_w0)gHMf3nC*?)7_u5xUXx0+RITQu9`XAA+Om@9=FXC)CvTtFs6g>_`iH~zP#_yl3%vu zv6U0dJy{dwwvM^fF?KBk5evt|z7ExzM6x1rak}Ol4QjN9kefavfG`)8>}{nBDYkR5 z5RZ+IoqzvDs;#_~dlTN|6`LGc-uzd)%cFRYkI&{c*%){o z2{Z|mp^ZY5PcCfwfhV3*wP<+0hCdxGsAoh>jDe7dMYgb^oosPf*5nH0w~KmT!A%Z+ zM)4?4SwDu)Db{IA?)Ya{B+rC8jpR3FEFDinW(_4Nxgk;N@sowxQb=d7)&!PH`WqlA z94`Q!c_DTDc7$ezL4!U;JOjX>(>*w&?`1In4lM!pegQz8D3&WP;P`N;^u?rz!LiVn5@z505I@H0Q#c%O6K(A!b@g&!MuVe86I^lrmt8Cft&*mEO-{gALEBy? zE(>@;_y8UXeb-;?E4QEEVHR=4L~zpcV$F|aVJKZJ2J&DNo^{$PkWoe9rBsok+)8{E?FyW+$L}YUaxkm*xk&?5dtXHtzC+Je0;zgVaZpUk0 zuleBKat}TY#G{s&Xdp0II`wMeVH<~kF9hf@u{u&Hh-9RP=Ee4iR~+4uBw&_X&x`yu z93j5d_c=ATq!(*ol;;EsLXJkR7+7(!@zXqB6u#z`edT_< z=%EWP(`n)~N!*L|2_E=S>b{ip^cQvDmjJiq069~(PiS(X=m0~(@B=FeB>lnNCyy9-bIe*T`t@*nP9#^f`wQQAQy+a4xN0yBsn zFscJ0RF+hyIjYH^wSg?wh)61|RwPz7TmT(WgA8ltNOz%wuy;&M?$Eupts-a9M=4;> zo<1z=dDwG4X!(e~8xi`PM4jo=FKt8uv1MT(VJ{JT*we=CYAjlF@#z~kGARcQ zPX~Ya@M8JykM1px;mw_Sc;ke{I?xdyKd1M12Cb95XdS!oWR0VS!Y7Z~j*ABwF1kO* z7612re2-oS)8lCd#4QqkX(Z#+xjf0GN6_v*TBuOh8(S)*GmWGW)dlTyBM6GrX@NjT zbtcwRpR&FjEC2!>Q!`Qg90*j}MMwt5QdZ)$6|wx^Y1o!MVb;q4q2?Y#y`RVt+ctK9 zuWK#gUVGm%zjkdMY1mW#GU)qpBzVKe_m<;0KVwbEh4jQ=B6HJ(N@0kg(J$i>v-%2Z z1`)PgR0|m0d+{{#4Y%#WcL8w3fp7JZ_H=<+=Z{yNwv2~DI7R7;q0&K5uJB8ro+4SR zukNrlPneIXWI$mij#wtgRtKbq1!S-Q)Zw&cDT4?UO;Vdaon)Evw1Fu*kCDs2C|0>f zLAdF>v4JNN2lC}tu9tUy!z1N=-+HpVBOZg1Xhn%_xciid@&kA5m6#o4-`n`1p$Xx_OhpFmKI>W%7%mvy5&}map6dU}oy+C- zapB3u#=a;{Wq6ewtM29a$=Wx6@djdCFIVqhD{s4L6F)_R_ZP^=Sm=uQXsF$Zg3-Lh zB2~KtQy4y}ZDI- zT7&?SbQuyC_^20ycf}c-<@723U=v^N)H{Nc^6Yc)5(o~}jHSiH3$#i3<@=Y*kKT>X z4WP+$v?d%}bc7w*i-OHj;$-m*poI{`Jn!H9>80{Z;N|J2CdG{YppU$JcozOhHIMuJ zzQ8(ePtU*$rWfwV`wArNqO4bPkdnfT&d0;x9V{{7Sx_R!=+Ms;9gc*fw8H{$Fvf9^ z(GHR8Y*Wy0Xp&pF;gm}bom3`OUU`!ybcv%2&Y51{=B)7wo`Z=xfALH95kp_+g#Fw5 zc9nni>0SB^fs^S8#e4razMqb33El36E!{fwNjVR%p$khHD*Vf%|Mkd1`4{)#ihn$I z;C1pM&_gE1$nS$A#!Zy%7C4M$V?#-jGvqAX7cx_c&Huf#VNm!l&4{W;GY*&uR8Tie zaxxU5HCh0T#4MdFszNXHWTehp^Y;k2+A#uW9ec0(jlQ70>__SX%Q79+%*+guVKlRb9OCDxS~y{|Ha` ze&DX%=r`Z(BQg?g2Pya>PX2z8eyCEo1iQELOWVo^z4}rGh>bSGiB`Zt<-!>8q$$dP zM09~cValPFpy2|DUPh=v0@iM@(^n`}$PJx@FsC#pWQR#HK|c zhg8NUIQK+Vz~i@y-}|n;ROxj(uDmEzr6lgdp&~rgKp^VtvZbimvlFzUq(TQ# z8BN_F{@~II;5Tz(%PV;fdJd2+(~Avx>fmn+eE*$$%WprtP36UUnl30 zikm{Jy(X$9h=&n3Rb9yx5u`*OdUWa0w9ctVGKx?97dc?;e>_`osX@lYYd%%jU7 z%JhX&Z!L4uxf3x?lspnu0*D3)D*9t$nVSv5YnZ35$ICEa0~;#BPMCoaM#k5{QZXAW z0PIx{riMGIFEAhpN6A$&RB2D7#FLV`K@hd8)|!W;xw&dL$Xzj*^_ciA9#*-bJ)Dq? zY-9_+^O*F9@!;n5ckVB@;%@;jqs_k=@H!mw58yimUw7_WdH&vYo%?y`@YcI`m3QOm zBCq&42J+)fjr8Q;+-u78013SL_R%(f%aE}T47fD4Ec%{Tj7E@Mpk3Ied5W?mDDfE! zOD%rH+s3EYs*c}NZ)vaqAii6)j3A;2H;Sj3WsTu5Wtpwcs^b!_hq8{%=x796g;CFe z)hPfCKIze|m3@gIt7F@c^9uf6{2csuePUm^3qJ!>H$kSEYYBG_jgpeg|HADe2B}XKbt>|i@ zPbQJjV25PFQ1CJJ_Psr7umG?(-wM?ROXNeMnyCol_=9m#if*Gn1(0< zLW{8tIgHiPU@SE3j3q)Fx2qouG8Kabu(h>u3!cYwAFBjoCnVKjUxU(9xjqmx$OzP& z%wr=lw`eMGQ`B54X1uK$onHl_E_>NICYL%~wF3IXoTK<9&pY>(6L8LZb>1@m{$q>f zhd#MSHVO&wj!v!|CwYUr^DSSDPq%;2Yq6$tw8@~%RBZTPwp~)@VPQT_L4ZR3SOU^- zYV9bG#j?GPKd@9j)H4qjz@bBjZpVijpCBNK1!e=uGIz*1i8W-_BCWDM_JuuBo%=Q zfAZy>4*_urj`l8>*W$Uy$ME6KA)FHU1d-R5dTWTm(O_tdwqp=XYCQIZ|1&GdFb@C# z2{B1TK~$Hv%NOI%$F1TUOqx)_sAtSdD4VGz1PqcV-=dNK#Em#oJct!SdL8bH?hHPd zdpA_-X4;My0IsjLeg)^VH-ZGelvn#>RtPnhY29_AUkIrlmH^W}g=o@T?GS1%BYbxO zzte+za@}I_CLR;OkAt7JXQTY=b5E9=Ke1FE!ONI@er5jyBEa1yFZXJ-0y2Tohw!73 z{JEHCoW_eI-oH8N`M$!<8{^ct%(%&T1{UIXU39WswP#bY@!129EWEHhhOe$g2*Ys$ z4LO)1957R4|gbyDagAY~ zw{t687h#ui^3yz}E^ZGhCd8`+u3|v|s5gH{Z3p9^$y;wcP}jmjNzOf3KuZW<1$O~- zM;YG^KD0JhUi^o9>H?)M=ga*JZrV_%)M~XUL$si>mU#+Yn;B=rMUffC^LHM6@W@NX zs+l7I0Ju|_ybaGsZltkX^*$X%wn-6BsHvj)lCfema29k4(qe46(e+`j!5 zz9IY?>}C9wFU14xDz61FGkb(&CZbwMthi9)45lGxD4@Im;#%Qi^Wup~#Do%_y`e6t zAeKgi1aT1(4FHc96!GV4ejVQrJc8HQ`K1;n=Kax=o`#%)1<-Yk3qY;cX(2X&szkWp zsD-t%pKRX@al$Kt@$Qu74;(o7-nr@Am+)s|YXI!0D3JMowavq=1!E|wj&E0 zOpGS#E_@U?1NZE|c(ilE0e&`bYTc-CXa7zMP(_2?)OLBof3tSCJ!(1qHr8+V8y z;6!CBIw4r!$&_ONp*xCa?C*bgsa(8kvs}8gg)4bK;bZW;P+@@hlvgF6{ISjV11--s zWT3UquXwe3FOND#Z4QfH{IKH-puGFwt6}uP&zI7kynNWi{r`OrE|fQXWEo!+!Sw}$ zuYF~Gl)#ZAK@BLh4NwG7QB$HYiZZ5G{DasdSb?ZWh`+D5`RbD=Pu|;WvOb_rVU`CD zT=XgXIWE2Np%HB0vm~S~gD^i52TO3FC6Gybzz{eeqeF8QD8}ds#$ROmbR1FPepL0bGF8To5{NV>4c;H6_*da@w zJE$aDyx@X^@0g#P`?9>qBXJFmL6gBk7d0>ekp-ZS6?Fz`4RQ_=8$Gs~hdtW7HRW}{ zCU7%nP;!jYcz~)OtpEj~nC)7*8Ft{Ru>mpkZz3PLJGFa)>L9@R+J6Vw)f zWGg`v)A%neY*fejObIeYH|4;=Xl;PK;kJ0~8+9xttJY^;6Tbh7ljSWVB&MbI0J zJJ@tFpgkaBObp{~!`UXl@<73!8t=9ECXf!Rd6`d4vkMCiDqlwBAjq~K%mk$-oax6U zsbjmNY_Vi5%Sz-)>};wA&=glIRvc6pl~Kb58z7QNZA|5UoQfyE+=}jhJ7A}rd{SsQ zABU?PK79E8)wS(c;nv``ncZEJiymc(F1e!_Y_{#8wP+JwYspGBh7m~`Dl!lE6=FlF z!dg#0&RM@}l`QPx zWWrymDwEr=pkIlneuqZjndTEN09qV5a_=Ybtn(H4TfDc}!3@tRQ0gP7fM&~s!$?OQ z*-l{Cr?^KOLQQI;WD&Di7YV?LOf+Nj82jjw+_?~B06Y3=HWd}p&;);KS<;R<7om0< zLK|FqV+0I?hzZ)JqkWHIJ+-L_Jqq?23+PsyEMI}i*CYL=-MMzEyMP(=V~;)d(5~IP zejN+o={OxcU4bYD2a=s`5mSzkX5yp(X#aQr5)(2yXJ-P*CK5d)P=Zm`bRNRiRt#v8 z!71ai56Kd)5}E(csHhesH6hRur?ZiIlr{fWm}kHS?ue<1Ny;tBYDFTWkz>zCzu$vi zel;%o?oRX*m4EF8K%(PFM~^=Ct9$nBUBTxC*W+m+{z^^`tXHsBJ%yQSud{*#xZsXrfP>Vh%ZlH@saE*H~FzF|l zPP2O`J;Ai@6~RqCY@t1lLq4wdkG%23i4*)2n1Ai`SuKEI-8y#c=>OWcf8TpBP#3`e z(>>{}iy42L-muJmoH9HB8ciDr;z=4QSA7#UqgD%T+CialRvV29WTg#r^+8-`Tj4Sc z1%#?GL%m^=WoKE_j%rDkMA_ackm_^tTR7x@8}|CQgKg$P&&b0}Q!ZwtpM~Ip3odvu z4nJ?iBKT4a2Yx<3UWLjLNe_cgVPLY|`|5?9t>EAx-BSb+#940?QA0s2X}l5jYN_}-_Indep+IaWBoT`m^GfBbI!rb@u%9ZMX=AnZN|lboQ>-R z?YNwTVd@5exA!~Umq5-BTJ-k}s27erUHI{FUH^n&=m)KIoi0)Gh{eQ*&Z)KoiIF*= zG-Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NQ14%?dRA>d=T3d`=RT=*GKIhD> z)0t8zooPGM(Ux)(3{u*12^3yTh%ur-M6QNNl*C{RT8;66c;UtPVB#$rLohr@K@%l0 z1~vF#8j1!)MQDpHl(uv_W2c?Y%$ak}-rMi{{`j&Fr<;f4{7MUG}tQ|Klxr zFaO8K$Iodr8dnrWav}JJ@VqC#Ssv7-c;}W!FkriMjNU;jnJ8NnMS40(^8Hzsy?Erv zk?AV6I(}D&CMG6E>h+#4m=&K&EE%Ifk~nJ-qy?cXBEkxdqe7tr(OJ;z*ZEwH<2ZI6 z4nP-?e0tu3^TOXnI!2?(ZeqE0etTrvn|^5Dy%PN)5uqeqYazH}A?nkw6-O`C2^)B3N{G#Qpb zbo^1{D{#9rQOxOGe#euwQ7>$+X;!Zh*VW@X<*Bgb4O$c^6St%hRuK7_JkLIkAfAnM z7OUFEjTeu?`N!yd&eTz*99Aag+lX zbWlrN)I+4afnij}V4Bu`Ha0f4j#}8t02+<#VK_ft$azp8RVJe1uarjz#3Vi94{iyO zLi536i9K>xZtKo1EXyiN#38rJSgOXBb21p}=FFg+HbB>|VATWIvSrJ8K-?*Z8_AGB*;dGoi||cl1D%?!3g4x zk&%%#O+lKqh`g($sT?0X1#XXsmcBzpKbbK$jmnF7^3KReisucw2hx-yeDiI_*twIu# z9SsD4Gtg|AU5mwg$JHIPW?`pixsaXF-HlE|*;(|tI%o|naUIZ-2U84?M*-kn;e-r@ zDvG19%#yQ0q~m;I;|aTJMQ-2t#G>^h`#hXqI+)u0Vl)L#37}JIDd}2Dv@n85RP)m8 z;^2b-FQLfAH_&8uBa8x1S59C=#5@Xy41X3oiQRug+b&txwtS(myj9qT0W}c7ZCAAIvh|r=a9)NWomb-2BR9}# zOb8F76Wk@LtQ{>|T3mqZ6&A=)L2MBU+9EBmL@c>uFnphyhu_G4N(X?*k@33_z{``I z=fZyYTo3SGq@^|RMQb!eyw8wC1Y=b4xU^Tl_bgr+bOBdE5wz%?#$8G@?z4ph3w!;C zHg@dbRAQ5}FhRMFKYh@@eWY#MHgxRMJ6hJnJ!wgkx9+l2Ds-T$!IaU2Z;ucLUf3Ed zdP={$s=~r%w&+~>_JujvliR)97Hww1?5+Pm9|ciDdu(wQzLWmwHTxv$-ldbInBCwvM)~7e(1%b~?GG zH9V{(27(~+#l%)%O+0i>6Zr~jt822fO_OR64ekJhM|4V#CAb_qiwA%)8C4D;WC?bq zqhwX1#=LqD^=9_D?F%+Lm)M1CI<{qXX03K=yI=0L-@e+=f=;p=+bXtP%)$ z9XOfV)^#1bcC2HlDm2K-Irk8d;#L1*oYQM zkayuE=7lWLm4Qw=6M7EZYhi^K+V4RdhH{*+sU1f-oR4xTQ2(z?*X`FY_Sip8)bv@o zfFK@yq2DHkGW+C2%f>KcylPyzHnY1nE!e+L)vOn5h0ZUrP5+e5W&Qw-2}bjM)OR6b zz${-&hsC9iM_f4O1XJ%Y4zBwynYTA*Q~UXAecIO(IQBY9*Z+MXi~tEs-to;}pC zr}y>P@iQ=k8M$R_(RSZBYv*D`*HCt~XcKQAvX96(Dv4dkFj{gBETKdoWIW#GiN=nu ztld7|v>R~m|K7{}b`XxUlx`kbw7s{VvshHy@B6ge~Tz%TM z;_x~+gO3(Ck^^6dNBsms>xZ%$K5TOAwz^h8uEX65EYDBYwVRO@*3?T3!wTep2;OlE zXDio$VGT$Hr6dYiN`xR%SiU)J)A&UE>+y!&yrF4N>^P-w0cKa+V8~ITbVypcGjSV5 za0N>j#-*c`+A}D%1^~BCn{IEpRSyobAcSHE5N7}iB@jC@L6JLvd=sxngfL9(vDf>o zg+0B2jQ3(IVfKsQtgke8$hTO~!Zu5uUMT&^!Cu=pThn1j^=>5g0d|w3(r}fJNG3wP zXFyQsB5O5XDj>eFUhFu3I?-d_-`{W8A$3q01He(c*cD|~C9BWH@9Z0}#}4&b9~tQ+YF%%Bd5IDH zaGJA|V^KGNe-%5|7ymh6O_mZfhZgOW%Auyj$sRjTGx4!$4RAr!uou&wvqW-)-HJN| z8bFp951?izwXeN8XgIs<&b3XOX9oj|P1ELJ+N_bIt&mDVO7#kpj*T+?Oz8FW~T6i9b0$xUFTEpPyNq*AOj%sj|6VgzWszubep{+m1JbpLMxet7?&{SLLw&&fI-#3`8u#x*>T zzR_>Lnd-%dzS-v0xqa)VdAs`qEx!x7TDKt!=!gqCDgz+PNMZoEbwyDLQ3}};YnPck zA`=gE!pxn)WsVL4w}2oXdVSFL%rxwl)h%0#)B56p%x)TP+mDa-*^iF(;jeYnfc+aX zHj4*qgSs3mQrQvLwHSGTrEG{oGk~dXm7WDsRUwt=r;4OLp1)ccyvGt)U0)IH#dUts9(ZBl8*Rg^QXqak!b<-LDPV&Y_l_i|^tGQChrGFbU-0 zr(_%Jp}=45m<0Z?xpqJp_}H<6#o`3_B|AW>cA-Wq-JA90Cy||Vq>RiATta-61Inmr zfpP|LCAf09V@GkP(QXo0XYlv$U2hKB9Nu;8aHBjdLSrzLNwAM{d-Vo-$x;qNwFEe@ z;2$}rYqfMQ zHZlR?7aRHcS?M|fuz__I0xIxViWhM0<{EH@^0jP01=8TWW=~B{P9CQ!imHu{j&7{i z8_xr^w)_(cDK1CXD%s$UlWOAR70w97xtXMJdG|cos(?+0HFm!EyK2R!{@$M70M=Ag^Zj}zwOMmFN(}{^= zjh4uXO&pXfCXvX;>-F@0)V&ri^~Oeyv$i#BCPsSF_SQVL3*c1zcSi1+?-F{7zZ3v} z)`q=S`3i4-Frb}H0#0+EKY;)6@s|@PPP{GV|HtmX8p0N}nbqq~00000NkvXXu0mjf D*)!}s diff --git a/Extensions/Firefox/manifest.json b/Extensions/Firefox/manifest.json deleted file mode 100644 index 5675f68..0000000 --- a/Extensions/Firefox/manifest.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "manifest_version": 3, - "name": "Firelink", - "version": "1.0.0", - "description": "Capture downloads and links directly to Firelink download manager.", - "permissions": [ - "downloads", - "downloads.open", - "contextMenus", - "storage", - "activeTab", - "scripting" - ], - "background": { - "scripts": ["background.js"] - }, - "action": { - "default_popup": "popup/popup.html", - "default_title": "Firelink" - }, - "icons": { - "48": "icons/icon-48.png", - "128": "icons/icon-128.png" - }, - "browser_specific_settings": { - "gecko": { - "id": "firelink@nimbold.github.io" - } - } -} diff --git a/Extensions/Firefox/popup/popup.html b/Extensions/Firefox/popup/popup.html deleted file mode 100644 index 08ddfa5..0000000 --- a/Extensions/Firefox/popup/popup.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - -
-
-
- -
-

Firelink

-
- -
- -
-
-
- Capture All Downloads - Intercept browser downloads -
- -
- -
-
- Disable on site - ... -
- -
-
- -
- - - diff --git a/Extensions/Firefox/popup/popup.js b/Extensions/Firefox/popup/popup.js deleted file mode 100644 index d7b814c..0000000 --- a/Extensions/Firefox/popup/popup.js +++ /dev/null @@ -1,88 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const globalToggle = document.getElementById('global-toggle'); - const siteToggle = document.getElementById('site-toggle'); - const hostnameSpan = document.getElementById('current-hostname'); - const themeToggleBtn = document.getElementById('theme-toggle'); - const sunIcon = document.getElementById('sun-icon'); - const moonIcon = document.getElementById('moon-icon'); - - // Apply theme function - const applyTheme = (theme) => { - document.documentElement.setAttribute('data-theme', theme); - if (theme === 'light') { - sunIcon.style.display = 'none'; - moonIcon.style.display = 'block'; - } else { - sunIcon.style.display = 'block'; - moonIcon.style.display = 'none'; - } - }; - - // Load current settings including theme - chrome.storage.local.get(['globalCapture', 'siteToggles', 'theme'], (result) => { - globalToggle.checked = result.globalCapture || false; - - // Determine initial theme - let currentTheme = result.theme; - if (!currentTheme) { - currentTheme = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'; - } - applyTheme(currentTheme); - - // Get current active tab - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - if (tabs.length > 0 && tabs[0].url) { - try { - const url = new URL(tabs[0].url); - // Only show site toggle for valid http/https URLs - if (url.protocol.startsWith('http')) { - const hostname = url.hostname; - hostnameSpan.textContent = hostname; - - const siteToggles = result.siteToggles || {}; - // If the site is in siteToggles and value is true, it means capture is DISABLED for this site - siteToggle.checked = siteToggles[hostname] === true; - } else { - document.getElementById('site-setting-row').style.display = 'none'; - } - } catch (e) { - document.getElementById('site-setting-row').style.display = 'none'; - } - } - }); - }); - - // Handle global toggle change - globalToggle.addEventListener('change', (e) => { - chrome.storage.local.set({ globalCapture: e.target.checked }); - }); - - // Handle theme toggle change - themeToggleBtn.addEventListener('click', () => { - const currentTheme = document.documentElement.getAttribute('data-theme') || - (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); - const newTheme = currentTheme === 'light' ? 'dark' : 'light'; - applyTheme(newTheme); - chrome.storage.local.set({ theme: newTheme }); - }); - - // Handle site toggle change - siteToggle.addEventListener('change', (e) => { - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - if (tabs.length > 0 && tabs[0].url) { - try { - const url = new URL(tabs[0].url); - const hostname = url.hostname; - - chrome.storage.local.get(['siteToggles'], (result) => { - const siteToggles = result.siteToggles || {}; - siteToggles[hostname] = e.target.checked; - chrome.storage.local.set({ siteToggles: siteToggles }); - }); - } catch (error) { - console.error("Invalid URL"); - } - } - }); - }); -}); diff --git a/Extensions/Firefox/popup/styles.css b/Extensions/Firefox/popup/styles.css deleted file mode 100644 index 07d8815..0000000 --- a/Extensions/Firefox/popup/styles.css +++ /dev/null @@ -1,282 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap'); - -:root { - /* Dark Theme Variables (Default fallback) */ - --bg-color: #0d0d0f; - --text-primary: #f5f5f7; - --text-secondary: #8e8e93; - --text-hover: #a1a1a6; - --row-bg: rgba(255, 255, 255, 0.03); - --row-border: rgba(255, 255, 255, 0.06); - --row-bg-hover: rgba(255, 255, 255, 0.05); - --row-border-hover: rgba(255, 255, 255, 0.1); - --header-border: rgba(255, 255, 255, 0.08); - --blob-color-1: rgba(255, 45, 85, 0.4); - --blob-color-2: rgba(255, 149, 0, 0.1); - --toggle-bg: rgba(255, 255, 255, 0.15); - --toggle-border: rgba(255, 255, 255, 0.05); - --toggle-knob: #ffffff; - --shadow-color: rgba(0, 0, 0, 0.2); - --icon-hover: rgba(255, 255, 255, 0.1); -} - -[data-theme="light"] { - --bg-color: #f2f2f7; - --text-primary: #1c1c1e; - --text-secondary: #636366; - --text-hover: #3a3a3c; - --row-bg: rgba(255, 255, 255, 0.6); - --row-border: rgba(0, 0, 0, 0.05); - --row-bg-hover: rgba(255, 255, 255, 0.9); - --row-border-hover: rgba(0, 0, 0, 0.1); - --header-border: rgba(0, 0, 0, 0.08); - --blob-color-1: rgba(255, 45, 85, 0.2); - --blob-color-2: rgba(255, 149, 0, 0.05); - --toggle-bg: rgba(0, 0, 0, 0.1); - --toggle-border: rgba(0, 0, 0, 0.05); - --toggle-knob: #ffffff; - --shadow-color: rgba(0, 0, 0, 0.05); - --icon-hover: rgba(0, 0, 0, 0.05); -} - -@media (prefers-color-scheme: light) { - :root:not([data-theme="dark"]) { - --bg-color: #f2f2f7; - --text-primary: #1c1c1e; - --text-secondary: #636366; - --text-hover: #3a3a3c; - --row-bg: rgba(255, 255, 255, 0.6); - --row-border: rgba(0, 0, 0, 0.05); - --row-bg-hover: rgba(255, 255, 255, 0.9); - --row-border-hover: rgba(0, 0, 0, 0.1); - --header-border: rgba(0, 0, 0, 0.08); - --blob-color-1: rgba(255, 45, 85, 0.2); - --blob-color-2: rgba(255, 149, 0, 0.05); - --toggle-bg: rgba(0, 0, 0, 0.1); - --toggle-border: rgba(0, 0, 0, 0.05); - --toggle-knob: #ffffff; - --shadow-color: rgba(0, 0, 0, 0.05); - --icon-hover: rgba(0, 0, 0, 0.05); - } -} - -body { - width: 340px; - margin: 0; - padding: 0; - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - background-color: var(--bg-color); - color: var(--text-primary); - overflow: hidden; - position: relative; - transition: background-color 0.3s ease, color 0.3s ease; -} - -/* Glassmorphic background blob animation */ -.background-blob { - position: absolute; - top: -50px; - right: -50px; - width: 200px; - height: 200px; - background: radial-gradient(circle, var(--blob-color-1) 0%, var(--blob-color-2) 50%, transparent 70%); - border-radius: 50%; - filter: blur(30px); - z-index: 0; - animation: pulse 6s infinite alternate cubic-bezier(0.4, 0, 0.2, 1); - transition: background 0.3s ease; -} - -@keyframes pulse { - 0% { transform: scale(1) translate(0, 0); opacity: 0.6; } - 100% { transform: scale(1.1) translate(-10px, 10px); opacity: 0.9; } -} - -.container { - position: relative; - z-index: 1; - padding: 20px; -} - -.header { - display: flex; - align-items: center; - margin-bottom: 24px; - padding-bottom: 16px; - border-bottom: 1px solid var(--header-border); - transition: border-color 0.3s ease; -} - -.logo { - width: 28px; - height: 28px; - margin-right: 12px; - border-radius: 6px; - box-shadow: 0 4px 12px rgba(255, 45, 85, 0.2); - transition: transform 0.3s ease; -} - -.logo:hover { - transform: scale(1.05) rotate(2deg); -} - -.header-title-container { - flex: 1; -} - -h2 { - margin: 0; - font-size: 20px; - font-weight: 600; - letter-spacing: -0.5px; - background: linear-gradient(90deg, #ff9500, #ff2d55); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.theme-toggle-btn { - background: transparent; - border: none; - cursor: pointer; - padding: 6px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: var(--text-secondary); - transition: background-color 0.2s ease, color 0.2s ease; -} - -.theme-toggle-btn:hover { - background-color: var(--icon-hover); - color: var(--text-primary); -} - -.theme-toggle-btn svg { - width: 20px; - height: 20px; - fill: currentColor; -} - -.settings { - display: flex; - flex-direction: column; - gap: 16px; -} - -.setting-row { - display: flex; - justify-content: space-between; - align-items: center; - padding: 14px 16px; - background: var(--row-bg); - border: 1px solid var(--row-border); - border-radius: 14px; - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - transition: all 0.2s ease; -} - -.setting-row:hover { - background: var(--row-bg-hover); - border-color: var(--row-border-hover); - transform: translateY(-1px); - box-shadow: 0 4px 12px var(--shadow-color); -} - -.setting-info { - display: flex; - flex-direction: column; - flex: 1; - padding-right: 16px; -} - -.setting-title { - font-size: 14px; - font-weight: 500; - color: var(--text-primary); - margin-bottom: 4px; - letter-spacing: -0.2px; - transition: color 0.3s ease; -} - -.setting-desc { - font-size: 12px; - color: var(--text-secondary); - line-height: 1.4; - word-break: break-all; - transition: color 0.2s ease; -} - -.setting-row:hover .setting-desc { - color: var(--text-hover); -} - -#current-hostname { - color: #ff9500; - font-weight: 500; -} - -/* Modern Toggle Switch Styling */ -.switch { - position: relative; - display: inline-block; - width: 48px; - height: 28px; - flex-shrink: 0; -} - -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: var(--toggle-bg); - transition: .4s cubic-bezier(0.4, 0, 0.2, 1); - border: 1px solid var(--toggle-border); - box-sizing: border-box; -} - -.slider:before { - position: absolute; - content: ""; - height: 22px; - width: 22px; - left: 2px; - bottom: 2px; - background-color: var(--toggle-knob); - transition: .4s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: 0 2px 5px rgba(0,0,0,0.3); -} - -input:checked + .slider { - background-color: #ff2d55; - border-color: #ff2d55; - box-shadow: 0 0 12px rgba(255, 45, 85, 0.4); -} - -input:focus + .slider { - outline: 2px solid rgba(255, 45, 85, 0.5); - outline-offset: 2px; -} - -input:checked + .slider:before { - transform: translateX(20px); -} - -.slider.round { - border-radius: 28px; -} - -.slider.round:before { - border-radius: 50%; -} diff --git a/README.md b/README.md index 8ed06c0..c484b12 100644 --- a/README.md +++ b/README.md @@ -98,12 +98,22 @@ git push origin v0.4.1 --- +## 🧩 Browser Extension + +The browser extension for Firelink is developed in a separate repository. You can find the extension source code, track its development, and download releases at: + +πŸ‘‰ **[nimbold/Firelink-Extension](https://github.com/nimbold/Firelink-Extension)** + +For local development parity, this repository tracks the extension via a Git Submodule located in the `Extensions/` directory. + +--- + ## πŸ—ΊοΈ Roadmap - [x] **Data Persistence:** Store history, column layout preferences, and active queues across restarts. - [x] **Zero-Config Setup:** Automatically bundle and configure `aria2c` inside the `.app` bundle. - [x] **Bandwidth Limits:** Add global and per-download speed caps and calendar schedules. -- [ ] **Browser Extensions:** Capture links directly from Safari, Chrome, and Firefox. +- [x] **Browser Extensions:** Capture links directly from Safari, Chrome, and Firefox. (See [Firelink-Extension](https://github.com/nimbold/Firelink-Extension) repository) - [x] **Advanced Transfer Features:** Checksum validation, cookie/header ingestion, and smart mirror failovers. - [x] **Updates & Releases:** GitHub Actions DMG release pipeline and built-in update checker. - [ ] **Distribution:** Notarized `.app` releases and Homebrew formulae.