Files
imexrps/dist-electron/main.cjs
2026-03-20 15:59:01 -07:00

173 lines
41 KiB
JavaScript

var p=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ye=p((Lr,mt)=>{mt.exports={webcontent:"webcontent-send",quit:"quit-app",test:{start:"test-start"},app:{toMain:{setAcceptableInsCoNm:"setAcceptableInsCoNm",setUserName:"setUserName",track:"analytics_track",checkForUpdates:"app_checkForUpdates",downloadUpdates:"app_downloadUpdates",installUpdates:"app_installupdates",getReleaseNotes:"app_getReleaseNotes",getAppVersion:"app_getApVersion",importJob:"app_importJob",setReleaseChannel:"app_setReleaseChannel",scrubEstimate:"app_scrubEstimate",openExternalWindow:"app_openExternalWindow",setInsRuleSet:"app_setInsRuleSet",log:{info:"app_logInfo",debug:"app_logDebug",warn:"app_logWarn",error:"app_logError",silly:"app_logSilly"}},toRenderer:{updateAvailable:"app_updateAvailable",downloadProgress:"app_downloadProgress",signOut:"app_signOut",setReleaseNotes:"app_setReleaseNotes",appVersion:"app_appVersion",scrubResults:"app_scrubResults",scrubError:"app_scrubError"}},store:{get:"store__get",getAll:"store_getAll",set:"store_set",response:"store_response"},fileScan:{toMain:{scanFilePaths:"fileScan__scanFilePaths",importJob:"fileScan__importJob",deleteAllEms:"filescan_deleteAllEms"},toRenderer:{scanFilePathsResponse:"fileScan__scanFilePathsResponse"}},fileWatcher:{toMain:{filepathsGet:"filewatcher__filepathsget",start:"filewatcher__start",stop:"filewatcher__stop",addPath:"filewatcher__addPath",removePath:"filewatcher__removePath",setPolling:"filewatcher__setPolling"},toRenderer:{filepathsList:"filewatcher__filepathslist",startSuccess:"filewatcher__start-success",startFailure:"filewatcher__start-failure",stopSuccess:"filewatcher__stop-success",error:"filewatcher__error",getPolling:"filewatcher__getPolling"}},audit:{toMain:{browseForFile:"audit__browseForFile",runAudit:"audit__runAudit",readFile:"audit__readFile"},toRenderer:{auditFilePath:"audit__filepath",auditClaimsArray:"audit_claimsArray",auditError:"audit__auditError"}},estimate:{toRenderer:{estimateDecodeStart:"estimatedecode__start",estimateDecodeSuccess:"estimatedecode__success",estimateDecodeFailure:"estimatedecode__failure",getCloseDate:"getclosedate"}}}});var P=p(Re=>{Re.default=ye()});var y=p(Pe=>{var{randomUUID:_t}=require("crypto"),wt=require("electron-store"),bt=new wt({defaults:{deviceId:_t(),showChangeLog:!0,enableNotifications:!0,filePaths:[],accepted_ins_co:[],runWatcherOnStartup:!0,polling:{enabled:!1,pollingInterval:3e4},ins_rule_set:null}});Pe.store=bt});var re=p(Ae=>{var{Notification:yt}=require("electron"),Rt=require("path"),{store:Pt}=y();function At(e){Pt.get("enableNotifications")&&yt({icon:Rt.join(__dirname,"../../src/assets/logo512.png"),...e}).show()}Ae.NewNotification=At});var Ie=p(Ne=>{var C=require("moment"),Nt=[{title:"V1",range:[C("2010-01-01"),C("2023-04-01")]},{title:"V2",range:[C("2023-04-01"),C("2024-09-01")]},{title:"V3",range:[C("2024-09-01"),C("2040-01-01")]}];function It(e){let t=e?C(e):C();return Nt.find(a=>t.isSameOrAfter(a.range[0])&&t.isBefore(a.range[1]))?.title}Ne.WhichRulesetToApply=It});var Ee=p(ve=>{var{DBFFile:Dr}=require("dbffile"),Or=require("path"),Wr=require("lodash"),Ur=require("electron-log"),{store:Vr}=y(),{BrowserWindow:Br}=require("electron"),$r=P();ve.claimsClerk=({jobline:e,joblines:t})=>vt.map(a=>a({jobline:e,joblines:t})).filter(a=>a!==null);var vt=[({jobline:e,joblines:t})=>e.db_hrs!==0&&e.mod_lb_hrs!==e.db_hrs&&e.lbr_inc===!1&&e.lbr_hrs_j===!0?{key:"Manual labor Time Change",alert:`<div>
Labor time manually changed from original CEG time.
<ul>
<li>This could possibly be denied by MPI.</li>
<li> Ensure labor time is accurate & justified.</li>
<li>Add an explanation line if needed.</li>
</ul>
</div>`}:null,({jobline:e,joblines:t})=>e.db_ref==="900500"&&e.mod_lb_hrs!==e.db_hrs?{key:"Manual Labor Line",alert:`<div>
Manually entered labor line detected.
<ul>
<li>Always ensure the labor operation you manually entered was not available in CEG.</li>
<li>Make sure there are no overlaps with other labor lines to consider.</li>
</ul>
</div>`}:null,({jobline:e,joblines:t})=>e.db_ref!=="900500"&&e.part_type&&e.oem_partno&&e.price_j?e.act_price<e.db_price?{key:"Modified Part Price",alert:`<div>
Modified part price detected.
<ul>
<li>
You will need to supply MPI with an invoice for this part showing the retail price you manually
entered.
</li>
<li>
Your manually entered price is <strong>LOWER</strong> than the database price, consider reverting back to database
price.
</li>
<li>If you chose to leave the manually entered price, you will need to:</li>
<li>Supply MPI with an invoice for this part showing the retail price you manually entered</li>
<li>NOTE: You do not need to show MPI your cost on this part, only retail.</li>
</ul>
</div>`}:{key:"Modified Part Price",alert:`<div>
Modified part price detected.
<ul>
<li>
You will need to supply MPI with an invoice for this part showing the retail price you manually
entered.
</li>
<li>NOTE: You do not need to show MPI your cost on this part, only retail.</li>
</ul>
</div>`}:null,({jobline:e,joblines:t})=>{if((e.part_type==="PAA"||e.part_type==="PAL")&&e.alt_partno&&e.act_price<e.db_price){let r=t.findIndex(o=>o.line_no===e.line_no);if(!t[r+1]?.line_desc.includes("price"))return{key:"Missing pricematch explanation",alert:"<div>In that explanation line (900501) we are looking for the words \u201Cpricematch\u201D or \u201Cprice\u201D & \u201Cmatch\u201D.</div>"}}return null},({jobline:e,joblines:t})=>null,({jobline:e,joblines:t})=>e.part_type&&e.part_qty!==1?{key:"Quantity Changed",alert:`<div>
Quantity manual change detected.
<ul>
<li>
MPI Estimating Standard outline that every part should have 1 line rather than manually changing the
quantity.
</li>
<li>Leaving the quantity modified <strong>MAY</strong> affect your RPS score.</li>
<li>
Consider creating manual entry lines for each part which will also disqualify those parts from your RPS
calculation.
</li>
</ul>
</div>`}:null]});var $=p(Q=>{var{DBFFile:R}=require("dbffile"),z=require("path"),A=require("lodash"),h=require("electron-log"),{store:Fe}=y(),{BrowserWindow:Ce}=require("electron"),Le=P(),{NewNotification:Se}=re(),{WhichRulesetToApply:Et}=Ie(),{claimsClerk:Gr}=Ee();async function St(e){let t=z.parse(e),r=z.join(t.dir,t.name),a=await qe(r);Ce.getAllWindows()[0].webContents.send(Le.default.estimate.toRenderer.getCloseDate,{filepath:e,clm_no:a.CLM_NO})}async function Mt(e,t){let r=await xe(e,!1,t),a=Ce.getAllWindows()[0];r&&!r.ERROR?(a.webContents.send(Le.default.estimate.toRenderer.estimateDecodeSuccess,r),h.info(`Sent job for upload. ${r.clm_no}`),Se({title:"Job Uploaded",body:"A new job has been uploaded."})):(h.info(`Ignored job. ${r.ERROR}`),Se({title:"Job Ignored",body:r.ERROR}))}Q.ImportJobWithCloseDate=Mt;async function xe(e,t=!1,r=null){let a=z.parse(e),o=z.join(a.dir,a.name),n={...await qe(o),...await Lt(o),...await xt(o),...await qt(o,r),...await Tt(o),...await Dt(o),...await Ct(o),...await kt(o),...t?{filePath:e}:{}},i=await Ft(o);n.rates=[...n.rates||[],...n.mat_rates||[]],delete n.mat_rates,n.insp_date=i.INSP_DATE,(n.OWNR_FN===""||!n.OWNR_FN)&&(n.OWNR_FN=i.CLMT_FN),(n.OWNR_LN===""||!n.OWNR_LN)&&(n.OWNR_LN=i.CLMT_LN),n.OWNR_CO_NM&&(n.OWNR_LN=`${n.OWNR_LN} ${n.OWNR_CO_NM}`),delete n.OWNR_CO_NM;let g=Fe.get("accepted_ins_co"),f;return g.includes(n.INS_CO_NM)?n.CLM_NO?n.CLM_NO.match("-01$")||n.CLM_NO.match("-99$")?(delete n.LOSS_TYPE,f=A.transform(n,function(_,k,x){_[x.toLowerCase()]=k})):(h.info("Job ignored. This is not a -01 or -99 claim. Claim #. "+n.CLM_NO),f={ERROR:"Job ignored. This is not a -01 or -99 claim. Claim #. "+n.CLM_NO}):(h.info("Job ignored. No claim #. "),f={ERROR:"An unique claim number must be set for all jobs sent to RPS."}):f={ERROR:`Insurance Company Name is not valid for RPS. (${n.INS_CO_NM||"No name set"})`},f}async function qe(e){let t;try{t=await R.open(`${e}A.AD1`)}catch(r){h.error("Error opening AD1 File.",r),t=await R.open(`${e}.AD1`),t&&h.log("Found AD1 file using regular CIECA Id.")}finally{if(!t)return{};let r=await t.readRecords(1);return A.pick(r[0],["INS_CO_NM","DED_AMT","CLM_NO","LOSS_DATE","LOSS_TYPE","LOSS_DESC","THEFT_IND","TLOS_IND","OWNR_LN","OWNR_FN","OWNR_CO_NM","OWNR_ADDR1","OWNR_CITY","OWNR_PH1"])}}async function Ft(e){let t;try{t=await R.open(`${e}B.AD2`)}catch(r){h.error("Error opening AD2 File.",r),t=await R.open(`${e}.AD2`),t&&h.log("Found AD2 file using regular CIECA Id.")}finally{if(!t)return{};let r=await t.readRecords(1);return A.pick(r[0],["CLMT_LN","CLMT_FN","INSP_DATE"])}}async function Ct(e){let t;try{t=await R.open(`${e}.PFH`)}catch(r){h.error("Error opening PFH File.",r)}finally{if(!t)return{};let r=await t.readRecords(1);return A.pick(r[0],["ID_PRO_NAM"])}}async function Lt(e){let t;try{t=await R.open(`${e}V.VEH`)}catch(r){h.error("Error opening VEH File.",r),t=await R.open(`${e}.VEH`),t&&h.log("Found VEH file using regular CIECA Id.")}finally{if(!t)return{};let r=await t.readRecords(1);return A.pick(r[0],["IMPACT_1","IMPACT_2","V_VIN","V_MODEL_YR","V_MAKEDESC","V_MODEL","V_TYPE","V_MILEAGE","V_STAGE"])}}async function xt(e){let r=await(await R.open(`${e}.TTL`)).readRecords(1);return{clm_total:r[0].G_TTL_AMT,supp_amt:r[0].SUPP_AMT,g_bett_amt:r[0].G_BETT_AMT}}async function qt(e,t){let o=(await(await R.open(`${e}.LIN`)).readRecords()).map(i=>A.transform(A.pick(i,["LINE_NO","LINE_IND","LINE_REF","DB_REF","UNQ_SEQ","LINE_DESC","PART_TYPE","PRT_DSMK_M","OEM_PARTNO","PRICE_INC","TAX_PART","DB_PRICE","ACT_PRICE","PART_QTY","PRICE_J","GLASS_FLAG","CERT_PART","ALT_PARTNO","PRT_DSMK_P","MOD_LBR_TY","DB_HRS","MOD_LB_HRS","LBR_INC","LBR_OP","LBR_HRS_J","LBR_OP_J","LBR_AMT","MISC_AMT"]),function(g,f,_){if(_==="UNQ_SEQ"){g[_.toLowerCase()]=f.toString();return}g[_.toLowerCase()]=f})),n=Fe.get("ins_rule_set");return o.map(i=>{switch(i.ignore=!1,n){case"MPI":switch(Et(t)){case"V1":i=Te(i,o);break;case"V2":i=ke(i,o);break;case"V3":i=Me(i,o);break;default:i=Me(i,o);break}break;case"SGI":h.info("Using SGI ruleset. Line will be automatically counted until rules are added.");break;default:h.info("Using default ruleset (MPI).");break}return i}),{joblines:{data:o}}}async function Tt(e){return{rates:(await(await R.open(`${e}.PFL`)).readRecords()).map(o=>A.pick(o,["LBR_TYPE","LBR_DESC","LBR_RATE"]))}}async function kt(e){return{totals:(await(await R.open(`${e}.STL`)).readRecords()).map(o=>A.pick(o,["TTL_TYPECD","T_AMT","T_HRS","NT_HRS"]))}}async function Dt(e){return{mat_rates:(await(await R.open(`${e}.PFM`)).readRecords()).map(o=>A.pick(o,["MATL_TYPE","CAL_PRETHR"]))}}Q.DecodeEstimate=xe;Q.ImportJob=St;function Te(e,t){if(e.part_type==="PAN"&&e.line_desc.toLowerCase().includes("wheel")&&Math.abs(e.prt_dsmk_m)===Math.round(e.act_price/2*100)/100&&(h.info(`Jobline '${e.line_desc}' ignored due to wheel repair.`),e.ignore=!0),e.part_type==="PAN"&&e.db_price!==e.act_price&&e.db_price!==0&&(e.db_price=e.act_price),(e.part_type==="PAA"||e.part_type==="PAL"||e.part_type==="PAN")&&e.db_price===0&&(e.ignore=!0),e.part_type!=="PAL"&&e.act_price===0&&e.price_j&&(h.info(`Jobline '${e.line_desc}' ignored because it was manually changed to 0..`),e.ignore=!0),e.line_desc.toLowerCase().includes("glass")&&e.oem_partno.match("[A-Z]{2}[0-9]{5,6}[A-Z]{3}")&&(console.log(e.line_desc,"NAGS Line ignored"),e.ignore=!0),(!e.part_type||e.db_ref.startsWith("900")||e.line_desc.toLowerCase().startsWith("urethane")||e.line_desc.toLowerCase().startsWith("w/shield adhesive")||e.line_desc.toLowerCase().includes("tire")&&!e.line_desc.toLowerCase().includes("sensor")&&!e.line_desc.toLowerCase().includes("label")||e.line_desc.toLowerCase().startsWith("hazardous")||e.line_desc.toLowerCase().startsWith("detail")||e.line_desc.toLowerCase().startsWith("clean")||e.part_type.toUpperCase()==="PAS"||e.part_type.toUpperCase()==="PASL"||e.part_type.toUpperCase()==="PAE")&&(e.ignore=!0),e.db_ref==="900511"&&e.prt_dsmk_p!==50){e.ignore=!1,e.act_price=e.prt_dsmk_m;let r=t.find(a=>parseInt(a.unq_seq)===e.line_ref);r&&r.ignore&&(e.ignore=!0)}return e.oem_partno.toLowerCase().includes("/rps-exclude")?e.ignore=!0:e.oem_partno.toLowerCase().includes("/rps")&&(e.ignore=!1),e}function ke(e,t){return Te(e,t),e.mod_lbr_ty?.toUpperCase()==="LAG"&&(e.ignore=!0),Ot.some(r=>e.line_desc.toLowerCase().includes(r))&&(e.ignore=!0),Wt.some(r=>e.line_desc.toLowerCase().includes(r))&&(e.ignore=!0),e}function Me(e,t){return ke(e,t),e}var Ot=["seat belt","air bag bolt","air bag cable reel","air bag center sensor","air bag clock","air bag coil","air bag control","air bag diagnostic","air bag driver","air bag ecs","air bag harness","air bag impact","air bag label","air bag module","air bag nut","air bag rollover","air bag rotary coupler","air bag safing sensor","air bag satellite sensor","air bag screw","air bag seat","air bag warning","air bag ocs","air bag opds","air bag sensor","air bag occupant","air bag pass","air bag system air bag terminal","air bag side","side air bag","air bag weight","air bag steering","air bag decal","air bag switch","air bag pressure","air bag pig","air bag whiplash","air bag spiral","air bag restraint","air bag wire harness","drivers knee air bag","drivers seat air bag","inform label air bag","pass air bag wire","air bag extension","air bag caution","connector air bag","curtain air bag","air bag sdm","air bag cover","air bag srs","air bag light sensor","knee air bag","air bag contact","air bag crash","air bag lwr","air bag pad","air bag suspension","air bag spacer","back air bag","air bag reel","air bag discriminating","air bag curtain","air bag initiator","air bag positive","engine wiring harness for air bag","air bag wiring","air bag combination","air bag connector","air bag plug","rear air bag","air bag clip","air bag gas","air bag bracket","suspension air bag","passenger air bag"],Wt=["frt sunroof assembly","frt sunroof glass assembly","frt sunroof glass panel","frt sunroof panel","frt sunroof sliding panel","rear sunroof glass assembly","rear sunroof glass panel","sunroof assembly","sunroof glass assembly","sunroof glass panel","sunroof sliding panel"]});var Ue=p(We=>{var q=require("electron-log"),Ut=require("axios"),ae=require("path"),{BrowserWindow:De}=require("electron"),{default:oe}=P(),{promises:Oe}=require("fs"),{autoUpdater:Vt}=require("electron-updater"),{store:Bt}=y();async function $t(e,t){try{let r=q.transports.file.getFile().path,a=ae.dirname(r),o=ae.join(a,"esjson");await Oe.mkdir(o,{recursive:!0});let n=ae.join(o,`${t}.json`);return await Oe.writeFile(n,JSON.stringify(e,null,2),"utf8"),q.debug(`Job object written to: ${n}`),console.log(`Job object written to: ${n}`),n}catch(r){throw q.error("Error writing job object to logs folder:",r),r}}async function Jt({job:e}){let t="Imex2",r="Patrick",a=Vt.channel,o;switch(a){case"alpha":o="https://4284-79287.el-alt.com";break;case"beta":o="https://4284-79073.el-alt.com";break;default:o="https://insurtechtoolkit.com";break}q.log(`Estimate Scrubber URL: [${a} |`,o);let n="87330f61-412b-4251-baaa-d026565b23c5";try{let i=e?.bodyshop?.es_api_key;if(!e){console.error("No job provided to ScrubEstimate");return}let g;switch(Bt.get("ins_rule_set")){case"MPI":g="ATAM";break;case"SGI":g="SAAR";break;default:g="ATAM";break}e.sending_entity_id=n,e.sending_entity_accept_terms_of_use=!0,e.association_switch=g,e.rf_zip=e.bodyshop.zip_post,e.rf_ph1=e.bodyshop.phone,e.g_ttl_amt=e.clm_total,e.source_system="M",e.v_mileage=e.v_mileage?.toString()||"",delete e.clm_total,delete e.bodyshop,e.rates&&Array.isArray(e.rates)&&e.rates.forEach(w=>{w.MATL_TYPE&&(w.MAT_TYPE=w.MATL_TYPE,delete w.MATL_TYPE)}),e.rates&&Array.isArray(e.rates)&&(e.rates=e.rates.map(w=>{let F={};for(let[D,O]of Object.entries(w))F[D.toLowerCase()]=O;return F})),e.totals&&Array.isArray(e.totals)&&(e.totals=e.totals.map(w=>{let F={};for(let[D,O]of Object.entries(w))F[D.toLowerCase()]=O;return F}));let f=`RPS-Scrub-${i}-${e.clm_no}-${Date.now()}`;try{await $t(e,f)}catch(w){q.error("Failed to write job to logs folder:",w)}let _=new FormData,k=JSON.stringify(e);_.append("file",new Blob([k],{type:"application/json"}),`${f}.json`);let x=await Ut.post(`${o}/api/sendems`,_,{auth:{username:t,password:r},headers:{..._.getHeaders?_.getHeaders():{},APIkey:i}}),B=x?.data?.report_link,H=`https://insurtechtoolkit.com/pcontactUs.aspx?apiKey=${i}&file=${f}.json`;return De.getAllWindows()[0].webContents.send(oe.app.toRenderer.scrubResults,{jobid:e.id,items:x.data?.identified_item,pdfUrl:B,reportIssueUrl:H}),B}catch(i){q.error("Error while scrubbing estimate:",i,i.stack),q.error("Error Response Data:",i.response?.data);let g=De.getAllWindows()[0];i.status===400?g.webContents.send(oe.app.toRenderer.scrubError,{message:i.response?.data||"Error encountered sending estimate to Estimate Scrubber."}):i.status===401&&g.webContents.send(oe.app.toRenderer.scrubError,{message:"Authentication with Estimate Scrubber failed."})}}We.ScrubEstimate=Jt});var Be=p(X=>{var Gt=require("chokidar"),ne=P(),Yt=require("path"),{ImportJob:Ht}=$(),{BrowserWindow:se}=require("electron"),{store:K}=y(),{NewNotification:ie}=re(),I=require("electron-log"),L;async function zt(){let e=K.get("filePaths")||[];if(I.info("Use polling? ",K.get("polling").enabled),e.length===0)return ie({title:"RPS Watcher cannot start",body:"Please set the appropriate file paths and try again."}),I.warn("Cannot start watcher. No file paths set."),[];if(L)try{I.info("Trying to close watcher - it already existed."),await L.close(),I.info("Watcher closed successfully!")}catch(t){I.error("Error trying to close Watcher.",t)}return L=Gt.watch(e,{ignored:(t,r)=>{let a=Yt.parse(t);return a.ext!==""&&a.ext.toUpperCase()!==".ENV"},usePolling:K.get("polling").enabled||!1,interval:K.get("polling").pollingInterval||1e3,persistent:!0,ignoreInitial:!0,awaitWriteFinish:{pollInterval:500,stabilityThreshold:2e3}}),L.on("add",async function(t){console.log("File",t,"has been added"),Ve(t)}).on("change",async function(t){console.log("File",t,"has been changed"),Ve(t)}).on("error",function(t){I.error("Error in Watcher",t);let r=se.getFocusedWindow();r&&r.webContents.send(ne.default.fileWatcher.toRenderer.error,t)}).on("ready",Qt).on("raw",function(t,r,a){}),e}function Qt(){I.info("Watcher ready!"),se.getAllWindows()[0].webContents.send(ne.default.fileWatcher.toRenderer.startSuccess),ie({title:"RPS Watcher Started",body:"Newly exported estimates will be automatically uploaded."}),I.info("Confirmed watched paths:",L.getWatched())}async function Kt(){L&&(await L.close(),I.info("Watcher stopped."),se.getAllWindows()[0].webContents.send(ne.default.fileWatcher.toRenderer.stopSuccess),ie({title:"RPS Watcher Stopped",body:"Estimates will not be automatically uploaded."}))}X.StartWatcher=zt;X.StopWatcher=Kt;X.watcher=L;async function Ve(e){await Ht(e)}});var le=p(()=>{var Xt=require("path"),Zt=require("fs"),$e=Xt.join(__dirname,"..","dist-electron","main.cjs"),jt=!require("electron-is-dev")&&Zt.existsSync($e);jt?require($e):Je()});var Ye=p(()=>{var{ipcMain:J,dialog:er}=require("electron"),{StartWatcher:tr,StopWatcher:de}=Be(),E=P(),{mainWindow:rr}=le(),ar=require("lodash"),{store:v}=y(),Ge=require("path");J.on(E.default.fileWatcher.toMain.filepathsGet,async(e,t)=>{e.reply(E.default.fileWatcher.toRenderer.filepathsList,v.get("filePaths"))});J.on(E.default.fileWatcher.toMain.start,async(e,t)=>{(t&&t.startup&&v.get("runWatcherOnStartup")||!t)&&tr(),e.sender.send(E.default.fileWatcher.toRenderer.filepathsList,v.get("filePaths"))});J.on(E.default.fileWatcher.toMain.stop,async(e,t)=>{de()});J.on(E.default.fileWatcher.toMain.addPath,async(e,t)=>{let r=await er.showOpenDialog(rr,{properties:["openDirectory"]});de(),v.set("filePaths",ar.union(r.filePaths,v.get("filePaths")));let a=v.get("filePaths");e.sender.send(E.default.fileWatcher.toRenderer.filepathsList,a)});J.on(E.default.fileWatcher.toMain.removePath,async(e,t)=>{de(),v.set("filePaths",v.get("filePaths").filter(a=>{let o=Ge.parse(a),n=Ge.parse(t);return o.dir+o.base!==n.dir+n.base}));let r=v.get("filePaths");e.sender.send(E.default.fileWatcher.toRenderer.filepathsList,r)})});var Ke=p(ue=>{var ze=require("path"),or=require("fs"),{store:Qe}=y(),He=require("electron-log"),ce=or.promises,{DecodeEstimate:nr}=$();async function sr(){He.info("Scanning all local estimates..");let e=await lr(),t=await ir(e),r=t.filter(a=>!a.ERROR);return He.log("Number of estimates filtered on file scan due to error: ",t.length-r.length),r}async function ir(e){return await Promise.all(e.map(async t=>await nr(t,!0)))}async function lr(){let e=Qe.get("filePaths"),t=[];return await Promise.all(e.map(async r=>{(await ce.readdir(r)).filter(o=>o.toUpperCase().includes(".ENV")).map(o=>(t.push(ze.join(r,o)),null))})),t}async function dr(){try{let e=Qe.get("filePaths"),t=[];return await Promise.all(e.map(async r=>{(await ce.readdir(r)).map(o=>(t.push(ze.join(r,o)),null))})),await Promise.all(t.map(async r=>{await ce.unlink(r)})),!0}catch{return!1}}ue.GetListOfEstimates=sr;ue.DeleteAllEms=dr});var Ze=p(()=>{var{ipcMain:pe}=require("electron"),G=P(),{ImportJob:cr}=$(),{GetListOfEstimates:Xe,DeleteAllEms:ur}=Ke();pe.on(G.default.fileScan.toMain.scanFilePaths,async(e,t)=>{let r=await Xe();e.reply(G.default.fileScan.toRenderer.scanFilePathsResponse,r)});pe.on(G.default.fileScan.toMain.importJob,async(e,t)=>{await cr(t)});pe.on(G.default.fileScan.toMain.deleteAllEms,async(e,t)=>{await ur();let r=await Xe();e.reply(G.default.fileScan.toRenderer.scanFilePathsResponse,r)})});var at=p(()=>{var{ipcMain:je,dialog:pr}=require("electron"),W=P(),{mainWindow:fr}=le(),ra=require("lodash"),{store:et}=y(),aa=require("path"),tt=require("node-xlsx"),rt=require("electron-log");je.on(W.default.audit.toMain.browseForFile,async(e,{sheetName:t})=>{let r=await pr.showOpenDialog(fr,{filters:[{extensions:["xls","xlsx"],name:"Excel Files"}],properties:["openFile"]});if(!r.canceled)try{var a=tt.parse(r.filePaths[0],{cellDates:!0});et.set("auditFilePath",r.filePaths),e.sender.send(W.default.audit.toRenderer.auditFilePath,{filePath:r.filePaths[0],sheets:a.map(o=>o.name)})}catch(o){console.log("Got some sort of err",o),rt.error("Error when trying to read audit xlsx file",o),e.sender.send(W.default.audit.toRenderer.auditError,o.meFssage)}});je.on(W.default.audit.toMain.runAudit,async(e,{sheetName:t})=>{try{let a=et.get("auditFilePath");var r=tt.parse(a[0],{cellDates:!0});let o=r.find(s=>s.name===t),n=[],i,g,f,_,k,x,B,H,te,w,F,D,O,_e,we,be;o.data.forEach(s=>{if(!i&&s[0]==="Claim Number")i=!0,f=s.findIndex(l=>l==="Claim Number"),_=s.findIndex(l=>l==="Ready for Pay Date"),k=s.findIndex(l=>l==="Vehicle Year"),x=s.findIndex(l=>l==="Vehicle Make"),B=s.findIndex(l=>l==="Vehicle Model"),H=s.findIndex(l=>l==="Under 20K"),te=s.findIndex(l=>l==="OE Part Prices"),w=s.findIndex(l=>l==="AM Part Prices"),F=s.findIndex(l=>l==="Recycled Part Prices"),D=s.findIndex(l=>l==="Reman & Other Part Prices"),O=s.findIndex(l=>l==="(a) Eligible OEM Part Prices"),_e=s.findIndex(l=>l==="(b) Eligible Actual Part Prices"),we=s.findIndex(l=>l==="(e) Expected RPS $ "),be=s.findIndex(l=>l==="(f) Actual RPS $");else if(i&&!g&&s[0]&&s[0]!=="Grand Total"){let l={clm_no:s[f].startsWith("00")?s[f].slice(2):s[f],close_date:s[_],v_model_yr:s[k],v_makedesc:s[x],v_model:s[B],under20kmiles:s[H],pan_total:s[te],paa_total:s[w],pal_total:s[F],pam_total:s[D],eligible_db_price_total:Math.round((s[O]+Number.EPSILON)*100)/100,eligible_act_price_total:Math.round((s[_e]+Number.EPSILON)*100)/100,expected_rps_dollars:Math.round((s[we]+Number.EPSILON)*100)/100,actual_rps_dollars:Math.round((s[be]+Number.EPSILON)*100)/100};n.push(l)}}),e.sender.send(W.default.audit.toRenderer.auditClaimsArray,n)}catch(a){console.log("ot some sort of err",a),rt.error("Error when trying to read audit xlsx file",a),e.sender.send(W.default.audit.toRenderer.auditError,a.message)}})});var fe=p((sa,gr)=>{gr.exports={"1.0.9":{title:"Release Notes for 1.0.9",date:"11/17/2020",notes:`New Features:
- Vehicles with mileage under 20,000kms will now be included in Watcher filtering criteria.
- Savings on OEM parts will always default to the user enter price and override the estimating system price.
- Wheel related lines will no longer be automatically ignored.
- Glass related lines will no longer be automatically ignored.
- Added 'Variance %' statistic to reporting totals.
- Automatically ignore any lines which have invalid prices from estimating system.
- Force line inclusion/exclusion - Using \u201C /rps-exclude\u201D or \u201C/rps\u201D in the Part Number field to force inclusion or exclusion of lines for RPS calculation.
- Added automatic update checks every 30 minutes.
Bug Fixes:
- Resolved an issue where the updater would not show update progress to some users.
- Fixed a UI bug during job search that would cause the 'no close date' alert to be incorrectly shown.`},"1.0.10":{title:"Release Notes for 1.0.10",date:"11/19/2020",notes:`Bug Fixes:
- Resolved an issue where N/A prices were being incorrectly included.
- Resolved a bug where clicking yes during update would not install the update.`},"1.0.11":{title:"Release Notes for 1.0.11",date:"11/24/2020",notes:`Bug Fixes:
- Added remanufactured as a part type dislpay instead of 'PAM'.
- Resolve an issue where group would occasionally not be preserved when changed.
- Added 'Reman' as a displayed part type.`},"1.0.12":{title:"Release Notes for 1.0.12",date:"11/26/2020",notes:`New Features:
- Added a reference guide for MPI Grouping Guidelines next to the Group Descriptor on the estimate screen.
- Added ability to filter for jobs with no close date on job search.
Bug Fixes:
- Added better error handling on reporting for jobs that did not have a group set.
- Added a confirmation on changes to shop settings to indicate that a restart is required for them to take effect.
- Added auto update download for users who are not seeing progress during update download.`},"1.0.13":{title:"Release Notes for 1.0.13",date:"11/30/2020",notes:`New Features:
- Added 'This Quarter' and 'Last Quarter' date quick select.
Bug Fixes:
- Added automatic job refresh on new import for estimate detail screen.
- Fixed an issue where more jobs would not be fetched in the list view in certain scenarios.`},"1.0.14":{title:"Release Notes for 1.0.14",date:"12/18/2020",notes:`Bug Fixes:
- Resolved an issue where launching a second instance of RPS could cause the program to occasionally freeze.
- Fixed an issue where date filtering could include dates outside the range depending on time zone.
- Added negative RPS calculations on combined estimate lines like assemblies.`},"1.0.15":{title:"Release Notes for 1.0.15",date:"01/12/2021",notes:`New Features:
- Renamed 'Close Date' to 'Ready for Payment' to better align with MPI terminology.
- Changed vehicle age calculation to use 'Ready for Payment' instead of loss date as per new MPI practices.
Bug Fixes:
- Updated grouping typo on group lookup popup.`},"1.0.16":{title:"Release Notes for 1.0.16",date:"01/12/2021",notes:`Bug Fixes:
- Resolved an issue where vehicle age was calculated using an old date.`},"1.0.17":{title:"Release Notes for 1.0.17",date:"02/17/2021",notes:`New Features:
- Implemented the new vehicle groupings by MPI.
- Implemented new model based group detection to provide more accurate groupings than relying solely on the estimating system. *
- Added group verification to disable alerts and track whether a grouping has already been reviewed and confirmed.
Bug Fixes:
- Updated ignore logic for recycled glass.
* Please send feedback on the model groupings if you notice any issues to support@thinkimex.com. `},"1.0.18":{title:"Release Notes for 1.0.18",date:"04/15/2021",notes:`Bug Fixes:
- Updated rare bug in vehicle age calculation.
- Improved wheel repair calculation logic.
- Improved $0 price recognition for Aftermarket and Recycled parts.`},"1.0.19":{title:"Release Notes for 1.0.19",date:"04/19/2021",notes:`Bug Fixes:
- Improved validation for mileage from estimating systems to be more fault tolerant.`},"1.0.20":{title:"Release Notes for 1.0.20",date:"04/29/2021",notes:`Bug Fixes:
- Resolved age calculation issue for some 2021 models.`},"1.0.21":{title:"Release Notes for 1.0.21",date:"05/07/2021",notes:`New Features:
- Improved glass parts recognition.
- Added additional models for more accurate group detection.`},"1.0.22":{title:"Release Notes for 1.0.22",date:"05/20/2021",notes:`New Features:
- Added support Line Discounting
- Ignored lines will now automatically reset when importing to ensure lines are not ignored when updated in place.
Bug Fixes:
- Improved detection of $0 price items.`},"1.0.23":{title:"Release Notes for 1.0.23",date:"10/13/2021",notes:`New Features:
- Improved detection of glass and glass related lines.
- Improved detection of manual part changes.`},"1.0.24":{title:"Release Notes for 1.0.24",date:"11/08/2021",notes:`New Features:
- Resolved age calculation issue for model year 2022 vehicles.`},"1.0.25":{title:"Release Notes for 1.0.25",date:"12/01/2021",notes:`New Features:
- Updated Vehicle categorization lists.
- Improved N/A/$0 line item detection and calculations.`},"1.0.26":{title:"Release Notes for 1.0.26",date:"12/06/2021",notes:`Bug Fix:
- Improved handling of company names coming from Mitchell Cloud Estimating.`},"1.0.27":{title:"Release Notes for 1.0.27",date:"02/17/2022",notes:`Bug Fix:
- Improved handling $0 DB items from Mitchell Cloud Estimating.
- Adjusted handling of part quantities during calculation.
- Removed line discounts from count of RPS eligible parts in header.
- Added automatic exlcusion for -02 estimates.`},"1.0.28":{title:"Release Notes for 1.0.28",date:"05/26/2022",notes:`Bug Fix:
- Improved SUV detection.`},"1.1.0":{title:"Release Notes for 1.1.0",date:"03/29/2023",notes:`***Major Update***\r
Added support for new rules coming into effect on April 1, 2023.\r
These rules come into effect based on the R4P date of the job. If you bring in a job before April 1, and set the R4P date after April 1, you will need to reimport the job and the system will warn you accordingly.\r
\r
Bug Fixes: \r
- Improved SUV recognition.`},"1.1.1":{title:"Release Notes for 1.1.1",date:"03/30/2023",notes:"Minor bug fix."},"1.1.2":{title:"Release Notes for 1.1.2",date:"04/12/2023",notes:`Bug Fixes:\r
Resolved an issue where the incorrect ruleset could apply to a job on first import.`},"1.1.3":{title:"Release Notes for 1.1.3",date:"08/15/2023",notes:`Bug Fixes:\r
- Added additional SUV and Truck models.\r
- Searches must now be at least 4 characters to prevent long running searches.\r
- Added right click context menu.`},"1.1.4":{title:"Release Notes for 1.1.4",date:"08/16/2023",notes:`Bug Fixes:\r
- Fix an issue when searching for jobs without an R4P date.`},"1.1.5":{title:"Release Notes for 1.1.5",date:"08/23/2023",notes:`Bug Fixes:\r
- Performance improvements.`},"1.1.6":{title:"Release Notes for 1.1.6",date:"10/13/2023",notes:`New Feature:\r
- Added live support chat.`},"1.1.7":{title:"Release Notes for 1.1.7",date:"10/19/2023",notes:`Bug Fixes:\r
- Minor bug fixes and improvements.`},"1.1.8":{title:"Release Notes for 1.1.8",date:"02/07/2024",notes:`Bug Fixes:\r
- Improved detection for wheel related repair lines.`},"1.2.0":{title:"Release Notes for 1.2.0",date:"05/21/2024",notes:`New Features
* Introducing Score Card Auditing. Simply select your MPI scorecard and instantly compare it to your RPS score card to find discrepancies. Available in your side bar
Improvements
* Added additional models to SUV and Van databases for better detection.
* Only -01 and -99 claims will now be brought into RPS.
* Under the hood fixes and improvements.`},"1.2.1":{title:"Release Notes for 1.2.1",date:"05/23/2024",notes:`Improvements
* UI improvements for audit functionality.`},"1.2.2":{title:"Release Notes for 1.2.2",date:"06/21/2024",notes:`Improvements
* Additional SUV models added.`},"1.3.0":{title:"Release Notes for 1.3.0",date:"08/16/2024",notes:`New Features
* Added support for new MPI rules. The rules will apply to all jobs with an R4P date on or after September 1, 2024. If a job R4P date is changed across this date, the job will need to be reimported to have correct scoring.`},"1.3.1":{title:"Release Notes for 1.3.1",date:"08/16/2024",notes:`Bug Fix
* Resolved incorrect targets for vehicles under 20,000 miles under current rule set.`},"1.3.2":{title:"Release Notes for 1.3.2",date:"09/06/2024",notes:`Improvements
* Sourced an additional 150 models for improved detection of SUVs and Vans.\r
* Added the ability to change groups for jobs imported under the latest set of MPI rules.`},"1.3.3":{title:"Release Notes for 1.3.3",date:"10/08/2024",notes:`Improvements
*Added new SUV models.\r
* Added a warning when quantities great than 1 were detected.\r
* Change of rules will now also detect for jobs without R4P dates set.`},"1.3.4":{title:"Release Notes for 1.3.4",date:"10/11/2024",notes:`Bug Fix
*Fix typos on application labels.`},"1.3.5":{title:"Release Notes for 1.3.5",date:"10/17/2024",notes:`Improvements:\r
* Improved group detection for latest RPS rule sets.\r
* Audit functionality will now rely on header names instead of order.`},"1.4.0":{title:"Release Notes for 1.4.0",date:"06/17/2025",notes:`New Features: \r
* Added a scenario manager to scorecards to dynamically remove and add jobs to see impacts without adjusting dates.\r
* Added ability to print a job. \r
\r
Improvements:\r
* Added dark mode for app.\r
* Added variance dollars to the scorecard.\r
* Adjusted layout of job details to more prominently display savings information.`},"1.4.1":{title:"Release Notes for 1.4.1",date:"07/04/2025",notes:`Improvements:\r
* Increased performance of scenario manager.\r
* Report lines will now display better on smaller screens.\r
* Job RPS printouts will now display in landscape mode and ignore dark mode styling.`},"1.4.2-beta.4":{title:"Release Notes for 1.4.2-beta.4",date:"09/16/2025",notes:`New Features:\r
* Added part quantity toggle to shop setup. This will use the part quantity from the job lines when calculating RPS instead of assuming 1 per MPI guidelines.\r
\r
Improvements:\r
* Updated ES integration to use newly specified API keys.`},"1.5.0":{title:"Release Notes for 1.5.0",date:"10/29/2025",notes:`New Features:\r
* Direct integration to Estimate Scrubber is now available in Public Beta. Existing customers should automatically have access to this feature. If you encounter any issues, please reach out to support.\r
* Added a quantity toggle to use line quantity instead of assuming 1 per MPI guidelines for RPS calculations.\r
* Added date shortcuts to the report page for ease of use.\r
* Added a floating shortcut to run 1 month and 3 month reports.\r
\r
Improvements:\r
* Added better indicators for quantities and negative RPS values.`}}});var ot=p(()=>{var{ipcMain:m,app:hr,app:mr,BrowserWindow:_r}=require("electron"),{default:u}=P(),{store:T}=y(),Z=require("electron-log"),{ImportJobWithCloseDate:wr}=$(),{ScrubEstimate:br}=Ue();Ye();Ze();at();console.log("*** Added IPC Handlers ***");m.on("test",async(e,t)=>{console.log("Received test IPC Command"),e.reply("test-toRenderer",{status:0,message:null})});m.on(u.app.toMain.setAcceptableInsCoNm,(e,t)=>{T.set("accepted_ins_co",t)});m.on(u.store.get,(e,t)=>{let r=T.get(t);e.sender.send(u.store.response,{[t]:r})});m.on(u.store.set,(e,t,r)=>{T.set(t,r);let a=T.get();e.sender.send(u.store.response,a)});m.on(u.store.getAll,(e,t)=>{let r=T.get();e.sender.send(u.store.response,r)});m.on(u.app.toMain.getReleaseNotes,(e,t)=>{if(T.get("showChangeLog")){let a=fe()[hr.getVersion()];e.sender.send(u.app.toRenderer.setReleaseNotes,a)}else e.sender.send(u.app.toRenderer.setReleaseNotes,null)});m.on(u.app.toMain.importJob,(e,{filepath:t,close_date:r})=>{wr(t,r)});m.on(u.app.toMain.log.debug,(e,...t)=>{Z.debug(t)});m.on(u.app.toMain.log.info,(e,...t)=>{Z.info(t)});m.on(u.app.toMain.log.warn,(e,...t)=>{Z.warn(t)});m.on(u.app.toMain.log.error,(e,...t)=>{Z.error(t)});m.on(u.app.toMain.getAppVersion,(e,t)=>{e.sender.send(u.app.toRenderer.appVersion,mr.getVersion())});m.handle(u.app.toMain.scrubEstimate,(e,{job:t})=>br({job:t}));m.on(u.app.toMain.openExternalWindow,(e,t)=>{let r=new _r({width:1200,height:800,webPreferences:{nodeIntegration:!1,contextIsolation:!0}});r.loadURL(t),r.webContents.setWindowOpenHandler(({url:a})=>(require("electron").shell.openExternal(a),{action:"deny"}))});m.on(u.app.toMain.setInsRuleSet,(e,t)=>{T.set("ins_rule_set",t)})});var ct=p(()=>{var{ipcMain:st}=require("electron"),nt=require("electron-log"),{default:it}=P(),lt=require("@amplitude/analytics-node"),{store:yr}=y(),Rr=yr.get("deviceId"),{app:Pr}=require("electron"),dt;lt.init("a733ff926aef84f93baf95e66b5dcb75");st.on(it.app.toMain.setUserName,(e,t)=>{dt=t});st.on(it.app.toMain.track,(e,t)=>{nt.log("Analytics Event",t);let{event:r,...a}=t;try{lt.track(r,a,{device_id:Rr,user_id:dt,app_version:Pr.getVersion()})}catch(o){nt.error(o)}})});var Je=p(ht=>{var V=require("path"),{app:c,BrowserWindow:he,Tray:Ar,Menu:me,ipcMain:Y,dialog:Nr,shell:ge,globalShortcut:Ir}=require("electron"),S=require("electron-is-dev"),{default:N}=P(),{store:j}=y(),{autoUpdater:b}=require("electron-updater"),M=require("electron-log"),vr=require("electron-context-menu"),Er=require("@sentry/electron/main");ot();ct();Er.init({dsn:"https://9840e0f304124299e379d9347e12d2e6@o492140.ingest.sentry.io/4505728058523648",ignoreErrors:["SimpleURLLoaderWrapper","Cannot read properties of null (reading 'webContents')","EBUSY: resource busy or locked"]});b.autoDownload=!0;b.logger=M;b.logger.transports.file.level="info";M.info("App starting...",c.getVersion());var pt,ft;if(S){let e=require("electron-devtools-installer");pt=e.default,ft=e.REACT_DEVELOPER_TOOLS}var Sr=me.buildFromTemplate([{label:"File",submenu:[{label:"Relaunch",click(){c.exit(),c.relaunch()}},{label:"Clear Settings",click(){j.reset("filePaths"),d.webContents.session.clearStorageData()}},{label:"Sign Out",click(){d.webContents.send(N.app.toRenderer.signOut)}},{label:"Exit",click(){c.quit()}}]},{label:S?"DEVELOPMENT -- HELP":"Help",submenu:[{label:"Rescue",click(){ge.openExternal("http://imexrescue.com")}},{label:`Check for Updates (currently ${c.getVersion()})`,click(){ee()}},{label:"Show Release Notes",click(){d.webContents.send(N.app.toRenderer.setReleaseNotes,fe()[c.getVersion()])}},{label:"Open Config File",click(){ge.openPath(j.path)}},{label:"Open Log File",click(){ge.openPath(V.join(c.getPath("appData"),"ImeX RPS\\logs"))}},{label:"Third Party Notices",click(){Fr()}}]}]),d,U,ut=null;vr({showInspectElement:!1});function gt(){me.setApplicationMenu(Sr),d=new he({title:`ImEX RPS ${c.getVersion()}`,icon:V.join(__dirname,"../src/assets/logo192.png"),webPreferences:{nodeIntegration:!1,enableRemoteModule:!1,webSecurity:!0,worldSafeExecuteJavaScript:!0,contextIsolation:!0,devTools:S,preload:V.join(__dirname,"preload.js")}}),c.requestSingleInstanceLock()?(c.on("second-instance",(t,r,a)=>{d&&(d.isMinimized()&&d.restore(),d.show(),d.focus(),d.maximize())}),d.loadURL(S?"http://localhost:3000":`file://${V.join(__dirname,"/../build/index.html")}`),d.on("minimize",function(t){t.preventDefault(),d.hide(),ut||(ut=Mr())}),Y.on(N.quit,(t,r)=>{c.isQuiting=!0,c.quit()}),S&&d.webContents.openDevTools({}),d.maximize(),S&&Ir.register("CommandOrControl+Shift+I",()=>{d.webContents.toggleDevTools()})):c.quit()}ht.mainWindow=d;c.whenReady().then(()=>{gt(),S&&(console.log(`Path to Settings File: ${j.path}`),console.log(`Path to Log File: ${M.log}`),pt(ft).then(e=>console.log(`Added Extension: ${e}`)).catch(e=>console.log(`An error occurred: , ${e}`))),setInterval(()=>{ee()},1e3*60*30)});S?c.setAppUserModelId(process.execPath):c.setAppUserModelId("com.imex.rps");c.on("window-all-closed",()=>{process.platform!=="darwin"&&c.quit()});c.on("activate",()=>{console.log("Activate"),he.getAllWindows().length===0&&gt()});function Mr(){let e=new Ar(V.join(__dirname,"../src/assets/logo192.png")),t=me.buildFromTemplate([{label:"Show",click:function(){d.show()}},{label:"Exit",click:function(){c.isQuiting=!0,c.quit()}}]);return e.on("double-click",function(r){d.show(),d.maximize()}),e.setToolTip(`ImEX RPS ${c.getVersion()}`),e.setContextMenu(t),e}function ee(){try{b.checkForUpdates()}catch(e){M.error("Error checking for updates",e)}}function Fr(){if(U){U.show();return}U=new he({width:900,height:700,title:"Third Party Notices",webPreferences:{nodeIntegration:!1,contextIsolation:!0,devTools:S}}),U.loadURL(`file://${V.join(__dirname,"licenses.txt")}`),U.on("closed",()=>{U=null})}b.on("update-available",e=>{M.log("Update available.",e),d&&d.webContents.send(N.app.toRenderer.updateAvailable,e)});b.on("update-not-available",e=>{M.log("Update not available.",e)});b.on("error",(e,t)=>{M.log("Error in auto-updater.",e,t)});Y.on(N.app.toMain.setReleaseChannel,(e,t)=>{b.channel=t,ee()});Y.on(N.app.toMain.checkForUpdates,(e,t)=>{ee()});Y.on(N.app.toMain.downloadUpdates,(e,t)=>{b.downloadUpdate()});Y.on(N.app.toMain.installUpdates,(e,t)=>{b.quitAndInstall(!0,!0)});b.on("download-progress",e=>{M.log("Download Progress:",e),d&&d.webContents.send(N.app.toRenderer.downloadProgress,e)});b.on("update-downloaded",(e,t)=>{d&&d.webContents.send(N.app.toRenderer.downloadProgress,{...e,percent:100}),Nr.showMessageBox({type:"info",title:"ImeX RPS Update Manager",message:`ImEX RPS is ready to update to Version ${e.version}. It is highly recommended that you update immediately. Would you like to update now? RPS will automatically restart.`,buttons:["Yes","No"]}).then(({response:r})=>{r===0?(j.set("showChangeLog",!0),b.quitAndInstall(!0,!0)):M.warn("Updated ignored.")})})});module.exports=Je();