PageSourceSearch

https://myka.ng/assets/VerifyImeiPage-BJf4ERrk.js

js myka.ng collected 2026-10-09 22:42:28 UTC 14,778 bytes, 1 lines download raw bytes

1import{r as C,j as n,d as Q}from"./vendor-react-DfYGAhtm.js";import{b5 as V,b6 as K,b7 as L,aB as X,b8 as Z}from"./vendor-icons-1odZwi-b.js";import{m as r,g as J,t as D,b2 as ee,b3 as re,a as te,x as oe,c as ne,B as T,o as ae,A as se,b4 as ie}from"./index-DsBgCU7r.js";import{u as ce}from"./useOpenLoginModalOnAuthRequired-D6y-uK5-.js";import{u as le}from"./useAnalytics-HP01GbIH.js";import{a as de,b as ue}from"./gadgetPolicyApi-C0LGK2Xi.js";import{h as me,u as ge}from"./vendor-state-BsBVN-fX.js";import{O as pe,a as fe,b as he,c as xe,d as ye,e as P,f as be,g as Ie,h as Ee,i as Ce,j as _e}from"./ocrConfig-B-KSx9JM.js";import{M as B}from"./constants-9aQr_m9y.js";import{a as M,V as A,T as y,F as v,v as j,I as k,S as Se}from"./vendor-ui-DA_r9yXk.js";import{g as z}from"./errors-BYKXB8DF.js";import{G as $}from"./routes-CNOe4p0Z.js";import{e as Me,b as Ae}from"./manualDeviceMappers-BKIysACn.js";import"./gadgetPostPaymentFlowConfig-ChCU4qBA.js";import"./vendor-forms-BP-7CbAP.js";import"./LinkPaymentMethodOption-CuZHpNDU.js";import"./checkoutSessionStore-BRM5sYZN.js";const we=e=>new Promise((t,a)=>{const o=new FileReader;o.onload=()=>t(o.result),o.onerror=()=>a(new Error("Could not read image file. Please try a different one.")),o.readAsDataURL(e)}),Te=e=>new Promise((t,a)=>{const o=new Image;o.onload=()=>t(o),o.onerror=()=>a(new Error("That image couldn't be opened. Try a different file.")),o.src=e}),ve=(e,t,a)=>{const o=Math.max(e,t);if(o<=a)return{width:e,height:t};const l=a/o;return{width:Math.round(e*l),height:Math.round(t*l)}},U=e=>{const t=e.indexOf(",");return t>=0?e.slice(t+1):e},W=e=>Math.ceil(e.length*3/4),De=async(e,t={})=>{const a=t.maxDimension??pe,o=t.maxBytes??fe,l=t.initialQuality??he,d=t.minQuality??xe,i=await we(e),c=await Te(i),{width:u,height:s}=ve(c.naturalWidth||c.width,c.naturalHeight||c.height,a),m=document.createElement("canvas");m.width=u,m.height=s;const h=m.getContext("2d");if(!h)throw new Error("Your browser couldn't process the image. Please try again.");h.drawImage(c,0,0,u,s);let g=l,b=m.toDataURL("image/jpeg",g),p=U(b),I=W(p);for(;I>o&&g>d;)g=Math.max(d,g-.1),b=m.toDataURL("image/jpeg",g),p=U(b),I=W(p);return{base64:p,mimeType:"image/jpeg",sizeBytes:I}},N=15,R=e=>{if(!/^\d{15}$/.test(e))return!1;let t=0;for(let a=0;a<N;a+=1){let o=Number.parseInt(e[a],10);a%2===1&&(o*=2,o>9&&(o-=9)),t+=o}return t%10===0},G=e=>e.replace(/O/g,"0").replace(/[Il|]/g,"1").replace(/B/g,"8").replace(/S/g,"5").replace(/Z/g,"2").replace(/G/g,"6"),je=e=>{for(let t=0;t+N<=e.length;t+=1){const a=e.slice(t,t+N);if(R(a))return a}return null},Ne=e=>{if(!e)return null;const t=e.split(/[\r\n]+/).map(d=>d.trim()).filter(Boolean);for(let d=0;d<t.length;d+=1){const i=t[d];if(!/IMEI/i.test(i))continue;const c=[],u=i.replace(/^.*?IMEI\s*[12]?\s*[:-]?\s*/i,"");u&&c.push(u);const s=t[d+1];s&&!/^(IMEI|EID|ICCID|SN\b|Serial)/i.test(s)&&c.push(s);for(const m of c){const h=m.split("/")[0]??"",g=G(h).replace(/[^0-9]/g,""),b=je(g.slice(0,20));if(b)return b}}const a=G(e),o=a.match(new RegExp("(?<!\\d)\\d{15}(?!\\d)","g"))??[];for(const d of o)if(R(d))return d;const l=a.match(new RegExp("(?<!\\d)\\d[\\d -]{13,17}\\d(?!\\d)","g"))??[];for(const d of l){const i=d.replace(/\D/g,"");if(i.length===N&&R(i))return i}return null};class E extends Error{code;constructor(t,a){super(a),this.name="ImeiOcrError",this.code=t}}const Pe=e=>Ce.includes(e.type),Re=e=>{const t=Array.isArray(e.ErrorMessage)?e.ErrorMessage.join(" "):e.ErrorMessage,a=e.ParsedResults?.[0]?.ErrorMessage,o=Array.isArray(a)?a.join(" "):a;return[t,o,e.ErrorDetails].filter(Boolean).join(" ").trim()},Oe=async(e,t)=>{if(!Pe(e))throw new E("invalid-file-type","Please upload a JPG, PNG, or WEBP image.");if(e.size>ye)throw new E("file-too-large","That image is too large. Please pick one under 10 MB.");if(!P||P==="your-ocr-space-key-here")throw new E("missing-api-key","IMEI scanning is temporarily unavailable. Please enter the IMEI manually.");const a=await De(e),o=new FormData;o.append("base64Image",`data:${a.mimeType};base64,${a.base64}`),o.append("isOverlayRequired","false"),o.append("detectOrientation","true"),o.append("scale","true"),o.append("language","eng"),o.append("OCREngine",be);const l=new AbortController,d=setTimeout(()=>l.abort(),Ie);let i;try{i=await fetch(Ee,{method:"POST",headers:{apikey:P},body:o,signal:l.signal})}catch(m){const h=m instanceof DOMException&&m.name==="AbortError"||m instanceof Error&&m.name==="AbortError";throw new E(h?"ocr-timeout":"ocr-request-failed",h?"Scanning took too long. Please try again or enter the IMEI manually.":"We couldn't reach the IMEI scanner. Check your connection and try again.")}finally{clearTimeout(d)}if(!i.ok)throw new E("ocr-request-failed",`IMEI scanner returned an error (${i.status}). Please try again.`);let c;try{c=await i.json()}catch{throw new E("ocr-request-failed","We couldn't read the scanner response. Please try again.")}if(c.IsErroredOnProcessing){const m=Re(c)||"IMEI scanning failed. Please try a clearer image.";throw new E("ocr-request-failed",m)}const u=c.ParsedResults?.[0]?.ParsedText??"";if(!u.trim())throw new E("ocr-no-text","We couldn't read any text from that image. Try a clearer photo.");const s=Ne(u);
1if(!s)throw new E("ocr-no-imei","We couldn't find an IMEI in that image. Try the *#06# screen or enter it manually.");return{imei:s,rawText:u}},Le=()=>{const e=me({mutationKey:["gadget","imei-ocr"],mutationFn:t=>Oe(t),retry:!1});return{scanImage:e.mutate,scanImageAsync:e.mutateAsync,isScanning:e.isPending,isError:e.isError,error:e.error,reset:e.reset}},Be=15,F=17,ke=e=>e?Number(e).toLocaleString("en-NG"):"",ze=({onVerify:e,isLoading:t})=>{const[a,o]=C.useState(""),[l,d]=C.useState(""),[i,c]=C.useState({}),[u,s]=C.useState({type:"idle"}),m=C.useRef(null),{scanImageAsync:h,isScanning:g,reset:b}=Le();C.useEffect(()=>()=>b(),[b]);const p=x=>{c(f=>{if(!f[x])return f;const _={...f};return delete _[x],_})},I=x=>{const f=x.target.value.replace(/\D/g,"").slice(0,F);o(f),p("imei"),u.type==="success"&&s({type:"idle"})},w=x=>{d(x.target.value.replace(/\D/g,"")),p("sumInsured")},S=()=>{g||m.current?.click()},H=async x=>{const f=x.target.files?.[0];if(x.target.value="",!!f){p("imei"),s({type:"scanning",fileName:f.name});try{const{imei:_}=await h(f);o(_),s({type:"success",fileName:f.name}),D.success("IMEI detected — review and tap Verify Device.")}catch(_){const O=_ instanceof E||_ instanceof Error?_.message:"We couldn't scan that image. Please try again.";s({type:"error",fileName:f.name,message:O}),D.error(O)}}},Y=()=>{const x={};(a.length<Be||a.length>F)&&(x.imei="Please enter a valid IMEI number (15–17 digits).");const f=Number(l);if(!l||!Number.isFinite(f)||f<=0?x.sumInsured="Enter your device's value.":f<B&&(x.sumInsured=`Minimum sum insured is ₦${B.toLocaleString("en-NG")}`),Object.keys(x).length>0){c(x);return}e({imei:a,sumInsured:f})},q=t||g;return n.jsx(M,{bg:"white",borderRadius:"2xl",border:"1px solid",borderColor:r.border.primary,p:{base:6,md:8},children:n.jsxs(A,{align:"stretch",gap:6,children:[n.jsx(y,{fontWeight:"semibold",fontSize:"lg",color:r.text.primary,children:"Enter your device details"}),n.jsxs(A,{align:"stretch",gap:2,children:[n.jsx(y,{fontSize:"xs",fontWeight:"semibold",letterSpacing:"wider",color:r.text.gray,textTransform:"uppercase",children:"IMEI Number (up to 17 digits)"}),n.jsxs(v,{align:"center",gap:2,border:"1px solid",borderColor:i.imei?r.error[500]:r.border.primary,borderRadius:"lg",px:3,py:3,_focusWithin:{borderColor:r.orange[500],boxShadow:`0 0 0 1px ${r.orange[500]}`},children:[n.jsx(j,{as:V,boxSize:5,color:r.orange[500],flexShrink:0}),n.jsx(k,{value:a,onChange:I,placeholder:"e.g. 357891234567890",variant:"subtle",bg:"transparent",border:"none",outline:"none",boxShadow:"none",_focus:{border:"none",outline:"none",boxShadow:"none"},fontSize:"sm",color:r.text.primary,_placeholder:{color:r.text.gray},type:"tel",inputMode:"numeric",autoComplete:"off",disabled:g})]}),i.imei&&n.jsx(y,{fontSize:"xs",color:r.error[500],children:i.imei})]}),n.jsxs(A,{align:"stretch",gap:2,children:[n.jsx(y,{fontSize:"xs",fontWeight:"semibold",letterSpacing:"wider",color:r.text.gray,textTransform:"uppercase",children:"Device value (sum insured)"}),n.jsxs(v,{align:"center",gap:2,border:"1px solid",borderColor:i.sumInsured?r.error[500]:r.border.primary,borderRadius:"lg",px:3,py:3,_focusWithin:{borderColor:r.orange[500],boxShadow:`0 0 0 1px ${r.orange[500]}`},children:[n.jsx(j,{as:K,boxSize:5,color:r.orange[500],flexShrink:0}),n.jsx(k,{value:ke(l),onChange:w,placeholder:"Min. 100,000",variant:"subtle",bg:"transparent",border:"none",outline:"none",boxShadow:"none",_focus:{border:"none",outline:"none",boxShadow:"none"},fontSize:"sm",color:r.text.primary,_placeholder:{color:r.text.gray},type:"text",inputMode:"numeric",autoComplete:"off",disabled:g})]}),i.sumInsured&&n.jsx(y,{fontSize:"xs",color:r.error[500],children:i.sumInsured})]}),n.jsxs(v,{align:"center",gap:3,children:[n.jsx(M,{flex:1,h:"1px",bg:r.border.primary}),n.jsx(y,{fontSize:"sm",color:r.text.gray,fontWeight:"medium",children:"OR"}),n.jsx(M,{flex:1,h:"1px",bg:r.border.primary})]}),n.jsx("input",{ref:m,type:"file",accept:_e,style:{display:"none"},onChange:H,"aria-hidden":"true",tabIndex:-1}),n.jsx(Ue,{status:u,isScanning:g,onClick:S}),n.jsx(v,{justify:"flex-end",children:n.jsx(J,{buttonType:"primary",text:"Verify Device",size:"lg",type:"button",onClick:Y,loading:t,disabled:q})})]})})},Ue=({status:e,isScanning:t,onClick:a})=>{const o=We(e,t);return n.jsxs(M,{role:"button",tabIndex:0,"aria-busy":t,"aria-disabled":t,onClick:a,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),a())},border:"1.5px dashed",borderColor:o.borderColor,borderRadius:"xl",p:8,dis
1play:"flex",flexDirection:"column",alignItems:"center",gap:3,cursor:t?"wait":"pointer",bg:o.bg,...!t&&{_hover:{borderColor:o.hoverBorderColor,bg:o.hoverBg}},transition:"all 0.15s",children:[n.jsx(M,{w:10,h:10,borderRadius:"full",bg:o.iconBg,display:"flex",alignItems:"center",justifyContent:"center",children:t?n.jsx(Se,{size:"sm",color:r.orange[500],borderWidth:"2px"}):n.jsx(j,{as:o.icon,boxSize:5,color:o.iconColor})}),n.jsxs(A,{gap:1,children:[n.jsx(y,{fontWeight:"semibold",fontSize:"sm",color:o.titleColor,textAlign:"center",children:o.title}),n.jsx(y,{fontSize:"xs",color:r.text.gray,textAlign:"center",maxW:"320px",children:o.subtitle})]})]})},We=(e,t)=>t&&e.type==="scanning"?{icon:L,iconColor:r.orange[500],iconBg:r.orange[50],borderColor:r.orange[300],hoverBorderColor:r.orange[300],bg:r.orange[50],hoverBg:r.orange[50],titleColor:r.orange[700],title:"Scanning for IMEI…",subtitle:`Reading ${e.fileName} — this usually takes a few seconds.`}:e.type==="success"?{icon:X,iconColor:r.success[600],iconBg:r.success[100],borderColor:r.success[400],hoverBorderColor:r.success[400],bg:r.success[50],hoverBg:r.success[50],titleColor:r.success[700],title:"IMEI detected",subtitle:`Pulled from ${e.fileName}. Review the number above and continue, or tap to upload a different image.`}:e.type==="error"?{icon:Z,iconColor:r.error[500],iconBg:r.error[100],borderColor:r.error[400],hoverBorderColor:r.error[400],bg:r.error[50],hoverBg:r.error[50],titleColor:r.error[700],title:"Couldn't read that image",subtitle:`${e.message} Tap to try another image, or enter the IMEI above.`}:{icon:L,iconColor:r.text.label,iconBg:r.slate[100],borderColor:r.border.primary,hoverBorderColor:r.orange[300],bg:"white",hoverBg:r.orange[50],titleColor:r.text.primary,title:"Upload a screenshot of your IMEI page",subtitle:"We'll extract the IMEI automatically — JPG, PNG, or WEBP."},Ge=e=>{const t=ge(),a=Q(),{createGadgetDevicePolicy:o,isLoading:l}=de();return{isLoading:l,handleConfirm:i=>{const c=i?.deviceInfo??e;c&&o({usageType:"PERSONAL",deviceDetails:{deviceType:"PHONE",detailsSource:"MANUAL",brand:c.brand??"",model:c.model??"",imeiNumber:c.imei,...i?.sumInsured!=null?{sumInsured:i.sumInsured}:{}}},{onSuccess:u=>{const s=Me(u);if(!u.success||!s?.id){D.error(z(u)||"Could not create your gadget policy. Please try again.");return}t(ee({id:s.id,ourReference:s.ourReference,policyNumber:s.policyNumber,status:s.status,createdAt:s.createdAt})),s.gadgetDetails&&t(re(s.gadgetDetails)),a(`/${$.SelectPlan}/${s.id}`)},onError:u=>{D.error(z(u)||"Something went wrong. Please try again.")}})}}},Fe=1800,Ve="We couldn't find that device automatically. Enter the details manually to continue.",cr=()=>{const e=te(),{navigateImmediate:t}=oe(),{isAuthenticated:a,isInitialized:o}=ne(),l=ce(),{lookupImei:d,isLoading:i}=ue(),{handleConfirm:c,isLoading:u}=Ge(),{track:s}=le(),m=C.useRef(0),h=C.useRef(null);C.useEffect(()=>{s(T.SCREEN_FLOW_STARTED,{product_type:"screen",entry_point:"home_card"})},[s]),C.useEffect(()=>()=>{h.current!=null&&clearTimeout(h.current)},[]);const g=({imei:p,sumInsured:I})=>{h.current!=null&&clearTimeout(h.current),h.current=setTimeout(()=>{D.info(Ve),t(`/${$.ManualDevice}`,{state:Ae({origin:"imei",imeiNumber:p,sumInsured:String(I)})})},Fe)},b=async({imei:p,sumInsured:I})=>{if(o&&!a){e(ae({step:se.LOGIN}));return}const w=m.current+=1;s(T.SCREEN_IMEI_LOOKUP_ATTEMPTED,{product_type:"screen",imei_length:p.replace(/\s/g,"").length,attempt_number:w,input_method:"manual"});try{const S=await d(p);if(S){s(T.SCREEN_DEVICE_FOUND,{product_type:"screen",device_brand:S.brand??"unknown",device_model:S.model??"unknown",imei_suffix:ie(p)}),c({deviceInfo:S,sumInsured:I});return}s(T.SCREEN_DEVICE_NOT_FOUND,{product_type:"screen",attempt_number:w}),g({imei:p,sumInsured:I})}catch(S){if(l(S))return;s(T.SCREEN_DEVICE_NOT_FOUND,{product_type:"screen",attempt_number:w}),g({imei:p,sumInsured:I})}};return n.jsx(M,{px:{base:4,md:6,lg:8},py:{base:6,md:10},children:n.jsx(M,{maxW:"680px",mx:"auto",children:n.jsxs(A,{align:"stretch",gap:8,children:[n.jsxs(A,{align:"flex-start",gap:2,children:[n.jsxs(y,{fontSize:{base:"3xl",md:"4xl"},fontWeight:"bold",color:r.text.label,lineHeight:"1.2",children:["Let's verify your"," ",n.jsx(y,{as:"span",color:r.orange[500],children:"device first."})]}),n.jsx(y,{fontSize:"md",color:r.text.gray,maxW:"460px",children:"Enter your IMEI and device value. We'll look up the device details so you can continue with coverage."})]}),n.jsxs(v,{align:"center",gap:3,bg:r.orange[50],border:"1px solid",borderColor:r.orange[200],borderRadius:"xl",px:4,py:3,children:[n.jsx(j,{as:V,boxSize:5,color:r.orange[500],flexShrink:0}),n.jsxs(M,{children:[n.jsxs(y,{fontSize:"sm",fontWeight:"semibold",color:r.text.primary,children:["Quick tip: Dial"," ",n.jsx(y,{as:"span",color:r.orange[500],children:"*#06#"})," ","on your phone"]}),n.jsx(y,{fontSize:"xs",color:r.text.gray,mt:.5,children:"Your IMEI will appear instantly on-screen — no searching through settings menus needed."})]})]}),n.jsx(ze,{onVerify:b,isLoading:i||u})]})})})};export{cr as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.