import{b as a,g as m}from"./settings-CgBxHrrF.js";import{n as W,a as oe}from"./downloadIntent-Dv31jC2S.js";import{n as f,a as I}from"./clipTypes-C_ha5Ash.js";const Y="org.gdown.nativehost";async function ie(e){return a.runtime.sendNativeMessage(Y,{action:"addUri",...e})}async function ae(){return a.runtime.sendNativeMessage(Y,{action:"focus"})}const M="history";async function se(){const t=(await a.storage.local.get([M]))[M];return Array.isArray(t)?t:[]}async function ue(e){await a.storage.local.set({[M]:e.slice(0,300)})}async function ce(e){const t=await se(),r=t.findIndex(n=>n.gid===e.gid);r>=0?t[r]=e:t.unshift(e),await ue(t)}function Q(e,t){const r=Array.isArray(e?.responseHeaders)?e.responseHeaders:[],n=t.toLowerCase(),o=r.find(i=>String(i?.name||"").toLowerCase()===n);return String(o?.value||"")}function le(e){const t=e.toLowerCase();return t?t.includes("application/vnd.apple.mpegurl")||t.includes("application/x-mpegurl")||t.includes("audio/mpegurl")?"m3u8":t.includes("video/mp4")?"mp4":t.includes("application/octet-stream")&&t.includes("m3u8")?"m3u8":t.includes("hls")?"hls":"unknown":"unknown"}function de(e){const t=String(e||"").toLowerCase();return t.includes(".m3u8")?"m3u8":t.includes(".m3u")?"m3u":t.includes(".mp4")?"mp4":t.includes("m3u8")?"m3u8":t.includes("hls")?"hls":"unknown"}function X(e,t){const r=le(t);return r!=="unknown"?r:de(e)}function fe(e){if(!e?.url)return!1;const t=String(e?.method||"").toUpperCase();if(t&&t!=="GET")return!1;const r=Number(e?.statusCode||0);if(r>0&&(r<200||r>299))return!1;const n=String(e?.type||"");if(!["xmlhttprequest","media","other","main_frame","sub_frame","fetch"].includes(n))return!1;const o=Q(e,"content-type");return X(e.url,o)!=="unknown"}function pe(e,t=""){const r=Q(e,"content-type"),n=String(e?.url||""),o=X(n,r),i=Number.isInteger(e?.tabId)?Number(e.tabId):-1,s=Date.now();return{id:`${s}:${i}:${o}:${n}`,url:n,kind:o,tabId:i,pageUrl:String(e?.documentUrl||e?.initiator||""),referer:String(t||e?.documentUrl||e?.initiator||""),contentType:r,detectedAt:s}}function $(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname}`.toLowerCase()}catch{return String(e||"").toLowerCase()}}const U="media_candidates",me=200;async function V(){const t=(await a.storage.local.get([U]))[U];return Array.isArray(t)?t:[]}async function ge(e){const t=[...e].sort((r,n)=>n.detectedAt-r.detectedAt);await a.storage.local.set({[U]:t.slice(0,me)})}async function we(e,t){const r=await V(),n=r.findIndex(o=>{try{const i=new URL(o.url);return`${i.protocol}//${i.host}${i.pathname}`.toLowerCase()===t}catch{return o.url.toLowerCase()===t}});n>=0?r[n]={...r[n],...e,detectedAt:Date.now()}:r.unshift(e),await ge(r)}async function ye(){await a.storage.local.set({[U]:[]})}const A="clips",he=500;function j(e,t){return Date.parse(t.createdAt||"")-Date.parse(e.createdAt||"")}function F(e){return`${f(e.pageUrl)}::${I(e.quote).toLowerCase()}`}async function b(){const t=(await a.storage.local.get([A]))[A];return Array.isArray(t)?t:[]}async function J(e){const t=[...e].sort(j).slice(0,he);await a.storage.local.set({[A]:t})}async function be(e){const t=f(e);return(await b()).filter(n=>f(n.pageUrl)===t).sort(j)}async function Se(e){return(await b()).find(n=>n.id===e)||null}async function ke(e){const t=await b(),r=Date.now(),n=F(e),o=t.find(i=>{const s=Date.parse(i.createdAt||"");return!Number.isFinite(s)||Math.abs(r-s)>8e3?!1:F(i)===n});return o||(t.unshift(e),await J(t),e)}async function Ue(e){const t=await b(),r=t.filter(n=>n.id!==e);return r.length===t.length?!1:(await J(r),!0)}const x=8e3,xe=7e3,L="gomdown-helper-download-context-menu-option",w=new Map,q=new Map,R=new Map,T=new Map,y=new Map,D=new Map,H=new Map;let O=!1,P=!1,z=!1,g=null;const Z="bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]/best",ve=[{hosts:["youtube.com","www.youtube.com","m.youtube.com","youtu.be"],extractor:"yt-dlp",format:Z}];function v(e){try{const t=new URL(e),r=(t.pathname||"/").replace(/\/+$/,"")||"/";return`${t.protocol}//${t.host}${r}`.toLowerCase()}catch{return String(e||"").toLowerCase()}}function p(e){const t=Date.now();for(const[r,n]of e.entries())n<=t&&e.delete(r)}function ee(e){const t=Date.now()+x;q.set(W(e),t),R.set(v(e),t)}function te(e){!Number.isInteger(e)||(e??-1)<0||D.set(e,Date.now()+x)}function Ce(e){p(q),p(R);const t=W(e);return q.has(t)||R.has(v(e))}function Ie(e){return p(D),!Number.isInteger(e)||(e??-1)<0?!1:D.has(e)}function Me(e){return p(T),T.has(v(e))}function Ae(e){T.set(v(e),Date.now()+xe)}function Le(e){return p(y),!!e&&y.has(e)}function qe(e){e&&y.set(e,Date.now()+x)}function Re(e){p(H);const t=$(e);return H.has(t)}function Te(e){H.set($(e),Date.now()+x)}async function De(){try{await ae()}catch{}}async function C(e){await a.notifications.create(`gomdown-notice-${Date.now()}`,{type:"basic",iconUrl:"/images/icon-large.png",title:"Gomdown Helper",message:e}).catch(()=>null)}async function d(e,t="",r,n,o,i){if(Me(e))return{ok:!1,error:"duplicate transfer suppressed"};const s=await m();if(!s.extensionStatus)return{ok:!1,error:"extension disabled"};if(!s.motrixAPIkey)return{ok:!1,error:"motrixAPIkey is not set"};try{const u=await ie({url:e,rpcPort:s.motrixPort,rpcSecret:s.motrixAPIkey,referer:t,split:64,out:o?.trim()||void 0,cookie:i?.cookie?.trim()||void 0,userAgent:i?.userAgent?.trim()||void 0,authorization:i?.authorization?.trim()||void 0,proxy:i?.proxy?.trim()||void 0,extractor:r==="yt-dlp"?"yt-dlp":void 0,format:r==="yt-dlp"?n||Z:void 0});if(!u?.ok)return{ok:!1,error:u?.error||"native host addUri failed"};s.activateAppOnDownload&&await De(),Ae(e);const c=String(u?.gid||u?.requestId||`pending-${Date.now()}`),l=(()=>{try{return new URL(e).pathname}catch{return""}})().split("/").filter(Boolean).pop()||e;return await ce({gid:c,downloader:"native",startTime:new Date().toISOString(),icon:"/images/32.png",name:decodeURIComponent(l),path:null,status:u?.pending?"queued":"downloading",size:0,downloaded:0}),s.enableNotifications&&await a.notifications.create(`gomdown-transfer-${Date.now()}`,{type:"basic",iconUrl:"/images/icon-large.png",title:"Gomdown Helper",message:"Download sent to gdown"}),{ok:!0}}catch(u){return{ok:!1,error:String(u)}}}function B(e){try{return new URL(e).hostname.toLowerCase()}catch{return""}}function re(e,t="",r=""){const n=[B(e),B(t)].filter(Boolean);for(const i of ve)if(n.some(s=>i.hosts.includes(s)))return{extractor:i.extractor,format:i.format};const o=r.toLowerCase();return o==="m3u8"||o==="m3u"||o==="hls"?{extractor:"yt-dlp",format:"best"}:o==="mp4"?{extractor:"aria2"}:{extractor:"aria2"}}function G(e,t){const r=t.toLowerCase(),n=e.find(o=>String(o?.name||"").toLowerCase()===r);return String(n?.value||"").trim()}async function He(e){if(e.type!=="main_frame"||(e.method||"").toUpperCase()!=="GET"||typeof e.statusCode=="number"&&(e.statusCode<200||e.statusCode>299))return!1;const t=await m();if(!t.extensionStatus||!t.motrixAPIkey)return!1;const r=String(Array.isArray(e?.responseHeaders)&&e.responseHeaders.find(o=>String(o?.name||"").toLowerCase()==="content-length")?.value||""),n=Number(r||0);return t.minFileSize>0&&n>0&&n=0){const ne=await a.tabs.get(u.tabId).catch(()=>null);c=String(ne?.title||"").trim()}const k=Fe(u.url,u.kind,c),l={...u,pageTitle:c||void 0,cookie:i||void 0,userAgent:s||void 0,suggestedOut:k||void 0};await we(l,$(l.url)),Te(l.url),l.tabId>=0&&await a.tabs.sendMessage(l.tabId,{type:"media:captured",kind:l.kind,url:l.url,suggestedOut:l.suggestedOut||""}).catch(()=>null)}function Ne(e){let t=e.trim().replace(/[\\/:*?"<>|]/g,"_").replace(/\s+/g," ").replace(/^\.+/,"").replace(/\.+$/,"");return t.length>180&&(t=t.slice(0,180).trim()),t}function _e(e){try{return new URL(e).pathname.toLowerCase().match(/\.([a-z0-9]{2,6})(?:$|[?#])/)?.[1]||""}catch{return""}}function Fe(e,t,r){const n=Ne(r||""),i=_e(e)||(t==="mp4"||t==="m3u8"||t==="m3u"||t==="hls"?"mp4":"");return n?!i||n.toLowerCase().endsWith(`.${i}`)?n:`${n}.${i}`:""}async function S(){const e=a.downloads;if(!e.setShelfEnabled)return;const t=await m();if(!t.extensionStatus)return;const r=t.useNativeHost?!1:!t.hideChromeBar;await e.setShelfEnabled(r)}function E(){P||(P=!0,a.downloads.onCreated.addListener(async e=>{await S();const t=e,r=t.finalUrl||t.url||"";!Ce(r)&&!Ie(t.tabId)||(await a.downloads.cancel(e.id).catch(()=>null),await a.downloads.erase({id:e.id}).catch(()=>null),await a.downloads.removeFile(e.id).catch(()=>null))}))}function N(){O||(O=!0,a.webRequest.onSendHeaders.addListener(e=>{w.set(e.requestId,e)},{urls:[""]},["requestHeaders","extraHeaders"]),a.webRequest.onErrorOccurred.addListener(e=>{w.delete(e.requestId),y.delete(String(e.requestId))},{urls:[""]}),a.webRequest.onCompleted.addListener(e=>{w.delete(e.requestId),y.delete(String(e.requestId))},{urls:[""]}),a.webRequest.onHeadersReceived.addListener(e=>{$e(e),Ee(e)},{urls:[""]},["responseHeaders"]))}async function K(e,t){console.log("[gomdown-helper] context menu clicked",{menuItemId:e?.menuItemId,linkUrl:e?.linkUrl,srcUrl:e?.srcUrl,frameUrl:e?.frameUrl,pageUrl:e?.pageUrl,tabUrl:t?.url});const r=e?.menuItemId;if(r!=null&&String(r)!==L)return;const n=String(e?.linkUrl||e?.srcUrl||"").trim(),o=String(e?.frameUrl||e?.pageUrl||t?.url||"").trim(),s=String(n||o||"").trim();if(!s||/^(about:|chrome:|chrome-extension:|edge:|brave:)/i.test(s)){await C("다운로드 가능한 URL을 찾지 못했습니다.");return}const u=re(s,String(e?.pageUrl||t?.url||""),""),c=await d(s,String(e?.pageUrl||t?.url||""),u.extractor,u.format);if(!c.ok){await C(`전송 실패: ${c.error||"unknown error"}`);return}await C(u.extractor==="yt-dlp"?"페이지 URL을 yt-dlp로 gdown에 전송했습니다.":"gdown으로 전송했습니다.")}function Oe(){if(typeof chrome>"u"||!chrome.contextMenus?.create){a.contextMenus.create({id:L,title:"Download with Gomdown",visible:!0,contexts:["all"]});return}chrome.contextMenus.create({id:L,title:"Download with Gomdown",contexts:["all"]},()=>{chrome.runtime.lastError})}function _(){z||(typeof chrome<"u"&&chrome.contextMenus?.onClicked?chrome.contextMenus.onClicked.addListener((e,t)=>{K(e,t)}):a.contextMenus.onClicked.addListener((e,t)=>{K(e,t)}),z=!0)}async function Pe(){const e=await m();if(!e.extensionStatus||!e.showContextOption){await a.contextMenus.removeAll().catch(()=>null);return}await a.contextMenus.removeAll().catch(()=>null),Oe()}function h(){return g||(g=Pe().finally(()=>{g=null}),g)}function ze(){try{return crypto.randomUUID()}catch{return`clip-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}}async function Be(e){const t=f(e),n=(await a.tabs.query({})).find(o=>f(String(o.url||""))===t);return Number.isInteger(n?.id)?n?.id:null}a.runtime.onMessage.addListener((e,t)=>{if(e?.type==="capture-link-download"){const r=String(e?.url||"").trim();if(!r)return Promise.resolve({ok:!1,error:"url is empty"});const n=Number(t?.tab?.id);return d(r,String(e?.referer||"")).then(o=>(o.ok&&(ee(r),te(n)),o))}if(e?.type==="media:list")return V().then(r=>({ok:!0,items:r}));if(e?.type==="media:clear")return ye().then(()=>({ok:!0}));if(e?.type==="media:enqueue"){const r=String(e?.url||"").trim(),n=String(e?.kind||"").trim(),o=String(e?.suggestedOut||"").trim(),i=String(e?.referer||"").trim(),s=String(e?.cookie||"").trim(),u=String(e?.userAgent||"").trim();if(!r)return Promise.resolve({ok:!1,error:"url is empty"});const c=re(r,i,n);return d(r,i,c.extractor,c.format,o,{cookie:s,userAgent:u}).then(k=>k)}if(e?.type==="page:enqueue-ytdlp")return a.tabs.query({active:!0,currentWindow:!0}).then(async r=>{const n=r[0],o=String(n?.url||"").trim();return o?d(o,o,"yt-dlp"):{ok:!1,error:"active tab url is empty"}});if(e?.type==="page:enqueue-ytdlp-url"){const r=String(e?.url||"").trim(),n=String(e?.referer||r).trim();return r?d(r,n||r,"yt-dlp"):Promise.resolve({ok:!1,error:"url is empty"})}if(e?.type==="clip:create")return m().then(async r=>{if(!r.extensionStatus)return{ok:!1,error:"extension disabled"};const n=f(String(e?.pageUrl||t?.tab?.url||"")),o=String(e?.pageTitle||t?.tab?.title||"").trim(),i=I(String(e?.quote||e?.anchor?.exact||"")),s=e?.anchor;if(!n)return{ok:!1,error:"pageUrl is empty"};if(!s||!String(s.exact||"").trim())return{ok:!1,error:"anchor is empty"};const u={id:ze(),tabId:Number.isInteger(t?.tab?.id)?Number(t.tab.id):void 0,pageUrl:n,pageTitle:o||n,quote:i||I(String(s.exact||"")),createdAt:new Date().toISOString(),color:"yellow",anchor:s};return{ok:!0,item:await ke(u)}});if(e?.type==="clip:list"){const r=String(e?.pageUrl||"").trim();return r?be(r).then(n=>({ok:!0,items:n})):b().then(n=>({ok:!0,items:n}))}if(e?.type==="clip:delete"){const r=String(e?.id||"").trim();return r?Ue(r).then(n=>({ok:n})):Promise.resolve({ok:!1,error:"id is empty"})}if(e?.type==="clip:reveal"){const r=String(e?.id||"").trim();return r?Se(r).then(async n=>{if(!n)return{ok:!1,error:"clip not found"};const o=Number.isInteger(n.tabId)&&(n.tabId||0)>=0?n.tabId:await Be(n.pageUrl);if(!Number.isInteger(o)||o<0){const i=await a.tabs.create({url:n.pageUrl,active:!0}).catch(()=>null);return Number.isInteger(i?.id)?{ok:!0,opened:!0}:{ok:!1,error:"failed to open clip page"}}return await a.tabs.update(o,{active:!0}).catch(()=>null),await a.tabs.sendMessage(o,{type:"clip:reveal",id:n.id}).catch(()=>null),{ok:!0}}):Promise.resolve({ok:!1,error:"id is empty"})}});a.runtime.onInstalled.addListener(()=>{console.log("[gomdown-helper] onInstalled"),N(),E(),_(),h(),S()});a.runtime.onStartup.addListener(()=>{console.log("[gomdown-helper] onStartup"),N(),E(),_(),h(),S()});a.storage.onChanged.addListener((e,t)=>{t==="sync"&&((e.hideChromeBar||e.useNativeHost||e.extensionStatus)&&(S(),h()),e.showContextOption&&h())});N();E();_();h();S();console.log("[gomdown-helper] service worker initialized");