const _="https://api.groq.com/openai/v1/chat/completions",Y="llama-3.3-70b-versatile",ie={1:"United States",7:"Russia",20:"Egypt",27:"South Africa",30:"Greece",31:"Netherlands",32:"Belgium",33:"France",34:"Spain",36:"Hungary",39:"Italy",40:"Romania",41:"Switzerland",43:"Austria",44:"United Kingdom",45:"Denmark",46:"Sweden",47:"Norway",48:"Poland",49:"Germany",51:"Peru",52:"Mexico",53:"Cuba",54:"Argentina",55:"Brazil",56:"Chile",57:"Colombia",58:"Venezuela",60:"Malaysia",61:"Australia",62:"Indonesia",63:"Philippines",64:"New Zealand",65:"Singapore",66:"Thailand",81:"Japan",82:"South Korea",84:"Vietnam",86:"China",90:"Turkey",91:"India",92:"Pakistan",93:"Afghanistan",94:"Sri Lanka",95:"Myanmar",98:"Iran",212:"Morocco",213:"Algeria",216:"Tunisia",220:"Senegal",221:"Senegal",222:"Mauritania",223:"Mali",224:"Guinea",225:"Ivory Coast",226:"Burkina Faso",227:"Niger",228:"Togo",229:"Benin",230:"Mauritius",231:"Liberia",232:"Sierra Leone",233:"Ghana",234:"Nigeria",235:"Chad",236:"Central African Republic",237:"Cameroon",238:"Cape Verde",239:"Sao Tome and Principe",240:"Equatorial Guinea",241:"Gabon",242:"Congo",243:"Democratic Republic of the Congo",244:"Angola",245:"Guinea-Bissau",246:"Diego Garcia",248:"Seychelles",249:"Sudan",250:"Rwanda",251:"Ethiopia",252:"Somalia",253:"Djibouti",254:"Kenya",255:"Tanzania",256:"Uganda",257:"Burundi",258:"Mozambique",260:"Zambia",261:"Madagascar",262:"Reunion",263:"Zimbabwe",264:"Namibia",265:"Malawi",266:"Lesotho",267:"Botswana",268:"Eswatini",290:"Saint Helena",291:"Eritrea",297:"Aruba",298:"Faroe Islands",299:"Greenland",350:"Gibraltar",351:"Portugal",352:"Luxembourg",353:"Ireland",354:"Iceland",355:"Albania",356:"Malta",357:"Cyprus",358:"Finland",359:"Bulgaria",370:"Lithuania",371:"Latvia",372:"Estonia",373:"Moldova",374:"Armenia",375:"Belarus",376:"Andorra",377:"Monaco",378:"San Marino",380:"Ukraine",381:"Serbia",382:"Montenegro",383:"Kosovo",385:"Croatia",386:"Slovenia",387:"Bosnia and Herzegovina",389:"North Macedonia",420:"Czech Republic",421:"Slovakia",423:"Liechtenstein",500:"Falkland Islands",501:"Belize",502:"Guatemala",503:"El Salvador",504:"Honduras",505:"Nicaragua",506:"Costa Rica",507:"Panama",508:"Saint Pierre and Miquelon",509:"Haiti",590:"Guadeloupe",591:"Guyana",592:"Suriname",593:"Ecuador",594:"French Guiana",595:"Paraguay",596:"Martinique",597:"Suriname",598:"Uruguay",599:"Curacao",670:"East Timor",672:"Norfolk Island",673:"Brunei",674:"Nauru",675:"Papua New Guinea",676:"Tonga",677:"Solomon Islands",678:"Vanuatu",679:"Fiji",680:"Palau",681:"Wallis and Futuna",682:"Cook Islands",683:"Niue",684:"American Samoa",685:"Samoa",686:"Kiribati",687:"New Caledonia",688:"Tuvalu",689:"French Polynesia",690:"Tokelau",691:"Micronesia",692:"Marshall Islands",850:"North Korea",852:"Hong Kong",853:"Macau",855:"Cambodia",856:"Laos",880:"Bangladesh",886:"Taiwan",960:"Maldives",961:"Lebanon",962:"Jordan",963:"Syria",964:"Iraq",965:"Kuwait",966:"Saudi Arabia",967:"Yemen",968:"Oman",970:"Palestine",971:"United Arab Emirates",972:"Israel",973:"Bahrain",974:"Qatar",975:"Bhutan",976:"Mongolia",977:"Nepal",992:"Tajikistan",993:"Turkmenistan",994:"Azerbaijan",995:"Georgia",996:"Kyrgyzstan",998:"Uzbekistan"};function ye(t){if(!t)return null;const c=String(t).replace(/\D/g,"");for(let r=3;r>=1;r--){const e=c.substring(0,r);if(ie[e])return ie[e]}return null}function ge(t,c){const r=t&&(t.preferredName||t.name||[t.firstName,t.lastName].filter(Boolean).join(" "))||"Candidate",e=(c||"").trim(),i=`You are an expert at writing professional, tailored cover letters. Your job is to generate a cover letter that:
1. Addresses the specific job and company when provided
2. Uses the candidate's name and profile information (experience, skills, summary)
3. Is professional and matches the candidate's preferred tone (e.g. professional, conversational)
4. Highlights relevant experience and skills from the profile that match the job description
5. Is concise (typically 3-4 short paragraphs), no fluff
6. Does NOT invent facts—only use information from the candidate profile and job description

Output ONLY the cover letter body. No subject line, no "Dear Hiring Manager" instruction in the output—start with the salutation line (e.g. "Dear Hiring Manager,") and end with a sign-off (e.g. "Sincerely," and the candidate's name). Use a standard business letter format.`,a=`TARGET JOB:
---
${e}
---

CANDIDATE PROFILE (use only this information):
- Name: ${r}
- Current/Target Role: ${t&&t.role||"Not provided"}
- Years of Experience: ${t&&t.yearsExperience||"Not provided"}
- Skills: ${t&&t.skills||"Not provided"}
- Professional Summary: ${t&&t.summary||"Not provided"}
- Preferred Tone: ${t&&t.preferredTone||"professional"}
${t&&t.emailAddress?`- Email: ${t.emailAddress}`:""}
${t&&t.phoneNumber?`- Phone: ${t.phoneNumber}`:""}
${t&&t.location?`- Location: ${t.location}`:""}

Write a tailored cover letter for this candidate applying to this job. Use the exact name above for the sign-off. Output only the cover letter text.`;return{systemPrompt:i,userContent:a}}async function se(t,c,r){var d,f,m;const e=t&&t.apiKey?t.apiKey:String(t||"").trim(),{systemPrompt:i,userContent:a}=ge(c,r),n=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:i},{role:"user",content:a}],max_tokens:800,temperature:.7})});if(!n.ok){const u=await n.text();if(n.status===429){var s=$(u);throw new q("Rate limit exceeded",{retryAfterMs:s.retryAfterMs,isTpd:s.isTpd})}let p=`API error ${n.status}`;try{const b=JSON.parse(u);(d=b.error)!=null&&d.message&&(p=b.error.message)}catch{}throw new Error(p)}const o=(f=(await n.json()).choices)==null?void 0:f[0];if(!((m=o==null?void 0:o.message)!=null&&m.content))throw new Error("Invalid API response: no content in choices");return o.message.content.trim()}const h={apiKey:"groqApiKey",groqApiTokens:"groqApiTokens",groqApiRateLimited:"groqApiRateLimited",profile:"userProfile",lastJobDescription:"lastJobDescription",customQuestionsAnswers:"customQuestionsAnswers",apiBaseUrl:"fillydashApiBaseUrl",extensionToken:"fillydashExtensionToken",resumesList:"fillydashResumesList",resumesLastSync:"fillydashResumesLastSync"},Q=2*60*1e3,ne=15*60*1e3;var D={_tokens:null,_rateLimited:null,_roundRobinIndex:0,_loaded:!1,async _ensureLoaded(){if(!this._loaded){var t=await new Promise(function(l){chrome.storage.local.get([h.groqApiTokens,h.groqApiRateLimited,h.apiKey],l)}),c=t[h.groqApiTokens],r=Array.isArray(c)?c:[];if(r=r.map(function(l){if(!l||typeof l!="object")return null;var o=(l.apiKey||l.key||"").trim();return o?{id:l.id||"tok-"+Date.now()+"-"+Math.random().toString(36).slice(2,7),name:l.name||"Unnamed",apiKey:o}:null}).filter(Boolean),r.length===0&&(t[h.apiKey]||"").trim()){var e=(t[h.apiKey]||"").trim();r=[{id:"legacy-"+Date.now(),name:"Default",apiKey:e}],await new Promise(function(l){chrome.storage.local.set({[h.groqApiTokens]:r},l)})}console.log("[FillyDash] tokenManager loaded:",r.length,"token(s)"),this._tokens=r;var i=t[h.groqApiRateLimited]&&typeof t[h.groqApiRateLimited]=="object"?Object.assign({},t[h.groqApiRateLimited]):{},a=Date.now(),n=!1;for(var s in i)Number(i[s])<=a&&(delete i[s],n=!0);n&&chrome.storage.local.set({[h.groqApiRateLimited]:i}),this._rateLimited=i,this._roundRobinIndex>=r.length&&(this._roundRobinIndex=0),this._loaded=!0}},async getNextAvailable(){await this._ensureLoaded();var t=this._tokens;if(!t||t.length===0)return null;for(var c=Date.now(),r=t.length,e=this._roundRobinIndex%r,i=0;i<r;i++){var a=(e+i)%r,n=t[a];if(!(!n||!(n.apiKey||"").trim())){var s=Number(this._rateLimited[n.id])||0;if(!(s>c))return this._rateLimited[n.id]&&s<=c&&delete this._rateLimited[n.id],this._roundRobinIndex=(a+1)%r,n}}return null},async markRateLimited(t,c){await this._ensureLoaded();var r=30*60*1e3,e=c&&c>0?Math.min(c,r):Q;this._rateLimited[t]=Date.now()+e,chrome.storage.local.set({[h.groqApiRateLimited]:Object.assign({},this._rateLimited)})},async getStatuses(){await this._ensureLoaded();for(var t=Date.now(),c=[],r=0;r<(this._tokens||[]).length;r++){var e=this._tokens[r],i=Number(this._rateLimited[e.id])||0,a=i>t;c.push({id:e.id,name:e.name||"Unnamed",available:!a,rateLimitedUntil:a?i:null})}return c},invalidate(){this._loaded=!1,this._tokens=null,this._rateLimited=null}};chrome.storage.onChanged.addListener(function(t,c){c==="local"&&t[h.groqApiTokens]&&D.invalidate()});function q(t,c){this.name="RateLimitError",this.message=t||"Rate limit exceeded",this.isRateLimit=!0,this.retryAfterMs=c&&c.retryAfterMs||null,this.isTpd=c&&c.isTpd||!1}q.prototype=Object.create(Error.prototype);function $(t){var c=null,r=!1;if(!t||typeof t!="string")return{retryAfterMs:c,isTpd:r};try{var e=JSON.parse(t),i=e&&e.error&&e.error.message?String(e.error.message):t;e&&e.error&&(e.error.type==="tokens"||i.toLowerCase().indexOf("tokens per day")!==-1)&&(r=!0),t=i}catch{}var a=t.toLowerCase();(a.indexOf("tokens per day")!==-1||a.indexOf("tpd")!==-1)&&(r=!0);var n=t.match(/try again in\s*(\d+)\s*m\s*(\d*\.?\d*)\s*s/i)||t.match(/try again in\s*(\d+)\s*s/i)||t.match(/try again in\s*(\d+)\s*m/i);if(n){var s=parseInt(n[1],10)||0,l=parseFloat(n[2])||0;n[2]!==void 0&&n[2]!==""?c=(s*60+l)*1e3:c=s*60*1e3,c>0&&c<24*60*60*1e3?c=Math.ceil(c):c>=24*60*60*1e3&&(c=15*60*1e3)}return{retryAfterMs:c,isTpd:r}}async function M(t){var c=await D.getNextAvailable();if(!c){var r=await new Promise(function(m){chrome.storage.local.get([h.groqApiTokens,h.apiKey],m)}),e=Array.isArray(r[h.groqApiTokens])?r[h.groqApiTokens]:[],i=e.length>0?(e[0].apiKey||e[0].key||"").trim():(r[h.apiKey]||"").trim();if(i)console.warn("[FillyDash] tokenManager returned null but found key in storage directly – using fallback"),c={id:"fallback-"+Date.now(),name:"Fallback",apiKey:i};else throw new Error("No Groq API key found. Add a Groq API key in Settings to use AI features.")}try{return await t(c)}catch(m){if(!(m&&m.isRateLimit))throw m;var a=m.isTpd?ne:Q,n=m.retryAfterMs&&m.retryAfterMs>0?m.retryAfterMs:a;await D.markRateLimited(c.id,n);for(var s=m;;){var l=await D.getNextAvailable();if(!l)break;try{return await t(l)}catch(u){if(!(u&&u.isRateLimit))throw u;var o=u.isTpd?ne:Q,d=u.retryAfterMs&&u.retryAfterMs>0?u.retryAfterMs:o;await D.markRateLimited(l.id,d),s=u}}if(s&&s.isTpd)throw new Error("All your Groq keys hit the daily token limit. Keys from the same Groq account share one limit. Wait for the limit to reset (often ~15 min) or add API keys from a different Groq account (different email).");if(s&&s.retryAfterMs){var f=Math.ceil(s.retryAfterMs/6e4);throw new Error("All Groq keys are rate-limited. Try again in about "+f+" min, or add keys from a different Groq account.")}throw s||new Error("All Groq keys are rate-limited. Add more keys in Settings or try again later.")}}const we="http://localhost:3000";async function U(){const t=await new Promise(e=>{chrome.storage.local.get([h.apiBaseUrl,h.extensionToken],e)});let c=(t[h.apiBaseUrl]||"").trim().replace(/\/$/,"");c||(c=we.replace(/\/$/,""));const r=(t[h.extensionToken]||"").trim();return{baseUrl:c,token:r}}function oe(t){const c={smartrecruiters:"SmartRecruiters",wellfound:"Wellfound",jobylon:"Jobylon",greenhouse:"Greenhouse",gem:"Gem",ashby:"Ashby"};if(!t)return null;const r=String(t).toLowerCase();return c[r]||t}async function ce(t){const{company:c,role:r,status:e="applied",notes:i,jobUrl:a,source:n}=t||{};if(!c||!r)return{success:!1,error:"company and role are required"};const{baseUrl:s,token:l}=await U();if(!s||!l)return{success:!1,error:"Not linked to FillyDash (set API URL and link in Settings)"};if(a&&String(a).trim())try{const u=await fetch(`${s}/api/jobs?jobUrl=${encodeURIComponent(String(a).trim())}`,{headers:{Authorization:`Bearer ${l}`}});if(u.ok){const p=await u.json(),b=Array.isArray(p)?p.find(A=>A.jobUrl===String(a).trim()):null;if(b)return{success:!0,isDuplicate:!0,message:`Job already exists: ${c} - ${r}`,id:b.id}}}catch(u){console.warn("[FillyDash] Could not check for duplicate job:",u.message)}const o=`${s}/api/jobs`,d={company:String(c).trim(),role:String(r).trim(),status:e==="saved"?"saved":"applied",notes:i!=null?String(i):null,jobUrl:a!=null&&String(a).trim()?String(a).trim():null,source:n!=null&&String(n).trim()?String(n).trim():null},f=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify(d)});if(!f.ok){const u=await f.text();let p=`Backend ${f.status}`;try{const b=JSON.parse(u);b.error&&(p=b.error)}catch{}return{success:!1,error:p}}const m=await f.json();return m._isDuplicate?{success:!0,isDuplicate:!0,message:`Job already exists: ${c} - ${r}`,id:m.id}:{success:!0,isDuplicate:!1,id:m.id}}async function fe(){const{baseUrl:t,token:c}=await U();if(!t||!c)return{success:!1,error:"Not linked"};const r=await fetch(`${t}/api/profile`,{headers:{Authorization:`Bearer ${c}`}});if(r.status===401)return{success:!1,unlinked:!0};if(!r.ok)return{success:!1,error:"Profile fetch failed"};let e;try{e=await r.json(),console.log("[FillyDash] Profile sync response:",e)}catch{return{success:!1,error:"Invalid profile response"}}const a=(await new Promise(d=>{chrome.storage.local.get([h.profile],d)}))[h.profile]||{},n=e.name||[e.firstName,e.lastName].filter(Boolean).join(" ").trim()||a.name||[a.firstName,a.lastName].filter(Boolean).join(" ").trim()||"";function s(d,f){return d??f??null}const l={name:n,firstName:e.firstName||a.firstName||"",lastName:e.lastName||a.lastName||"",preferredName:e.preferredName||a.preferredName||"",suffixName:e.suffixName||a.suffixName||"",role:e.role||a.role||"",yearsExperience:e.yearsExperience!=null?String(e.yearsExperience):a.yearsExperience||"",skills:e.skills||a.skills||"",summary:e.summary||a.summary||"",workHistory:e.workHistory||a.workHistory||"",preferredTone:e.preferredTone||a.preferredTone||"professional",emailAddress:e.emailAddress||a.emailAddress||"",phoneNumber:e.phoneNumber||a.phoneNumber||"",birthday:e.birthday||a.birthday||"",country:e.country||a.country||"",location:e.location||a.location||"",address:e.address||a.address||"",address2:e.address2||a.address2||"",address3:e.address3||a.address3||"",postalCode:e.postalCode||a.postalCode||"",linkedin:e.linkedin||a.linkedin||"",github:e.github||a.github||"",portfolio:e.portfolio||a.portfolio||"",website:e.website||a.website||"",twitter:e.twitter||a.twitter||"",facebook:e.facebook||a.facebook||"",instagram:e.instagram||a.instagram||"",tiktok:e.tiktok||a.tiktok||"",youtube:e.youtube||a.youtube||"",pronouns:e.pronouns||a.pronouns||"",gender:e.gender||a.gender||"",ethnicity:e.ethnicity||a.ethnicity||"",isVeteran:s(e.isVeteran,a.isVeteran),hasDisability:s(e.hasDisability,a.hasDisability),identifyLGBTQ:s(e.identifyLGBTQ,a.identifyLGBTQ),authorizedWorkUS:s(e.authorizedWorkUS,a.authorizedWorkUS),authorizedWorkCanada:s(e.authorizedWorkCanada,a.authorizedWorkCanada),authorizedWorkUK:s(e.authorizedWorkUK,a.authorizedWorkUK),requiresSponsorship:s(e.requiresSponsorship,a.requiresSponsorship),noticePeriod:e.noticePeriod||a.noticePeriod||"",salaryExpectation:e.salaryExpectation||a.salaryExpectation||"",availability:e.availability||a.availability||"",defaultResumeId:e.defaultResumeId||a.defaultResumeId||""};await new Promise(d=>{chrome.storage.local.set({[h.profile]:l},d)});const o=[];if(e.groqApiKeys&&Array.isArray(e.groqApiKeys)?o.push(...e.groqApiKeys):e.groqApiKey&&String(e.groqApiKey).trim()&&o.push({key:String(e.groqApiKey).trim(),label:"Synced from FillyDash"}),o.length>0){await D._ensureLoaded();const d=D._tokens||[];let f=!1;const m=u=>u&&d.some(p=>p.apiKey===u);console.log("[FillyDash] Syncing keys. Remote:",o,"Existing:",d);for(const u of o){const p=(u.key||u.apiKey||"").trim();if(!p){console.warn("[FillyDash] Skipping sync item with no key:",u);continue}if(!m(p)){const b={id:"synced-"+Date.now()+"-"+Math.random().toString(36).substr(2,5),name:u.label||u.name?`Synced: ${u.label||u.name}`:"Synced from FillyDash",apiKey:p};d.push(b),f=!0}}f&&(console.log("[FillyDash] Saving modified tokens:",d),await new Promise(u=>{chrome.storage.local.set({[h.groqApiTokens]:d},u)}),console.log("[FillyDash] Synced new API keys:",o.length),D.invalidate())}return{success:!0,profile:l}}function le(t){return(t||"").trim().toLowerCase().replace(/\*/g,"").replace(/\s+/g," ").trim()}async function he(){const{baseUrl:t,token:c}=await U();if(!t||!c)return{success:!1,error:"Not linked"};const r=await fetch(`${t}/api/qa`,{headers:{Authorization:`Bearer ${c}`}});if(r.status===401)return{success:!1,unlinked:!0};if(!r.ok)return{success:!1,error:"QA fetch failed"};let e;try{e=await r.json()}catch{return{success:!1,error:"Invalid QA response"}}const i=Array.isArray(e)?e:[],a=await new Promise(o=>{chrome.storage.local.get([h.customQuestionsAnswers],o)}),n=Array.isArray(a[h.customQuestionsAnswers])?a[h.customQuestionsAnswers]:[],s=new Map;n.forEach(o=>{s.set(le(o.question),{question:(o.question||"").trim(),answer:(o.answer||"").trim(),answerType:o.answerType||"text"})}),i.forEach(o=>{s.set(le(o.question),{question:(o.question||"").trim(),answer:(o.answer||"").trim(),answerType:o.answerType||"text"})});const l=Array.from(s.values());return await new Promise(o=>{chrome.storage.local.set({[h.customQuestionsAnswers]:l},o)}),{success:!0,qa:l}}async function be(){const{baseUrl:t,token:c}=await U();if(!t||!c)return{success:!1,error:"Not linked"};if((await fetch(`${t}/api/profile`,{headers:{Authorization:`Bearer ${c}`}})).status===401)return await new Promise(o=>{chrome.storage.local.remove([h.extensionToken,h.apiBaseUrl],o)}),{success:!1,unlinked:!0};const[e,i,a]=await Promise.all([fe(),he(),W()]),n=e.success&&!e.unlinked,s=i.success&&!i.unlinked,l=a.success&&!a.unlinked;return e.unlinked||i.unlinked||a.unlinked?{success:!1,unlinked:!0}:{success:n&&s&&l,profile:e.profile,qa:i.qa,resumes:a.resumes}}async function W(){const{baseUrl:t,token:c}=await U();if(!t||!c)return{success:!1,error:"Not linked"};try{const r=await fetch(`${t}/api/resumes`,{headers:{Authorization:`Bearer ${c}`}});if(r.status===401)return{success:!1,unlinked:!0};if(!r.ok)return{success:!1,error:`Backend returned ${r.status}`};const e=await r.json(),i=Array.isArray(e)?e:[],a={resumes:i,lastSync:Date.now()};return await new Promise(n=>{chrome.storage.local.set({[h.resumesList]:i,[h.resumesLastSync]:Date.now()},n)}),console.log("[FillyDash] Synced resumes from backend:",i.length,"resumes"),{success:!0,resumes:i}}catch(r){return console.error("[FillyDash] Resume sync failed:",r),{success:!1,error:r.message||"Resume sync failed"}}}async function Ae(t,c=null){const{baseUrl:r,token:e}=await U();if(!r||!e)return{success:!1,error:"Not linked to FillyDash"};if(!t||t.size===0)return{success:!1,error:"No file provided"};const i=5*1024*1024;if(t.size>i)return{success:!1,error:"File too large (max 5MB)"};if(!["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/plain"].includes(t.type||""))return{success:!1,error:"Invalid file type. Use PDF, DOC, DOCX, or TXT."};try{const n=new FormData;n.append("file",t),c&&String(c).trim()&&n.append("title",String(c).trim());const s=await fetch(`${r}/api/resumes`,{method:"POST",headers:{Authorization:`Bearer ${e}`},body:n});if(s.status===401)return{success:!1,unlinked:!0,error:"Not authenticated"};if(!s.ok)return{success:!1,error:(await s.json().catch(()=>({}))).error||`Upload failed: ${s.status}`};const l=await s.json();return console.log("[FillyDash] Resume uploaded:",l.id,l.title),await W(),{success:!0,id:l.id,title:l.title,fileName:l.fileName}}catch(n){return console.error("[FillyDash] Resume upload failed:",n),{success:!1,error:n.message||"Upload failed"}}}function Se(t=60*60*1e3){return new Promise(c=>{chrome.storage.local.get([h.resumesList,h.resumesLastSync],r=>{const e=r[h.resumesList],i=r[h.resumesLastSync];if(!e||!i){c(null);return}if(Date.now()-i>t){c(null);return}c(e)})})}var J={name:"Name",firstName:"First name",lastName:"Last name",preferredName:"Preferred name",suffixName:"Name suffix",role:"Role / Title",yearsExperience:"Years of experience",skills:"Skills",summary:"Professional summary",workHistory:"Work history & achievements",preferredTone:"Preferred tone",emailAddress:"Email address",phoneNumber:"Phone number",birthday:"Date of birth",email:"Email",phone:"Phone",country:"Country",location:"City / Location",address:"Address line 1",address2:"Address line 2",address3:"Address line 3",postalCode:"Postal code",linkedin:"LinkedIn URL",github:"GitHub URL",portfolio:"Portfolio / Website URL",website:"Website URL",twitter:"Twitter / X URL",facebook:"Facebook URL",instagram:"Instagram URL",tiktok:"TikTok URL",youtube:"YouTube URL",resumeUrl:"Resume URL",pronouns:"Pronouns",gender:"Gender",ethnicity:"Ethnicity",isVeteran:"Veteran status",hasDisability:"Has a disability",identifyLGBTQ:"Identifies as LGBTQ+",authorizedWorkUS:"Authorized to work in the US",authorizedWorkCanada:"Authorized to work in Canada",authorizedWorkUK:"Authorized to work in the UK",requiresSponsorship:"Requires visa sponsorship",nationality:"Nationality",citizenship:"Citizenship / Work authorization",visaSponsorship:"Visa sponsorship required",workAuthorization:"Work authorization",noticePeriod:"Notice period",salaryExpectation:"Salary expectation",availability:"Availability / Start date"};function ve(t){if(!t||typeof t!="object")return"Candidate";var c=t.name&&String(t.name).trim()||[t.firstName,t.lastName].filter(Boolean).map(String).join(" ").trim()||t.preferredName&&String(t.preferredName).trim();return c&&c.length>0?c:"Candidate"}var z=4e3,K=300;function V(t){if(!t||typeof t!="object")return"No profile data.";var c=[],r=ve(t);r&&r!=="Candidate"&&c.push("- Name: "+r.slice(0,K));var e=["isVeteran","hasDisability","identifyLGBTQ","authorizedWorkUS","authorizedWorkCanada","authorizedWorkUK","requiresSponsorship"];function i(P){return P===!0?"Yes":P===!1?"No":null}for(var a=["role","yearsExperience","skills","summary","country","location","emailAddress","phoneNumber","linkedin","github","website","portfolio","pronouns","gender","ethnicity","nationality","citizenship","visaSponsorship","workAuthorization"],n=["isVeteran","hasDisability","identifyLGBTQ","authorizedWorkUS","authorizedWorkCanada","authorizedWorkUK","requiresSponsorship"],s=Object.create(null),l=0,o=0;o<a.length&&l<z;o++){var d=a[o];s[d]=!0;var f=t[d];if(f!=null){var m=typeof f=="string"?f.trim():String(f).trim();if(!(!m||m==="false")){var u=J[d]||d,p="- "+u+": "+m.slice(0,K);c.push(p),l+=p.length+1}}}for(var b=0;b<n.length&&l<z;b++){var A=n[b];s[A]=!0;var v=i(t[A]);if(v!==null){var T=J[A]||A,C="- "+T+": "+v;c.push(C),l+=C.length+1}}s.workHistory=!0;var L=t.workHistory;if(L&&typeof L=="string"&&L.trim()){var F=L.trim().slice(0,2e3);c.push(`- Work history & achievements:
`+F),l+=F.length+30}var j=Object.create(null);e.forEach(function(P){j[P]=!0});for(var y=Object.keys(t),N=0;N<y.length&&l<z;N++){var w=y[N];if(!(w==="name"||w==="firstName"||w==="lastName"||w==="preferredName")&&!(w==="defaultResumeId"||w==="preferredTone")&&!s[w]){var g=t[w];if(g!=null){var k;if(j[w]){if(k=i(g),k===null)continue}else if(k=typeof g=="string"?g.trim():String(g).trim(),!k||k==="false")continue;var x=J[w]||w.replace(/([A-Z])/g," $1").replace(/^./,function(P){return P.toUpperCase()}),I="- "+x+": "+k.slice(0,K);if(l+I.length>z)break;c.push(I),l+=I.length+1}}}return c.length?c.join(`
`):"No profile data."}async function ke(t,c,r,e,i,a,n,s,l,o){var te,re,ae;const d=t&&t.apiKey?t.apiKey:String(t||"").trim(),f=(e||"").toLowerCase(),m=/gender|pronouns?|sex\b/.test(f)||/\brace\b|ethnicity|hispanic|latino|racial/.test(f)||/disability|disabled/.test(f)||/veteran|military\s+status/.test(f);if(m){const S=c||{};let E=null;if(/pronouns?\b/.test(f)&&!/gender/i.test(f)?E=(S.pronouns||"").trim():/gender|sex\b/.test(f)?E=(S.gender||"").trim():/\brace\b|ethnicity|hispanic|latino|racial/.test(f)?E=(S.ethnicity||"").trim():/disability|disabled/.test(f)?S.hasDisability===!0?E="Yes":S.hasDisability===!1&&(E="No"):/veteran|military\s+status/.test(f)&&(S.isVeteran===!0?E="Yes":S.isVeteran===!1&&(E="No")),E)return E;if(!(n&&Array.isArray(n)&&n.length>0))throw new Error("Demographic field not set in profile — skipping.")}let u="";if(a==="select"||a==="radio")n&&Array.isArray(n)&&n.length>0?u=`

⚠️ FIELD TYPE: `+(a==="select"?"Dropdown/Select":"Radio buttons")+`
AVAILABLE OPTIONS (you MUST choose EXACTLY one of these):
`+n.map(function(S,E){return"  "+(E+1)+". "+String(S).trim()}).join(`
`)+`

⚠️ CRITICAL: Output ONLY the exact text of one option from the list above. Do not add any other text.`+(m&&!((c||{}).pronouns||(c||{}).gender||(c||{}).ethnicity||(c||{}).hasDisability!=null||(c||{}).isVeteran!=null||(c||{}).identifyLGBTQ!=null)?`
⚠️ DEMOGRAPHIC/EEO FIELD: The candidate has not specified this information. Choose the option that most closely means 'Decline to answer' or 'Prefer not to say' from the list above.`:""):a==="select"&&(u=`

⚠️ FIELD TYPE: Dropdown/Select (options not visible — the dropdown menu was closed)
⚠️ Output a SHORT answer (1–5 words max) that would match a typical dropdown option.
⚠️ For Yes/No questions: output ONLY 'Yes' or 'No'.
⚠️ For consent/acknowledgment/privacy notice questions: output 'Yes' (the candidate is actively applying and consents).
⚠️ For country questions: output ONLY the country name (e.g. 'Nigeria', 'United States').
⚠️ For city/town/place of residence questions: output ONLY the city name from the profile's location (e.g., if location is 'Lagos, Nigeria' output 'Lagos').
⚠️ For experience-level questions: output 'Yes' followed by the level if applicable (e.g. 'Yes, 3-5 years').
⚠️ For pronouns: output the pronoun set (e.g. 'He/Him', 'She/Her', 'They/Them').
⚠️ For 'how did you hear' questions: output the source (e.g. 'LinkedIn', 'Job Board', 'Company Website').
⚠️ For work eligibility/authorization: output 'Yes' if the candidate can work in that country.
⚠️ Do NOT output full sentences, paragraphs, or explanations. Just the dropdown value.`);else if(a==="url")u=`

⚠️ CRITICAL - FIELD TYPE: URL/Link field
⚠️ This field expects a URL starting with http:// or https://
⚠️ Output ONLY a valid URL from the candidate's profile (LinkedIn, GitHub, portfolio, etc.)
⚠️ DO NOT output text, paragraphs, sentences, or cover letter content
⚠️ ONLY output the URL itself, nothing else`;else if(a==="email")u=`

⚠️ CRITICAL - FIELD TYPE: Email field
⚠️ Output ONLY the candidate's email address from their profile. No text, just the email.`;else if(a==="tel")u=`

⚠️ CRITICAL - FIELD TYPE: Phone/Tel field
⚠️ Output ONLY the candidate's phone number from their profile. No text, just the number.`;else if(a==="checkbox")u=`

⚠️ CRITICAL - FIELD TYPE: Checkbox field
⚠️ This is a yes/no checkbox. Output ONLY 'Yes' if the candidate should check this box, or 'No' if they should not.
⚠️ For checkbox GROUPS (multiple checkboxes), output comma-separated values to check (e.g. 'JavaScript, Python, React').
⚠️ Common checkbox questions: sponsorship (answer based on citizenship status), legal authorization to work, relocation willingness, veteran status, disability status, race/ethnicity, etc.`;else if(a==="number")u=`

⚠️ CRITICAL - FIELD TYPE: Number field
⚠️ Output ONLY a numeric value. No text, units, or currency symbols.
⚠️ For years of experience: just the number (e.g. '5').
⚠️ For salary: just the number (e.g. '120000').`;else if(a==="date"||a==="month"||a==="week"||a==="datetime-local"||a==="time"){var p="YYYY-MM-DD";a==="month"?p="YYYY-MM":a==="time"?p="HH:MM":a==="datetime-local"&&(p="YYYY-MM-DDTHH:MM"),u=`

⚠️ CRITICAL - FIELD TYPE: `+a+` field
⚠️ Output ONLY a date/time in this EXACT format: `+p+`
⚠️ No text, sentences, or other formatting. Just the value.
⚠️ If the question asks about availability/start date, use a reasonable near-future date.`}/consent|acknowledge|privacy\s*notice|notice\s*(at|of)\s*collection|brighthire|recorded|recording/i.test(e||"")&&!m&&(u+=`

⚠️ CONSENT/ACKNOWLEDGMENT QUESTION: The candidate is actively applying for this job. For consent, acknowledgment, or privacy notice questions, the candidate agrees/consents. Output 'Yes' or the shortest phrase indicating consent (e.g. 'Yes', 'I consent', 'I acknowledge'). Do NOT output full sentences or paragraphs.`);let A="";if(s&&String(s).trim()){var v=String(s).trim();A=`

FIELD CONTEXT (HTML attributes and nearby text):
`+v.slice(0,300),/type:\s*url|linkedin|github|portfolio|website|http|www\./i.test(v)&&(A+=`

⚠️ WARNING: This appears to be a URL field based on context. Output ONLY a URL, no text!`)}let T="";l&&String(l).trim()&&(T=`

HTML CONTEXT (Raw structural HTML of the field):
`+String(l).trim().slice(0,2e3)+`

Use this HTML fragment to fully understand the question being asked and to correctly map the exact option values if it is a dropdown or radio list.`);const C=/tell\s+us\s+about|tell\s+me\s+about|share\s+an\s+example|share\s+a\s+bit|describe\s+your|proudest\s+achievement|biggest\s+achievement|what\s+are\s+you\s+most\s+proud|if\s+you\s+have\s+experience\s+with|challenging\s+technical\s+problem|led\s+through\s+collaboration|collaborated\s+with\s+stakeholder|worked\s+with\s+stakeholder|how\s+have\s+you|what\s+has\s+been\s+your|walk\s+us\s+through|give\s+us\s+an\s+example|give\s+an\s+example|functional\s+programming|most\s+difficult\s+challenge|most\s+challenging|what\s+resonates|why\s+are\s+you\s+proud|what\s+excites\s+you|what\s+motivates\s+you/i.test(e||""),L=a==="select"||a==="radio",F=`You are the candidate filling out a job application form field. Output ONLY the answer — no preamble, no explanation, no meta-commentary.

The candidate's profile is the single source of truth. Use it to answer every question exactly as the data shows. Never guess or invent anything not in the profile.

- Short fields (name, email, phone, location, URL, yes/no): output just the value.
- Open-ended short questions: 2–4 sentences, first person, based on the profile.
- Deep/reflective questions (achievements, experience, projects, challenges): 5–8 sentences, first person — be specific, draw on concrete examples from the profile, address every part of the question directly.
- Dropdown/select/radio: carefully read the question and all options, then output ONLY the exact text of the single best-matching option.
- Checkbox: output only "Yes" or "No".`;var j=i&&i.length>0?i.filter(function(S){return S&&S.question&&(S.answer||"").trim()}).slice(0,18):[];const y=j.length>0?`
SAVED Q&A (use verbatim when form question matches):
`+j.map(function(S){return'- "'+String(S.question).trim().slice(0,80)+'" → '+String(S.answer).trim().slice(0,120)}).join(`
`):"",N=V(c),w=(r||"").trim().slice(0,600),g=L?"Read the question carefully. Review every option. Output ONLY the exact text of the single best option.":C?"Answer as the candidate. Write 5–8 sentences that directly address every part of the question. Be specific — use concrete examples from the profile. Output only the answer.":"Answer as the candidate would type. Output only the answer.",k=`CANDIDATE DATA:
`+N+y+(w?`

JOB CONTEXT:
`+w:"")+A+T+u+(o?`

⚠️ PREVIOUS ERROR TO FIX ⚠️
The candidate previously tried to answer this question but the form returned this validation error: "`+o+`"
You MUST read the error and provide a new, corrected answer that fixes the validation issue.`:"")+`

FORM QUESTION: `+e+`

`+g,x=C?600:L?60:200,I=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:F},{role:"user",content:k}],max_tokens:x,temperature:.4})});if(!I.ok){const S=await I.text();if(I.status===429){var P=$(S);throw new q("Rate limit exceeded",{retryAfterMs:P.retryAfterMs,isTpd:P.isTpd})}let E=`API error ${I.status}`;try{const G=JSON.parse(S);(te=G.error)!=null&&te.message&&(E=G.error.message)}catch{}throw new Error(E)}const R=(re=(await I.json()).choices)==null?void 0:re[0];if(!((ae=R==null?void 0:R.message)!=null&&ae.content))throw new Error("Invalid API response: no content");let O=R.message.content.trim();const pe=/^(As there is no[^.]*\.|Since there is no[^.]*\.)\s*/i;if(O=O.replace(pe,"").trim(),(a==="url"||a==="email"||a==="tel")&&(O.length>100||(O.match(/\.\s+[A-Z]/g)||[]).length>=2)){if(console.warn("[Background] AI returned paragraph for "+a+" field. Attempting to extract URL..."),a==="url"){var X=O.match(/https?:\/\/[^\s]+/);if(X)O=X[0],console.log("[Background] Extracted URL:",O);else throw console.error("[Background] No URL found in AI response for URL field"),new Error("AI did not return a valid URL")}else if(a==="email"){var Z=O.match(/[\w.-]+@[\w.-]+\.\w+/);if(Z)O=Z[0];else throw new Error("AI did not return a valid email")}else if(a==="tel"){var ee=O.match(/[\d\s\-()+]+/);if(ee)O=ee[0].trim();else throw new Error("AI did not return a valid phone number")}}return O}async function Ne(t,c,r,e,i){var C,L,F,j;const a=t&&t.apiKey?t.apiKey:String(t||"").trim(),n=V(c),s=(r||"").trim().slice(0,1500),l=i&&i.length>0?i.filter(y=>y&&y.question&&(y.answer||"").trim()).slice(0,18):[],o=l.length>0?`
SAVED Q&A (use verbatim when a question matches):
`+l.map(y=>`- "${String(y.question).trim().slice(0,80)}" → ${String(y.answer).trim().slice(0,120)}`).join(`
`):"";function d(y){return y?/tell\s+us\s+about|tell\s+me\s+about|share\s+an\s+example|share\s+a\s+bit|describe\s+your|proudest\s+achievement|biggest\s+achievement|what\s+are\s+you\s+most\s+proud|if\s+you\s+have\s+experience\s+with|challenging\s+technical\s+problem|led\s+through\s+collaboration|collaborated\s+with\s+stakeholder|worked\s+with\s+stakeholder|how\s+have\s+you|what\s+has\s+been\s+your|walk\s+us\s+through|give\s+us\s+an\s+example|give\s+an\s+example|functional\s+programming|most\s+difficult\s+challenge|most\s+challenging/i.test(y):!1}const f=e.map((y,N)=>{let w;return y.isCoverLetter?w="COVER LETTER":(y.fieldType==="select"||y.fieldType==="radio")&&Array.isArray(y.fieldOptions)&&y.fieldOptions.length>0?w=(y.fieldType==="select"?"SELECT":"RADIO")+": "+y.fieldOptions.slice(0,12).join(" | "):y.fieldType==="url"?w="URL FIELD":y.fieldType==="email"?w="EMAIL FIELD":y.fieldType==="tel"?w="PHONE FIELD":y.fieldType==="number"?w="NUMBER FIELD":y.fieldType==="checkbox"?w="CHECKBOX: Yes or No":y.fieldType==="date"||y.fieldType==="month"||y.fieldType==="datetime-local"?w="DATE FIELD (format: YYYY-MM-DD)":d(y.questionText)?w="ESSAY":w="SHORT ANSWER",`${N+1}. [${w}] ${y.questionText}`}).join(`
`),m=`You are a job applicant filling out an application form. Answer every question using the candidate's profile data — it is the single source of truth. Never guess or invent anything not in the profile.

OUTPUT FORMAT:
- Return ONLY a valid JSON array: [{"answer": "..."}, {"answer": "..."}, ...]
- One object per question, in the exact same order as the input
- No markdown fences, no extra text outside the JSON array

ANSWER RULES:
- [COVER LETTER]: 3–5 sentences, first person, tailored to the job and company
- [ESSAY]: 5–8 sentences, first person, specific and thoughtful — draw on concrete examples from the candidate's experience. Address every part of the question directly.
- [SHORT ANSWER]: 1–3 concise sentences, first person
- [SELECT: opt1 | opt2 | ...]: output ONLY the exact text of one listed option
- [RADIO: opt1 | opt2 | ...]: output ONLY the exact text of one listed option
- [CHECKBOX: Yes or No]: output ONLY "Yes" or "No"
- [URL FIELD]: output only a URL from the candidate profile
- [EMAIL FIELD]: output only the candidate's email address
- [PHONE FIELD]: output only the candidate's phone number
- [NUMBER FIELD]: output only a number
- [DATE FIELD]: output only a date in YYYY-MM-DD format
- For every field: use the candidate profile data exactly as provided. Do not override it.`,u=`CANDIDATE DATA:
${n}${o}${s?`

JOB DESCRIPTION:
`+s:""}

QUESTIONS TO ANSWER:
${f}

Return a JSON array with one {"answer": "..."} per question, in order.`,p=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:m},{role:"user",content:u}],max_tokens:4e3,temperature:.4})});if(!p.ok){const y=await p.text();if(p.status===429){const w=$(y);throw new q("Rate limit exceeded",{retryAfterMs:w.retryAfterMs,isTpd:w.isTpd})}let N=`API error ${p.status}`;try{const w=JSON.parse(y);(C=w.error)!=null&&C.message&&(N=w.error.message)}catch{}throw new Error(N)}const A=(j=(F=(L=(await p.json()).choices)==null?void 0:L[0])==null?void 0:F.message)==null?void 0:j.content;if(!A)throw new Error("Invalid API response: no content");const v=A.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"");let T;try{T=JSON.parse(v)}catch{const N=v.replace(/,?\s*\{[^}]*$/,"").replace(/,\s*$/,"")+"]";try{T=JSON.parse(N)}catch{throw new Error("AI response could not be parsed. Try again.")}}if(!Array.isArray(T))throw new Error("Expected JSON array from AI");return T.map(y=>typeof y=="object"&&y!==null?String(y.answer||"").trim():String(y).trim())}async function Te(t,c,r,e,i,a=null){var j,y,N,w;const n=t&&t.apiKey?t.apiKey:String(t||"").trim(),s=V(e),l=(r||"").trim().slice(0,1200),o=i&&i.length>0?i.filter(g=>g&&g.question&&(g.answer||"").trim()).slice(0,20):[],d=o.length>0?`
SAVED Q&A (use verbatim when a field matches):
`+o.map(g=>`- "${String(g.question).trim().slice(0,80)}" → ${String(g.answer).trim().slice(0,120)}`).join(`
`):"",f=c.map(g=>{let k=`[${g.index}] ${g.label||g.name||"Field "+g.index} (${g.type})`;if(g.id&&(k+=` id="${g.id}"`),g.name&&(k+=` name="${g.name}"`),g.placeholder&&(k+=` placeholder="${g.placeholder}"`),Array.isArray(g.options)&&g.options.length>0){const x=g.options.slice(0,15).map(I=>I.label||I.value).join(" | ");k+=`
    OPTIONS: ${x}`}return k}).join(`
`),m=e&&e.phoneNumber?ye(e.phoneNumber):null,u=m?`
⚠️ The candidate's phone number country is: ${m}`:"",p=`You are a job applicant filling out an online job application form. Use the candidate's profile data to answer every field — it is the single source of truth. Never guess or invent anything not in the profile.

OUTPUT FORMAT — return ONLY valid JSON, no markdown fences, no extra text:
[{"index": 0, "answer": "value"}, {"index": 1, "answer": "value"}, ...]

RULES:
- Include every field in the output (use the same index numbers from the input)
- Use the candidate's profile data exactly as provided for every field
- select / radio: output ONLY the exact text of one listed option
- checkbox: "Yes" to check, "No" to leave unchecked
- textarea / cover letter: 3–5 sentences first person if cover letter, 1–3 sentences otherwise
- date fields: YYYY-MM-DD format
- Twitter / X (fka Twitter) fields: output ONLY the plain username handle (e.g. "philzace1"), never a full URL
- "Confirm email" / "Confirm your email" / "Email confirmation" fields: output the EXACT SAME email address as the main email field
- "City" / "place of residence" / "city of residence" / "town" fields: output the candidate's city from their location (if location is "Lagos, Nigeria" output "Lagos")
- "Phone Country Code" field: CRITICAL - Match the candidate's phone country EXACTLY. Look at the dropdown options and find the one matching ${m||"(candidate's phone country)"}.${u}
- Phone number text field when a SEPARATE "Phone Country Code" field also exists in this form: output ONLY the local digits WITHOUT the country code prefix (e.g. profile phone +2348144251176 with country code +234 → output 8144251176)
- For fields you cannot answer from the profile, output "" (empty string)`,b=a&&a.length>0?`

CRITICAL ERRORS FROM PREVIOUS SUBMISSION ATTEMPT (YOU MUST FIX THESE):
`+a.map(g=>`- Field: "${g.label}"
  Error: "${g.error}"
  Instruction: Generate a corrected or alternative answer that fixes this issue.`).join(`
`):"",A=`CANDIDATE PROFILE:
${s}`+d+b+(l?`

JOB DESCRIPTION:
${l}`:"")+`

FORM FIELDS:
${f}

Return the JSON fill array now.`,v=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:p},{role:"user",content:A}],max_tokens:1200,temperature:.2})});if(!v.ok){const g=await v.text();if(v.status===429){const x=$(g);throw new q("Rate limit exceeded",{retryAfterMs:x.retryAfterMs,isTpd:x.isTpd})}let k=`API error ${v.status}`;try{const x=JSON.parse(g);(j=x.error)!=null&&j.message&&(k=x.error.message)}catch{}throw new Error(k)}const C=(w=(N=(y=(await v.json()).choices)==null?void 0:y[0])==null?void 0:N.message)==null?void 0:w.content;if(!C)throw new Error("No content from AI");const L=C.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,""),F=JSON.parse(L);if(!Array.isArray(F))throw new Error("Expected JSON array from AI");return F.map(g=>({index:typeof g.index=="number"?g.index:-1,answer:typeof g.answer=="string"?g.answer.trim():String(g.answer||"").trim()})).filter(g=>g.index>=0)}async function Ee(t,c){var f,m,u;if(!c||String(c).trim().length<10)return null;const r=t&&t.apiKey?t.apiKey:String(t||"").trim(),e="Extract the exact question from job application form text near a field. Output ONLY the question, one line, no quotes. If unclear, output nothing.",i=`TEXT NEAR FIELD:
`+String(c).trim().slice(0,500)+`

Exact question?`,a=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:e},{role:"user",content:i}],max_tokens:80,temperature:.2})});if(!a.ok){if(a.status===429){var n=await a.text(),s=$(n);throw new q("Rate limit exceeded",{retryAfterMs:s.retryAfterMs,isTpd:s.isTpd})}return null}const o=(f=(await a.json()).choices)==null?void 0:f[0],d=(u=(m=o==null?void 0:o.message)==null?void 0:m.content)==null?void 0:u.trim();return!d||d.length<10?null:d.length>250?d.slice(0,250):d}async function Le(t,c,r){var u,p,b;if(!r||r.length===0)return-1;const e=t&&t.apiKey?t.apiKey:String(t||"").trim(),i=r.filter(A=>A&&A.question&&String(A.question).trim()).slice(0,25).map(A=>String(A.question).trim());if(i.length===0)return-1;const a=`Match a job application form question to a saved question ONLY if they ask for the EXACT SAME piece of information (just worded differently).

Rules:
- A question asking for a phone number is NOT the same as an essay question about achievements or experience.
- Open-ended/essay questions (e.g. "tell us about...", "describe your...", "what resonates...") almost NEVER match short-answer saved questions (phone, email, name, country, URL).
- Only match if the questions genuinely request the same data. When in doubt, return -1.

Reply with ONLY the 0-based index of the matching saved question, or -1 if none match. Output a single number, nothing else.`,n="FORM: "+String(c).trim().slice(0,150)+`
SAVED:
`+i.map(function(A,v){return v+": "+A.slice(0,60)}).join(`
`)+`
Index or -1?`,s=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:Y,messages:[{role:"system",content:a},{role:"user",content:n}],max_tokens:10,temperature:0})});if(!s.ok){const A=await s.text();if(s.status===429){var l=$(A);throw new q("Rate limit exceeded",{retryAfterMs:l.retryAfterMs,isTpd:l.isTpd})}let v=`API error ${s.status}`;try{const T=JSON.parse(A);(u=T.error)!=null&&u.message&&(v=T.error.message)}catch{}throw new Error(v)}const d=(p=(await s.json()).choices)==null?void 0:p[0],f=(((b=d==null?void 0:d.message)==null?void 0:b.content)||"").trim(),m=parseInt(f.replace(/[^\d-]/g,""),10);return Number.isNaN(m)||m<-1||m>=i.length?-1:m}function me(t){return t?t==="jobs.smartrecruiters.com"||t.endsWith(".smartrecruiters.com")?"adapters/smartrecruiters.js":t==="wellfound.com"||t==="www.wellfound.com"?"adapters/wellfound.js":t==="jobs.gem.com"?"adapters/gem.js":t==="greenhouse.io"||t&&t.endsWith&&t.endsWith(".greenhouse.io")?"adapters/greenhouse.js":t==="jobs.ashbyhq.com"?"adapters/ashby.js":t==="emp.jobylon.com"?"adapters/jobylon.js":null:null}function B(t){var c="";try{c=new URL((t==null?void 0:t.url)||"").hostname}catch{}try{var r=chrome.runtime.getManifest();if(r&&Array.isArray(r.content_scripts)){for(var e=0;e<r.content_scripts.length;e++){var i=r.content_scripts[e];if(!(!i.matches||!Array.isArray(i.js))){var a=i.matches.some(function(f){try{if(/^https?:\/\/\*\//.test(f))return!0;var m=f.match(/^[*a-z]+:\/\/([^/]+)\//);if(!m)return!1;var u=m[1].replace(/^\*\./,"");return u==="*"?!0:c===u||c.endsWith("."+u)}catch{return!1}});if(a)return i.js.slice()}}for(var n=0;n<r.content_scripts.length;n++){var s=r.content_scripts[n];if(Array.isArray(s.js)){var l=s.js.some(function(f){return/content\.js/i.test(f)});if(l)return s.js.filter(function(f){return!/(?:^|\/)(?:smartrecruiters|wellfound|gem|greenhouse|ashby|jobylon)(?:\.js|\b)/i.test(f)})}}}}catch{}var o=["services/storage.js","services/fieldFiller.js","services/toast.js","services/formFiller.js","services/fieldDiscovery.js"],d=me(c);return d&&o.push(d),o.push("content.js"),o}function H(t){return t?t.startsWith("chrome://")||t.startsWith("edge://")||t.startsWith("about:")||t.startsWith("chrome-extension://"):!0}function ue(t){var c=chrome.runtime.getURL("popup.html"),r=chrome.runtime.getURL("assets/icon-collapsed.png");return Promise.all([chrome.scripting.insertCSS({target:{tabId:t},files:["sidebar.css"]}),chrome.scripting.executeScript({target:{tabId:t},func:function(e,i){if(document.getElementById("clg-sidebar-root"))return;var a="clg-sidebar-open";function n(){try{var b=sessionStorage.getItem(a);return b===null?!0:b==="1"}catch{return!0}}function s(b){try{sessionStorage.setItem(a,b?"1":"0")}catch{}}var l=document.createElement("div");l.id="clg-sidebar-root",n()||l.classList.add("clg-sidebar-collapsed");var o=document.createElement("div");o.className="clg-sidebar-panel";var d=document.createElement("iframe");d.className="clg-sidebar-iframe",d.src=e,d.title="FillyDash",d.addEventListener("load",function(){l.classList.add("clg-sidebar-ready")}),setTimeout(function(){l.classList.add("clg-sidebar-ready")},500);var f=document.createElement("button");f.type="button",f.className="clg-sidebar-tab",f.setAttribute("aria-label","Toggle FillyDash panel");var m=document.createElement("span");m.className="clg-sidebar-tab-icon";var u=document.createElement("img");u.src=i,u.alt="FillyDash",u.width=24,u.height=24,m.appendChild(u);var p=document.createElement("span");p.className="clg-sidebar-tab-label",p.textContent="X",f.appendChild(m),f.appendChild(p),f.addEventListener("click",function(){var b=l.classList.toggle("clg-sidebar-collapsed");s(!b)}),o.appendChild(d),l.appendChild(f),l.appendChild(o),document.body.appendChild(l)},args:[c,r]})]).then(function(){console.log("[FillyDash] background: sidebar lite inject OK for tab",t)})}function xe(t,c){var r=B(c);return console.log("[FillyDash] background: inject sidebar into tab",t,c==null?void 0:c.url),Promise.all([chrome.scripting.executeScript({target:{tabId:t},files:r}),chrome.scripting.insertCSS({target:{tabId:t},files:["sidebar.css"]})]).then(function(){return console.log("[FillyDash] background: sidebar inject OK for tab",t),ue(t).catch(function(){})}).catch(function(e){return console.warn("[FillyDash] background: sidebar file inject failed, trying lite inject",t,e),ue(t)})}function Ie(t){const c=t.field,r=t.action,e=t.lastAnswer||"",i=t.message||"";let a="";return r==="refill"?a='I need a concise answer for a job application field: "'+c+'". The field was empty and requires a value. Keep it under 50 words, professional tone.':r==="expand"?a='A job application answer is too short and needs to be expanded. Previous answer: "'+e+'". Please expand it to at least 20 words while maintaining professionalism and relevance.':r==="regenerate"&&(a='A job application answer failed validation: "'+e+'". For field "'+c+'", provide a different, valid answer. Error was: '+i),a}chrome.runtime.onMessage.addListener(function(t,c,r){if(t.action==="INJECT_SIDEBAR")return chrome.tabs.query({active:!0,currentWindow:!0},function(e){var i=e&&e[0];if(!i||!i.id||!i.url){r({ok:!1,error:"No active tab"});return}if(H(i.url)){r({ok:!1,error:"Cannot inject on this page"});return}xe(i.id,i).then(function(){r({ok:!0})}).catch(function(a){r({ok:!1,error:String(a&&a.message)})})}),!0});function de(t,c){return new Promise(r=>{chrome.tabs.sendMessage(t,{action:"autofill",text:c},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message}):e!=null&&e.filled?r({success:!0,coverLetterFilled:e.coverLetterFilled,fieldsFilled:e.fieldsFilled}):r({success:!1,error:(e==null?void 0:e.error)||"No cover letter field found on this page."})})})}async function Oe(t,c){let r;try{r=await chrome.tabs.get(t)}catch{return{success:!1,error:"Tab was closed or is invalid. Open the job page again."}}const e=(r==null?void 0:r.url)||"";if(e.startsWith("chrome://")||e.startsWith("edge://")||e.startsWith("about:"))return{success:!1,error:"Can't autofill on this page. Open a job application page (e.g. Wellfound)."};await new Promise(s=>setTimeout(s,50));let i=await de(t,c);if(i.error&&/Receiving end does not exist|Could not establish connection/i.test(i.error))try{var n=B(r);await chrome.scripting.executeScript({target:{tabId:t},files:n}),await new Promise(s=>setTimeout(s,200)),i=await de(t,c)}catch{return{success:!1,error:"Couldn't run on this page. Click the FillyDash icon on the page first, or refresh and try again."}}return i}function De(t){return chrome.tabs.get(t).then(c=>{var r=B(c);return chrome.scripting.executeScript({target:{tabId:t},files:r}).catch(()=>{}).then(()=>new Promise(e=>{setTimeout(()=>{chrome.tabs.sendMessage(t,{action:"getJobDescriptionFromPage"},i=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message}):i!=null&&i.success&&i.text?e({success:!0,text:i.text}):e({success:!1,error:"No job description found on this page."})})},50)}))})}chrome.runtime.onMessage.addListener((t,c,r)=>{if(t.action==="generate")return(async()=>{try{const e=t.payload||{},i=await new Promise(o=>{chrome.storage.local.get([h.lastJobDescription,h.profile],o)});let a=(e.jobDescription||i[h.lastJobDescription]||"").trim();const n=e.userProfile||i[h.profile]||{};if(e.apiKey&&String(e.apiKey).trim()){try{const o=await se({apiKey:String(e.apiKey).trim()},n||{},a);r({success:!0,text:o})}catch(o){r({success:!1,error:o.message})}return}try{const o=await M(d=>se(d,n||{},a));r({success:!0,text:o});return}catch(o){if(!o.message||o.message.indexOf("No Groq API key found")===-1){r({success:!1,error:o.message});return}}const{baseUrl:s,token:l}=await U();if(l&&s)try{const o=await fetch(`${s}/api/cover-letters/generate`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({jobDescription:a.trim()})}),d=await o.json().catch(()=>({}));if(o.ok&&d.content){r({success:!0,text:d.content});return}r({success:!1,error:d.error||"FillyDash generation failed."});return}catch(o){r({success:!1,error:o.message||"Could not reach FillyDash. Try again."});return}r({success:!1,error:"Add a Groq API key in Settings to use AI features."})}catch(e){r({success:!1,error:e.message||"Generation failed."})}})(),!0;if(t.action==="autofill")return(async()=>{try{const{tabId:e,text:i}=t.payload||{};if(!e){r({success:!1,error:"No tab. Switch to the job page and try again."});return}const a=await Oe(e,typeof i=="string"?i:"");r(a)}catch(e){r({success:!1,error:e.message||"Autofill failed. Try refreshing the page."})}})(),!0;if(t.action==="getProfileData")return chrome.storage.local.get([h.profile],function(e){r({profile:e[h.profile]||{}})}),!0;if(t.action==="getJobDescription")return(async()=>{try{const{tabId:e}=t.payload;if(!e){r({success:!1,error:"No tab ID."});return}const i=await De(e);r(i)}catch(e){r({success:!1,error:e.message})}})(),!0;if(t.action==="getPageQuestions")return(async()=>{var e;try{let i=(e=t.payload)==null?void 0:e.tabId;if(!i){const[l]=await new Promise(o=>chrome.tabs.query({active:!0,currentWindow:!0},o));i=l==null?void 0:l.id}if(!i){r({success:!1,questions:[],error:"No active tab."});return}const a=()=>new Promise(l=>{chrome.tabs.sendMessage(i,{action:"getPageQuestions"},o=>{chrome.runtime.lastError?l({error:chrome.runtime.lastError.message}):l(o||{questions:[]})})});let n=await a();if(n.error&&/Receiving end does not exist|Could not establish connection/i.test(n.error))try{const l=await chrome.tabs.get(i),o=B(l);await chrome.scripting.executeScript({target:{tabId:i},files:o}),await new Promise(d=>setTimeout(d,80)),n=await a()}catch{r({success:!1,questions:[],error:"Open a job application page and click the extension icon first."});return}n.error?r({success:!1,questions:[],error:n.error}):r({success:!0,questions:Array.isArray(n.questions)?n.questions:[]})}catch(i){r({success:!1,questions:[],error:i.message||"Failed to get page questions."})}})(),!0;if(t.action==="getGroqTokenStatuses")return(async()=>{try{var e=await D.getStatuses();r({success:!0,statuses:e})}catch(i){r({success:!1,statuses:[],error:i.message})}})(),!0;if(t.action==="clearGroqRateLimits")return(async()=>{try{D._rateLimited={},D._loaded=!1,await new Promise(function(i){chrome.storage.local.set({[h.groqApiRateLimited]:{}},i)});var e=await D.getStatuses();r({success:!0,statuses:e})}catch(i){r({success:!1,error:i.message})}})(),!0;if(t.action==="answerQuestion")return(async()=>{try{const{question:e,fieldType:i,fieldOptions:a,elementContext:n,htmlContext:s,errorMsg:l}=t.payload||{};if(console.log("[Background] answerQuestion called with:",e,"type:",i,"options:",a,"context:",n,"errorMsg:",l),!e||!String(e).trim()){r({success:!1,error:"Question is required."});return}const o=await new Promise(p=>{chrome.storage.local.get([h.profile,h.lastJobDescription,h.customQuestionsAnswers],p)}),d=o[h.profile]||{},f=o[h.lastJobDescription]||"",m=Array.isArray(o[h.customQuestionsAnswers])?o[h.customQuestionsAnswers]:[],u=await M(p=>ke(p,d,f,String(e).trim(),m,i,a,n,s,l));console.log("[Background] AI response:",u),r({success:!0,text:u})}catch(e){console.error("[Background] AI error:",e),r({success:!1,error:e.message||"AI answer failed."})}})(),!0;if(t.action==="inferFormQuestion")return(async()=>{try{const{context:e}=t.payload||{},i=await M(a=>Ee(a,e));r({success:!0,question:i||null})}catch(e){r({success:!1,question:null,error:e.message})}})(),!0;if(t.action==="matchSavedQuestion")return(async()=>{try{const{question:e,savedQA:i}=t.payload||{};if(!e||!String(e).trim()){r({success:!1,error:"Question is required."});return}const n=(Array.isArray(i)?i:[]).filter(l=>l&&l.question&&(l.answer||"").trim()),s=await M(l=>Le(l,String(e).trim(),n));s>=0&&n[s]?r({success:!0,index:s,answer:String(n[s].answer).trim()}):r({success:!0,index:-1})}catch(e){console.error("[Background] matchSavedQuestion error:",e),r({success:!1,error:e.message||"Match failed.",index:-1})}})(),!0;if(t.action==="answerAllQuestions")return(async()=>{try{const{questions:e}=t.payload||{};if(!Array.isArray(e)||e.length===0){r({success:!1,error:"Questions array is required."});return}const i=await new Promise(o=>{chrome.storage.local.get([h.profile,h.lastJobDescription,h.customQuestionsAnswers],o)}),a=i[h.profile]||{},n=i[h.lastJobDescription]||"",s=Array.isArray(i[h.customQuestionsAnswers])?i[h.customQuestionsAnswers]:[],l=await M(o=>Ne(o,a,n,e,s));r({success:!0,answers:l})}catch(e){console.error("[Background] answerAllQuestions error:",e),r({success:!1,error:e.message||"AI batch answer failed."})}})(),!0;if(t.action==="analyzeFormFields")return(async()=>{try{const{fields:e,jobDescription:i}=t.payload||{};if(!Array.isArray(e)||e.length===0){r({success:!1,error:"No fields provided."});return}const a=await new Promise(d=>{chrome.storage.local.get([h.profile,h.lastJobDescription,h.customQuestionsAnswers],d)}),n=a[h.profile]||{},s=i||a[h.lastJobDescription]||"",l=Array.isArray(a[h.customQuestionsAnswers])?a[h.customQuestionsAnswers]:[],o=await M(d=>Te(d,e,s,n,l,t.payload.previousErrors));r({success:!0,answers:o})}catch(e){console.error("[FillyDash] analyzeFormFields error:",e),r({success:!1,error:e.message||"Form analysis failed."})}})(),!0;if(t.action==="fillApplicationFields")return(async()=>{try{const{tabId:a}=t.payload||{};if(!a){r({success:!1,error:"No tab ID."});return}const n=()=>new Promise(o=>{chrome.tabs.sendMessage(a,{action:"fillApplicationFields"},d=>{chrome.runtime.lastError?o({error:chrome.runtime.lastError.message}):o(d||{error:"No response."})})});let s=await n();if(s.error&&/Receiving end does not exist|Could not establish connection/i.test(s.error))try{var e=await chrome.tabs.get(a),i=B(e);await chrome.scripting.executeScript({target:{tabId:a},files:i}),await new Promise(o=>setTimeout(o,80)),s=await n()}catch{r({success:!1,error:"Can't run on this page. Click the FillyDash icon on the page first to open the sidebar, then try again."});return}s&&s.error?r({success:!1,error:s.error}):r(s&&s.success!==!1?{success:!0,filled:s.filled}:s||{success:!1,error:"No response."})}catch(a){r({success:!1,error:a.message||"Fill failed."})}})(),!0;if(t.action==="submitProfilePrompts")return(async()=>{try{const{questions:e}=t.payload||{};if(!Array.isArray(e)||e.length===0){r({success:!0,submitted:0});return}const{baseUrl:i,token:a}=await U();if(!i||!a){r({success:!1,error:"Not linked to FillyDash"});return}const n=t.payload.sourceUrl||"",s=await fetch(`${i}/api/profile-prompts`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({questions:e.slice(0,20).map(function(o){return{question:String(o.question||"").trim().slice(0,500),context:o.context?String(o.context).trim().slice(0,500):null,source:n?String(n).slice(0,300):null}})})});if(!s.ok){r({success:!1,error:"Backend returned "+s.status});return}const l=await s.json();console.log("[FillyDash] Profile prompts submitted:",l.created),r({success:!0,submitted:l.created||0})}catch(e){console.error("[FillyDash] submitProfilePrompts error:",e),r({success:!1,error:e.message})}})(),!0;if(t.action==="attachResume")return(async()=>{try{const{tabId:e,fileData:i,fileName:a,mimeType:n}=t.payload||{};if(!e||!i||!a){r({success:!1,error:"No tab or file data. Select a resume and try again."});return}let s;try{s=await chrome.tabs.get(e)}catch{r({success:!1,error:"Tab not found. Switch to the job application tab and try again."});return}if(H(s.url||"")){r({success:!1,error:"Cannot attach on this page. Open a job application page (e.g. Wellfound, Gem) and try again."});return}const l=()=>new Promise(f=>{chrome.tabs.sendMessage(e,{action:"attachResume",payload:{fileData:i,fileName:a,mimeType:n||"application/pdf"}},m=>{chrome.runtime.lastError?f({success:!1,error:chrome.runtime.lastError.message}):f(m||{success:!1,error:"No response."})})});let o=await l();if(o.error&&/Receiving end does not exist|Could not establish connection/i.test(o.error))try{const f=B(s);await chrome.scripting.executeScript({target:{tabId:e},files:f}),await new Promise(m=>setTimeout(m,150)),o=await l()}catch{r({success:!1,error:"Extension could not run on this tab. Open the job application page (e.g. wellfound.com/jobs/...), then click Attach to page again."});return}if(o&&o.success)r({success:!0,attached:o.attached});else{const f=o&&o.error?o.error:"Failed to attach resume.";r({success:!1,error:f==="No file input found"||/no resume.*field|no file input/i.test(f)?"No resume upload field found. Open the application form (e.g. click Apply on the job) so the CV/resume field is visible, then try again.":f})}}catch(e){r({success:!1,error:e.message||"Attach resume failed."})}})(),!0;if(t.action==="addJobToTracker")return(async()=>{try{const e=t.payload||{},i=await ce(e);r(i)}catch(e){r({success:!1,error:e.message||"Failed to add job."})}})(),!0;if(t.action==="getCurrentPageJobInfo")return(async()=>{try{const e=await new Promise(l=>{chrome.tabs.query({active:!0,currentWindow:!0},l)}),i=e&&e[0];if(!i||!i.id){r({success:!1,error:"No active tab."});return}const a=i.url||null,n=await new Promise(l=>{chrome.tabs.sendMessage(i.id,{action:"getJobInfo"},o=>{if(chrome.runtime.lastError){l(null);return}l(o)})});if(!n||!n.company||!n.role){r({success:!1,error:"Could not read job from this page. Open a job application page (e.g. Wellfound, Greenhouse) and try again."});return}const s=n.source||oe(n.adapterName);r({success:!0,company:n.company,role:n.role,jobUrl:a,source:s})}catch(e){r({success:!1,error:e.message||"Failed to get job info."})}})(),!0;if(t.action==="addCurrentPageJob")return(async()=>{try{const e=await new Promise(o=>{chrome.tabs.query({active:!0,currentWindow:!0},o)}),i=e&&e[0];if(!i||!i.id){r({success:!1,error:"No active tab."});return}const a=i.url||null,n=await new Promise(o=>{chrome.tabs.sendMessage(i.id,{action:"getJobInfo"},d=>{if(chrome.runtime.lastError){o(null);return}o(d)})});if(!n||!n.company||!n.role){r({success:!1,error:"Could not read job from this page. Open a job application page (e.g. Wellfound, Greenhouse) and try again."});return}const s=n.source||oe(n.adapterName),l=await ce({company:n.company,role:n.role,status:"saved",jobUrl:a,source:s});r(l)}catch(e){r({success:!1,error:e.message||"Failed to save job."})}})(),!0;if(t.action==="syncProfile")return(async()=>{try{const e=await fe();r(e)}catch(e){r({success:!1,error:e.message||"Sync failed."})}})(),!0;if(t.action==="syncQA")return(async()=>{try{const e=await he();r(e)}catch(e){r({success:!1,error:e.message||"Sync failed."})}})(),!0;if(t.action==="runStartupSync")return(async()=>{try{const e=await be();r(e)}catch(e){r({success:!1,error:e.message||"Sync failed."})}})(),!0;if(t.action==="checkSiteSupport")return chrome.tabs.query({active:!0,currentWindow:!0},function(e){var i=e&&e[0];if(!i||!i.url){r({supported:!1,host:""});return}var a="";try{a=new URL(i.url).hostname}catch{}var n=H(i.url),s=!!me(a),l=!n&&(i.url.startsWith("https://")||i.url.startsWith("http://"));r({supported:l,hasAdapter:s,restricted:n,host:a})}),!0;if(t.action==="EXCHANGE_LINK_CODE")return(async()=>{try{const{code:e,baseUrl:i}=t.payload||{};if(!e||!i){r({success:!1,linked:!1,error:"Missing code or baseUrl."});return}const a=`${i.replace(/\/$/,"")}/api/link/exchange`,n=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:String(e).trim().toUpperCase()})}),s=await n.json().catch(()=>({}))||{};if(!n.ok){r({success:!1,linked:!1,error:s.error||"Link failed."});return}const l=s.token;if(!l){r({success:!1,linked:!1,error:"No token received."});return}await new Promise(o=>{chrome.storage.local.set({[h.extensionToken]:l,[h.apiBaseUrl]:i.replace(/\/$/,"")},o)}),r({success:!0,linked:!0})}catch(e){r({success:!1,linked:!1,error:e.message||"Exchange failed."})}})(),!0;if(t.action==="SAVE_LINK_TOKEN"){const{token:e,baseUrl:i}=t.payload||{};return!e||!i?(r({success:!1}),!0):(chrome.storage.local.set({[h.extensionToken]:e.trim(),[h.apiBaseUrl]:String(i).trim().replace(/\/$/,"")},function(){r({success:!chrome.runtime.lastError})}),!0)}if(t.action==="CLEAR_LINK_TOKEN")return chrome.storage.local.remove([h.extensionToken,h.apiBaseUrl],function(){r({success:!chrome.runtime.lastError})}),!0;if(t.action==="GET_EXTENSION_LINK_STATUS")return chrome.storage.local.get([h.extensionToken],function(e){const i=(e[h.extensionToken]||"").trim();r({linked:!!i})}),!0;if(t.action==="OPEN_EXTENSION_TAB"){try{const e=chrome.runtime.getURL("popup.html");chrome.tabs.create({url:e}),r({success:!0})}catch{r({success:!1})}return!0}if(t.action==="syncResumes")return(async()=>{try{const e=await W();r(e)}catch(e){r({success:!1,error:e.message||"Resume sync failed"})}})(),!0;if(t.action==="getResumesList")return(async()=>{try{const e=await Se();if(e){r({success:!0,resumes:e,cached:!0});return}const i=await W();i.success?r({success:!0,resumes:i.resumes,cached:!1}):r(i)}catch(e){r({success:!1,error:e.message||"Failed to get resumes"})}})(),!0;if(t.action==="uploadResume")return(async()=>{try{const{fileData:e,fileName:i,mimeType:a,title:n}=t.payload||{};if(!e||!i){r({success:!1,error:"No file data provided"});return}let s;if(typeof e=="string"){const d=atob(e),f=new Uint8Array(d.length);for(let m=0;m<d.length;m++)f[m]=d.charCodeAt(m);s=new Blob([f],{type:a||"application/octet-stream"})}else e instanceof ArrayBuffer?s=new Blob([e],{type:a||"application/octet-stream"}):s=new Blob([e],{type:a||"application/octet-stream"});const l=new File([s],i,{type:a||"application/octet-stream"}),o=await Ae(l,n||i);r(o)}catch(e){console.error("[FillyDash] uploadResume error:",e),r({success:!1,error:e.message||"Upload failed"})}})(),!0;if(t.action==="getResumeById")return(async()=>{try{const{resumeId:e}=t.payload||{};if(!e){r({success:!1,error:"Resume ID required"});return}const{baseUrl:i,token:a}=await U();if(!i||!a){r({success:!1,error:"Not linked"});return}const n=await fetch(`${i}/api/resumes/${e}`,{headers:{Authorization:`Bearer ${a}`}});if(n.status===401){r({success:!1,unlinked:!0,error:"Not authenticated"});return}if(!n.ok){r({success:!1,error:`Failed to fetch resume: ${n.status}`});return}const s=await n.json();r({success:!0,resume:s})}catch(e){r({success:!1,error:e.message||"Failed to get resume"})}})(),!0;if(t.action==="correctErrorsWithAI")return(async()=>{var e;try{console.log("[Background] Received error correction request for",((e=t.corrections)==null?void 0:e.length)||0,"fields");const i=t.corrections||[],a={},n=[];for(const s of i){const l=s.action;if(l==="truncate"||l==="reformat"||l==="select_alternative")continue;const o=Ie(s);console.log("[Background] Building AI request for field:",s.field,"action:",l);const{baseUrl:d,token:f}=await U();if(f&&d){const m=(async()=>{try{const u=await fetch(`${d}/api/errors/correct`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f}`},body:JSON.stringify({field:s.field,prompt:o})});if(!u.ok)throw new Error(`Backend error: ${u.status}`);const p=await u.json();p.answer&&(a[s.field]=p.answer)}catch(u){console.error("[Background] Backend error for",s.field,":",u)}})();n.push(m)}else{const m=(async()=>{try{const u=await generateAnswerWithGroq(o,null,null);u&&(a[s.field]=u)}catch(u){console.error("[Background] Groq error for",s.field,":",u)}})();n.push(m)}}n.length>0&&(await Promise.all(n),console.log("[Background] All error corrections completed, sending",Object.keys(a).length,"answers")),r({success:!0,answers:a})}catch(i){console.error("[Background] Error correction failed:",i),r({success:!1,error:i.message})}})(),!0});
//# sourceMappingURL=background.js-BaaxkDME.js.map
