InstantRoofIQRoof + budget planning by Inspector Roofing
Checking assessment + report service…
Inspector Roofing and Restoration
InstantRoofIQ 2.0 · Live

Know your roof's number before any salesman calls.

Watch · Real Installs, Real Proof
Video: Real Installs, Real Proof
Listen to this page · 30 sec

Know your roof's number before any salesman calls. - narrated summary of this page.

Read the transcript
Know your roof's number before any salesman calls. Get a free instant roof report — photoreal 3D view of your home, measured roof area and pitch, and a 5-page PDF. Inspector Roofing, North Me. Serving Every finding is photographed, labeled, and explained in plain language. To schedule a documented inspection, call (678) 287-7169 or visit inspector roofing dot com.

Enter one address and get a free five-page roof report — size, pitch, sections, edge lengths, and a budget range in three tiers. When evidence is strong the numbers are marked as measured; when it’s limited they’re clearly marked ESTIMATED. No phone call or login required.

Every address gets a result. Numbers backed by strong evidence are labeled as measured; anything less stays a clearly-marked planning estimate with its assumptions spelled out. Every report is for budgeting — never a survey, material order, or binding price quote.

Three honest five-page report outcomes

Outcome 1Verified measurements

Roof numbers backed by strong evidence. Anything we can’t verify stays out of the report.

Outcome 2Estimated range

Clearly marked ESTIMATED — great for budgeting, not for ordering materials.

Outcome 3Planning estimate

When evidence is limited, you still get a useful number — with every assumption labeled.

✓ Labeled 3D view of your home ✓ Size, pitch, sections & edge lengths ✓ Waste allowance included ✓ Five-page mobile PDF ✓ Focused on your home’s main roof
Private property match

Find your roof.

Start with the address — we’ll complete the match.

  1. 1Property
  2. 2Planning report

Only the address is needed — city, state, ZIP, and contact details are optional.

Get your instant report (only the address is needed)
Property address
Start typing and choose your address from the list.
Address not autofilling? Add city, state, or ZIP

By choosing Build My Roof Report, you ask InstantRoofIQ to process the submitted property address through its property-data services to create the requested planning result. This is separate from optional marketing consent.

Trees and shadows trigger automatic evidence checks. When cover is heavy, the review checks dated property context and widens the planning assumptions when evidence remains limited.

Licensed & insured · Serving Alpharetta, Roswell, Milton, Cumming, Johns Creek, Sandy Springs & nearby

Your info stays with Inspector Roofing — never sold or shared. ¿Habla español? Llame al (678) 287-7169.

No required contact fields. No automatic material order. Every valid matched property continues to a five-page planning report with measured inputs, an engine-supplied ESTIMATED range, or a broader best-available planning estimate.

Heavy obstruction detected.The review checks dated context automatically. Dated context is not hidden dimensional proof and cannot make an unsupported measurement order-ready.
See it in 3D
Keep planning with clear next steps

From instant roof budget to the right roof decision

Use the report first. Then choose the inspection, pricing, financing, or local service path that fits the property.

Instant roof quote questions

People also ask about instant roof quotes

Clear answers about the five-page report, measurements, recommended waste, ordering, and budget ranges.

How does InstantRoofIQ measure a roof?

Submitting an address starts a matched-property review. A roof value is described as an independently reviewed measurement only after the property-binding, evidence, and release checks have cleared. When they have not cleared, InstantRoofIQ still returns a clearly labeled best-available planning estimate. Residential and commercial assumptions are labeled, unsupported lineals are withheld, and a field or professional release is still required before material ordering.

How quickly can I get the report?

The property review begins after the property is confirmed. Every valid matched-property request receives a best-available planning result; internal review can refine it when stronger evidence becomes available. InstantRoofIQ does not promise a completion time. When review tracking is available, it shows only the current stage and next step.

Is InstantRoofIQ free, and will a salesman call me?

InstantRoofIQ is free. You can view the planning result without a required sales call. Inspector Roofing only uses the contact details you provide for follow-up when you choose the displayed consent option.

What happens when property evidence is limited?

InstantRoofIQ returns a broader, clearly labeled planning estimate using the best available matched-property evidence and documented assumptions. Inspector Roofing can refine that result internally before any proposal or material order. The planning result is never presented as a survey or independently reviewed measurement.

Are the roof and shingle colors exact?

No. The 3D roof and shingle colors are visual simulations for planning. Screen settings, lighting, manufacturing variation, and the actual roof surface can change appearance, so confirm a final selection with physical manufacturer samples.

'; var win=window.open("","_blank"); if(!win){setStatus("Your browser blocked the print window. Use Copy checklist instead.","warn");return;} win.document.open();win.document.write(doc);win.document.close();win.focus(); window.setTimeout(function(){try{win.print();}catch(e){}},350); setStatus("Your checklist opened in a new tab, ready to print or save as a PDF.","info"); }; var reportId=function(prefix){return (prefix||"IRV")+"-"+Date.now().toString(36).toUpperCase();}; var setStatus=function(text,mode){var el=$("irv2-status");el.textContent=text;el.className="irv2-status "+(mode||"info");el.setAttribute("aria-hidden","false");}; var REFUSAL_MESSAGES=Object.freeze({ AMBIGUOUS_BUILDING:"We found more than one roof near this address. Add the city or ZIP below so the property can be matched safely \u2014 or call (678) 287-7169 and we will verify it by drone, free.", NO_3DEP_COVERAGE:"Detailed elevation evidence is limited for this property. The report will use a broader best-available planning estimate and label its assumptions.", INSUFFICIENT_POINT_CLOUD:"Detailed roof evidence is limited for this property. The report will use a broader best-available planning estimate and label its assumptions.", PLANE_FIT_FAILED:"The available evidence did not form stable roof planes. The report will use a broader best-available planning estimate and label its assumptions.", NO_BUILDING_FOUND:"We could not safely bind the public roof data to this property, so no roof numbers were shown. Check the address or call (678) 287-7169.", ADDRESS_NOT_FOUND:"We could not bind that address to one property. Check the street, city, state, and ZIP, then try again.", NO_MEASUREMENT:"The available evidence does not support independently reviewed measurements. The report will use a broader best-available planning estimate and label its assumptions." }); var customerSafeFailure=function(error){ var rawCode=String(error&&error.code||error&&error.message||"NO_MEASUREMENT").toUpperCase().replace(/[^A-Z0-9_]/g,"_").slice(0,64); var code=Object.prototype.hasOwnProperty.call(REFUSAL_MESSAGES,rawCode)?rawCode:"NO_MEASUREMENT"; if(code==="NO_MEASUREMENT"&&/(PRIMARY_ROOF|BUILDING|STRUCTURE)/.test(rawCode))code="AMBIGUOUS_BUILDING"; if((error&&error.retryable===true)||/^HTTP_5/.test(rawCode)||["INVALID_JSON_RESPONSE","RATE_LIMITED","ENGINE_UNREACHABLE","ENGINE_INVALID","ENGINE_TIMEOUT","WORKFLOW_TIMEOUT"].indexOf(rawCode)>=0)return {code:"ENGINE_UNAVAILABLE",message:"The measurement service is temporarily unavailable. A broader best-available planning estimate will be prepared for the matched property.",retryable:true,captureAvailable:false}; return {code:code,message:REFUSAL_MESSAGES[code],retryable:false,captureAvailable:false}; }; var customerSafeWorkflowFailure=function(error){ var failure=customerSafeFailure(error); if(failure.code!=="NO_MEASUREMENT"||error&&error.retryable===true)return failure.message; return "The measurement or private report could not be completed safely. No unsupported result was shown. Please retry or call (678) 287-7169."; }; var clearRecovery=function(){ var recovery=$("irv2-recovery"); if(!recovery)return; recovery.hidden=true; recovery.removeAttribute("data-refusal-code"); $("irv2-recovery-copy").textContent="We could not safely finish this property result. Check the address or retry the request."; $("irv2-recovery-retry").hidden=true; }; var showRecovery=function(failure){ var recovery=$("irv2-recovery"); if(!recovery)return; var safe=failure&&typeof failure==="object"?failure:{code:"NO_MEASUREMENT",message:REFUSAL_MESSAGES.NO_MEASUREMENT}; $("irv2-recovery-copy").textContent=String(safe.message||REFUSAL_MESSAGES.NO_MEASUREMENT); recovery.setAttribute("data-refusal-code",String(safe.code||"NO_MEASUREMENT")); var retry=$("irv2-recovery-retry"); retry.hidden=safe.retryable!==true; retry.textContent=state.preflight?"Retry roof measurement":"Retry property check"; recovery.hidden=false; }; var setBusy=function(on){var button=$("irv2-house-use"),form=$("irv2-form"),progress=$("irv2-progress");root.setAttribute("aria-busy",on?"true":"false");if(form)form.setAttribute("aria-busy",on?"true":"false");if(button){button.disabled=on;button.setAttribute("aria-busy",on?"true":"false");button.textContent=on?"Building your 5-page report...":"Build My 5-Page Report";}var change=$("irv2-house-change");if(change)change.disabled=on;if(progress){progress.classList.toggle("active",on);progress.setAttribute("aria-hidden",on?"false":"true");}}; var setDiag=function(key,value){state.diagnostics[key]=value;var map={geo:"irv2-diag-geo",solar:"irv2-diag-solar",lines:"irv2-diag-lines"};var el=map[key]?$(map[key]):null;if(el)el.textContent=value;}; var clearPdfLink=function(){state.pdfUrl="";state.evidenceJobId="";state.evidenceTrackingToken="";state.evidenceStatus="";state.evidencePollCount=0;if(state.evidencePollTimer)window.clearTimeout(state.evidencePollTimer);state.evidencePollTimer=0;var link=$("irv2-pdf-view");var note=$("irv2-pdf-expiry");link.hidden=true;link.removeAttribute("href");link.removeAttribute("title");note.hidden=true;note.textContent="";var delivery=$("irv2-delivery");var actions=$("irv2-delivery-actions");var print=$("irv2-delivery-print");var view=$("irv2-delivery-view");var download=$("irv2-delivery-download");var track=$("irv2-evidence-track");var evidenceStatus=$("irv2-evidence-status");var viewer=$("irv2-pdf-viewer");var frame=$("irv2-pdf-frame");delivery.hidden=true;actions.hidden=true;viewer.hidden=true;print.disabled=true;view.removeAttribute("href");download.removeAttribute("href");download.removeAttribute("download");track.hidden=true;track.disabled=false;track.textContent="Check review status";evidenceStatus.hidden=true;evidenceStatus.textContent="";frame.removeAttribute("src");}; var showPdfNote=function(message){clearPdfLink();var note=$("irv2-pdf-expiry");note.textContent=message;note.hidden=false;}; var focusDelivery=function(){var delivery=$("irv2-delivery");delivery.hidden=false;var reduceMotion=window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.setTimeout(function(){delivery.scrollIntoView({behavior:reduceMotion?"auto":"smooth",block:"start"});try{delivery.focus({preventScroll:true});}catch(e){delivery.focus();}},40);}; var printPdf=function(){ if(!state.pdfUrl){setStatus("The private PDF link is not ready yet.","warn");return;} var frame=$("irv2-pdf-frame"); try{if(frame&&frame.contentWindow){frame.contentWindow.focus();frame.contentWindow.print();return;}}catch(e){} var opened=window.open(state.pdfUrl,"_blank"); if(opened){try{opened.opener=null;}catch(e){}setStatus("The PDF opened in a new tab. Choose Print from the PDF viewer.","info");} else{setStatus("Your browser blocked the print window. Use “Open PDF in a new tab” below the preview.","warn");} }; var applyPdfResponse=function(payload){ clearPdfLink(); var delivery=$("irv2-delivery"),title=$("irv2-delivery-title"),copy=$("irv2-delivery-copy"),review=$("irv2-delivery-review"),emailStatus=$("irv2-delivery-email"),deliveryNote=$("irv2-delivery-note"),actions=$("irv2-delivery-actions"),print=$("irv2-delivery-print"),view=$("irv2-delivery-view"),download=$("irv2-delivery-download"),viewer=$("irv2-pdf-viewer"),frame=$("irv2-pdf-frame"); var reviewId=payload&&typeof payload.reviewId==="string"&&/^[A-Z0-9][A-Z0-9-]{5,39}$/.test(payload.reviewId)?payload.reviewId:"Pending";review.textContent=reviewId;emailStatus.textContent=payload&&payload.acknowledgementSent===true?"Sent to you and Inspector Roofing":(payload&&payload.acknowledgementSent===false?"Inspector Roofing received it; your email was not confirmed":"Email delivery status unavailable"); if(!payload||typeof payload!=="object"){title.textContent="Your request was received";copy.textContent="Your five-page planning report is ready. If the PDF did not open, call (678) 287-7169 and we will resend it right away.";deliveryNote.textContent="Call (678) 287-7169 if you need immediate help.";focusDelivery();return false;} if(payload.reportAvailable===true&&typeof payload.downloadUrl==="string"&&typeof payload.expiresAt==="string"){ try{ var url=new URL(payload.downloadUrl,window.location.href);var expiry=new Date(payload.expiresAt);var expiryMs=expiry.getTime();var now=Date.now();var locationHost=String(window.location.hostname||"").toLowerCase();var allowedHosts=[locationHost,"inspector-roofing.com","www.inspector-roofing.com"].filter(Boolean);var loopback=locationHost==="127.0.0.1"||locationHost==="localhost"||locationHost==="::1";var transportOk=url.protocol==="https:"||(loopback&&url.protocol==="http:"&&url.host===window.location.host);var nonce=url.searchParams.get("nonce")||"";var signature=url.searchParams.get("sig")||"";var tokenExpiry=url.searchParams.get("expires")||"";var routeOk=/(?:\/wp-json\/instantroofview\/v1\/planning-report\/[A-Za-z0-9-]{6,40}\/download|\/wp-json\/inspector-roofing\/v1\/property-report\/[A-Za-z0-9-]{6,40}\/download)$/.test(url.pathname);var tokenTime=Number(tokenExpiry)*1000; if(transportOk&&allowedHosts.indexOf(url.hostname.toLowerCase())>=0&&routeOk&&/^\d{10}$/.test(tokenExpiry)&&/^[a-f0-9]{16,64}$/i.test(nonce)&&/^[a-f0-9]{64}$/i.test(signature)&&Number.isFinite(expiryMs)&&expiryMs>now&&expiryMs<=now+604800000&&Math.abs(expiryMs-tokenTime)<=1000){var link=$("irv2-pdf-view");var note=$("irv2-pdf-expiry");var readable;try{readable=expiry.toLocaleString(undefined,{dateStyle:"medium",timeStyle:"short"});}catch(e){readable=payload.expiresAt;}var planning=payload.previewPdfComplete===true||payload.planningEstimate===true;state.pdfUrl=url.toString();var downloadUrl=new URL(state.pdfUrl);downloadUrl.searchParams.set("download","1");link.href=state.pdfUrl;link.hidden=false;link.title="Private signed report link expires "+readable;note.textContent="Private signed link expires "+readable+". It opens in your browser for viewing, printing, or saving.";note.hidden=false;title.textContent=planning?"Your five-page planning PDF is ready":"Your complete roof PDF is ready";copy.textContent=planning?"Released values keep their evidence and assumption labels. Preview, print, or save the non-orderable planning report here.":"All release checks passed. Preview it here, print it, or save a copy to your device.";view.href=state.pdfUrl;download.href=downloadUrl.toString();download.setAttribute("download","InstantRoofIQ-"+reviewId+".pdf");print.disabled=false;actions.hidden=false;frame.src=state.pdfUrl;viewer.hidden=false;deliveryNote.textContent=planning?"Use this evidence-locked report for transparent budgeting; field-verify unresolved rows before scoping or ordering.":"Private signed link expires "+readable+". This PDF was released only after the complete-measurement gate passed.";focusDelivery();return true;} }catch(e){} } var oldNote=$("irv2-pdf-expiry");oldNote.hidden=false; if(payload.reportAvailable===true){title.textContent="Your roof PDF was created";copy.textContent=payload.acknowledgementSent===true?"The private PDF link was emailed, but this browser could not safely display it.":"This browser could not safely display the private PDF and customer email delivery was not confirmed.";oldNote.textContent=copy.textContent;deliveryNote.textContent="Inspector Roofing has the review. Call (678) 287-7169 if you need the PDF immediately.";focusDelivery();return false;} title.textContent="Your planning result is ready";copy.textContent="The full planning result remains visible here. Please try the private PDF link again shortly.";oldNote.textContent=copy.textContent;deliveryNote.textContent="Every visible field retains its measured, estimated, or not-measured label.";focusDelivery();return false; }; var buildRoofGeometrySummary=function(report){ var geometry=report&&report.roofGeometry;if(!geometry||typeof geometry!=="object")return null; var allowedEvidence=["measured","inferred","corroborating","presentation_only"];var evidence=String(geometry.evidenceClass||"inferred").toLowerCase();if(allowedEvidence.indexOf(evidence)<0)evidence="inferred"; var segments=(Array.isArray(geometry.lineSegments)?geometry.lineSegments:[]).slice(0,150).map(function(segment,index){ var type=String(segment&&segment.type||"").toLowerCase();var allowed=["ridge","hip","valley","eave","rake","drip_edge","wall_flashing","step_flashing","transition","parapet","unspecified","other"]; var length=finiteNumber(segment&&segment.lengthFt,0,10000);var x1=finiteNumber(segment&&segment.x1,0,1);var y1=finiteNumber(segment&&segment.y1,0,1);var x2=finiteNumber(segment&&segment.x2,0,1);var y2=finiteNumber(segment&&segment.y2,0,1); if(allowed.indexOf(type)<0||length===null||x1===null||y1===null||x2===null||y2===null)return null; var segmentEvidence=String(segment&&segment.evidenceClass||evidence).toLowerCase();if(allowedEvidence.indexOf(segmentEvidence)<0)segmentEvidence=evidence;return {id:/^[A-Za-z0-9._:-]{1,40}$/.test(String(segment.id||""))?String(segment.id):"L"+(index+1),type:type,lengthFt:Number(length.toFixed(2)),x1:x1,y1:y1,x2:x2,y2:y2,evidenceClass:segmentEvidence}; }).filter(Boolean); var facets=(Array.isArray(geometry.facets)?geometry.facets:[]).slice(0,100).map(function(facet,index){ var outline=(Array.isArray(facet&&facet.outline)?facet.outline:[]).slice(0,16).map(function(point){var x=finiteNumber(point&&point[0],0,1);var y=finiteNumber(point&&point[1],0,1);return x===null||y===null?null:[x,y];}).filter(Boolean); var pitch=finiteNumber(facet&&facet.pitch,0,IRV_LIMITS.pitchRise);var area=finiteNumber(facet&&facet.areaSqFt,0,IRV_LIMITS.surfaceAreaSqFt);var direction=String(facet&&facet.slopeDirection||"unknown").toLowerCase();if(["n","ne","e","se","s","sw","w","nw","flat","unknown"].indexOf(direction)<0)direction="unknown"; if(outline.length<3||pitch===null||area===null)return null; var facetEvidence=String(facet&&facet.evidenceClass||evidence).toLowerCase();if(allowedEvidence.indexOf(facetEvidence)<0)facetEvidence=evidence;return {id:/^[A-Za-z0-9._:-]{1,40}$/.test(String(facet.id||""))?String(facet.id):"F"+(index+1),pitch:Number(pitch.toFixed(1)),areaSqFt:Number(area.toFixed(1)),slopeDirection:direction,outline:outline,evidenceClass:facetEvidence,notes:facetEvidence==="measured"?"Verified measured facet.":"Confidence-labeled planning facet."}; }).filter(Boolean); if(!segments.length&&!facets.length)return null; var flags=(Array.isArray(geometry.reviewFlags)?geometry.reviewFlags:[]).slice(0,20).map(function(flag,index){var severity=String(flag&&flag.severity||"yellow").toLowerCase();if(severity!=="red")severity="yellow";var code=String(flag&&flag.code||("REVIEW_"+(index+1))).replace(/[^A-Za-z0-9._:-]/g,"_").slice(0,40);var message=String(flag&&flag.message||"Field verification required.").replace(/\s+/g," ").trim().slice(0,220);return {severity:severity,code:code||("REVIEW_"+(index+1)),message:message||"Field verification required."};}); return {evidenceClass:evidence,sourceLabel:evidence==="measured"?"Verified measured roof topology":"Address-bound calculated roof topology",lineSegments:segments,facets:facets,penetrations:[],reviewFlags:flags,fieldVerification:evidence==="measured"?[]:["Confirm every roof edge and hidden junction before ordering materials.","Verify pitch changes and one physical scale anchor in the field."]}; }; var normalizeReleaseGate=function(raw){ if(!raw||typeof raw!=="object")return null; var allowedCodes=["IDENTITY","IMAGERY_RECENCY","AREA","PITCH","TOPOLOGY","LINEALS","FIELD_OR_PROVIDER_EVIDENCE"]; var checks=(Array.isArray(raw.checks)?raw.checks:[]).slice(0,allowedCodes.length).map(function(check){var code=String(check&&check.code||"").toUpperCase();if(allowedCodes.indexOf(code)<0)return null;var passed=check.passed===true&&String(check.status||"").toUpperCase()==="PASS";return {code:code,passed:passed,status:passed?"PASS":"BLOCKED"};}).filter(Boolean); var blockers=(Array.isArray(raw.blockers)?raw.blockers:[]).map(function(code){return String(code||"").toUpperCase();}).filter(function(code,index,list){return allowedCodes.indexOf(code)>=0&&list.indexOf(code)===index;}); var required=finiteNumber(raw.requiredCheckCount,1,allowedCodes.length);var passed=finiteNumber(raw.passedCheckCount,0,allowedCodes.length);required=required===null?allowedCodes.length:Math.round(required);passed=passed===null?checks.filter(function(check){return check.passed;}).length:Math.round(passed); var checkCodes=checks.map(function(check){return check.code;});var hasEveryUniqueCheck=allowedCodes.every(function(code){return checkCodes.filter(function(candidate){return candidate===code;}).length===1;});var internallyOrderReady=String(raw.status||"").toUpperCase()==="ORDER_READY"&&raw.orderReady===true&&raw.materialOrderingAllowed===true&&String(raw.pdfClassification||"").toUpperCase()==="VERIFIED_ORDER_TAKEOFF"&&required===allowedCodes.length&&passed===required&&checks.length===required&&hasEveryUniqueCheck&&checks.every(function(check){return check.passed;})&&blockers.length===0; return {status:internallyOrderReady?"ORDER_READY":"NOT_ORDER_READY",orderReady:internallyOrderReady,materialOrderingAllowed:internallyOrderReady,pdfClassification:internallyOrderReady?"VERIFIED_ORDER_TAKEOFF":"PRELIMINARY_REVIEW_ONLY",requiredCheckCount:required,passedCheckCount:passed,blockers:internallyOrderReady?[]:blockers,checks:checks}; }; var customerPdfCompleteness=function(report){ var blockers=[];if(!report||typeof report!=="object"||report.demo===true)return {ready:false,blockers:["MEASUREMENT_RESULT"]}; var gate=normalizeReleaseGate(report.releaseGate);if(!gate||gate.orderReady!==true||gate.materialOrderingAllowed!==true||gate.pdfClassification!=="VERIFIED_ORDER_TAKEOFF")blockers.push("SIGNED_ORDER_RELEASE"); if(report.structureMatchReliable!==true)blockers.push("PROPERTY_IDENTITY"); var evidence=String(report.evidence||"").toLowerCase();var measurementEvidence=String(report.measurementEvidence||"").toLowerCase();if(["professional_report","field_verified"].indexOf(evidence)<0||measurementEvidence!=="measured")blockers.push("TRUSTED_MEASURED_EVIDENCE"); var area=finiteNumber(report.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),pitch=finiteNumber(report.pitchRise,0,IRV_LIMITS.pitchRise),facets=finiteNumber(report.facets,1,IRV_LIMITS.facets),squares=finiteNumber(report.squares,2.5,IRV_LIMITS.netSquares);if(area===null)blockers.push("ROOF_AREA");if(pitch===null)blockers.push("PITCH");if(facets===null||Math.floor(facets)!==facets)blockers.push("FACETS");if(squares===null||area===null||Math.abs(squares-Number((area/100).toFixed(4)))>.0001)blockers.push("SQUARES_IDENTITY"); var geometry=report.roofGeometry&&typeof report.roofGeometry==="object"?report.roofGeometry:null;var geometryFacets=geometry&&Array.isArray(geometry.facets)?geometry.facets:[];var segments=geometry&&Array.isArray(geometry.lineSegments)?geometry.lineSegments:[];if(!geometry||String(geometry.evidenceClass||"").toLowerCase()!=="measured"||!geometryFacets.length||!segments.length)blockers.push("MEASURED_ROOF_GEOMETRY");else{if(geometryFacets.length!==facets)blockers.push("COMPLETE_FACET_REGISTER");if(geometryFacets.some(function(item){return String(item&&item.evidenceClass||geometry.evidenceClass).toLowerCase()!=="measured";}))blockers.push("MEASURED_FACETS");var professionalSegments=evidence==="professional_report";if(segments.some(function(item){var itemEvidence=String(item&&item.evidenceClass||geometry.evidenceClass).toLowerCase();return itemEvidence!=="measured"&&!(professionalSegments&&itemEvidence==="corroborating");}))blockers.push("MEASURED_LINE_GEOMETRY");if((Array.isArray(geometry.reviewFlags)?geometry.reviewFlags:[]).some(function(item){return String(item&&item.severity||"").toLowerCase()==="red";}))blockers.push("UNRESOLVED_RED_FLAG");} var lines=report.lines&&typeof report.lines==="object"?report.lines:{};var verified=report.lineVerified&&typeof report.lineVerified==="object"?report.lineVerified:{};var required=["ridges","hips","valleys","rakes","eaves","stepFlashing","parapets"];required.forEach(function(key){if(finiteNumber(lines[key],0,100000)===null||verified[key]!==true)blockers.push("LINEAL_"+key.toUpperCase());}); var wallKey=Object.prototype.hasOwnProperty.call(lines,"wallFlashing")?"wallFlashing":"flashing";if(finiteNumber(lines[wallKey],0,100000)===null||verified[wallKey]!==true)blockers.push("LINEAL_WALLFLASHING");var eaves=finiteNumber(lines.eaves,0,100000),rakes=finiteNumber(lines.rakes,0,100000),drip=finiteNumber(lines.dripEdge,0,100000);if(eaves===null||rakes===null||drip===null||Math.abs(drip-Number((eaves+rakes).toFixed(1)))>.01)blockers.push("LINEAL_DRIPEDGE_IDENTITY"); if(typeof report.measurementToken!=="string"||!/^[A-Za-z0-9._~-]{40,60000}$/.test(report.measurementToken))blockers.push("SERVER_MEASUREMENT_TOKEN"); return {ready:blockers.length===0,blockers:blockers.filter(function(value,index,list){return list.indexOf(value)===index;})}; }; var allowsHistoricalPreliminaryMetrics=function(context){ var safety=context&&context.safety||{};var temporal=context&&context.temporal||{};var gate=context&&context.releaseGate;var warnings=(Array.isArray(safety.warnings)?safety.warnings:[]).map(function(value){return String(value||"").toUpperCase();});var allowedWarnings=["IMAGERY_TOO_OLD_UNKNOWN","COVERAGE_REVIEW_REQUIRED","MEASURED_OVERRIDE_REQUIRED_REVIEW"]; var criticalChecks=gate&&Array.isArray(gate.checks)?gate.checks.filter(function(check){return ["IDENTITY","AREA","PITCH"].indexOf(check.code)>=0;}):[];var criticalPassed=["IDENTITY","AREA","PITCH"].every(function(code){return criticalChecks.some(function(check){return check.code===code&&check.passed===true;});});var criticalBlocked=gate&&gate.blockers.some(function(code){return ["IDENTITY","AREA","PITCH"].indexOf(code)>=0;});var coverageStatus=String(context&&context.coverageStatus||"UNKNOWN").toUpperCase(); return safety.preliminaryAreaAllowed===false&&safety.requiresMeasuredOverride===true&&safety.humanReviewRequired===true&&safety.severeCoverageFailSafe!==true&&safety.materialOrderingAllowed!==true&&String(safety.pdfClassification||"PRELIMINARY_REVIEW_ONLY").toUpperCase()==="PRELIMINARY_REVIEW_ONLY"&&String(temporal.status||"").toUpperCase()==="UNKNOWN"&&String(temporal.ageBand||"").toUpperCase()==="OLDER_THAN_60_MONTHS"&&temporal.preliminaryAreaAllowed===false&&temporal.currentIndependentEvidenceAccepted!==true&&warnings.indexOf("IMAGERY_TOO_OLD_UNKNOWN")>=0&&warnings.indexOf("MEASURED_OVERRIDE_REQUIRED_REVIEW")>=0&&warnings.every(function(code){return allowedWarnings.indexOf(code)>=0;})&&["CLEAR","REVIEW","ELEVATED"].indexOf(coverageStatus)>=0&&context.structureMatchReliable===true&&context.geometryComplete===true&&Number.isFinite(context.consensusSpreadPct)&&context.consensusSpreadPct<=5&&String(context.quality||"").toUpperCase()==="HIGH"&&gate&&gate.status==="NOT_ORDER_READY"&&gate.orderReady===false&&gate.materialOrderingAllowed===false&&gate.pdfClassification==="PRELIMINARY_REVIEW_ONLY"&&gate.blockers.indexOf("IMAGERY_RECENCY")>=0&&criticalPassed&&!criticalBlocked; }; var normalizePresentation=function(raw){ var asset=raw&&raw.primaryAsset;if(!asset||asset.kind!=="ADDRESS_BOUND_GOOGLE_SATELLITE_2D")return null; var center=asset.center||{};var lat=finiteNumber(center.lat!==undefined?center.lat:center.latitude,-90,90);var lng=finiteNumber(center.lng!==undefined?center.lng:center.longitude,-180,180);var binding=asset.binding&&typeof asset.binding==="object"?asset.binding:{};var candidateId=String(binding.selectedCandidateId||"");var measurementId=String(binding.measurementId||"").toUpperCase(); if(lat===null||lng===null||!/^IRV-S-[A-Z0-9]+$/.test(candidateId)||!/^IRV-[A-Z0-9-]{3,36}$/.test(measurementId))return null; return {primaryAsset:{kind:"ADDRESS_BOUND_GOOGLE_SATELLITE_2D",enabled:asset.enabled===true,availabilityStatus:String(asset.availabilityStatus||"UNKNOWN").slice(0,80),center:{lat:lat,lng:lng},binding:{measurementId:measurementId,selectedCandidateId:candidateId,addressBinding:String(binding.addressBinding||"").slice(0,80)},evidenceRole:"PRESENTATION_ONLY_NOT_DIMENSIONAL_EVIDENCE"}}; }; var getJson=async function(url,timeout){if(LEAD_CONFIG.preview)throw new Error("Network is disabled in offline preview mode.");var controller=new AbortController();var timer=setTimeout(function(){controller.abort();},timeout||10000);try{var response=await fetch(url,{method:"GET",signal:controller.signal,headers:{Accept:"application/json"},cache:"no-store"});var payload=await response.json().catch(function(){return null;});if(!response.ok||!payload)throw new Error("Presentation service unavailable");return payload;}finally{clearTimeout(timer);}}; var renderAppReadiness=function(payload){ var status=$("irv2-appstatus"); if(!status)return; var checks=payload&&payload.checks&&typeof payload.checks==="object"?payload.checks:{}; var engineAssertion=checks.measurementGateway&&checks.measurementGateway.engineAssertion;var valid=payload&&payload.schema==="instantroofview/public-readiness-v1"&&typeof payload.release==="string"&&checks.publicApp&&checks.publicApp.ready===true&&checks.coverage&&checks.coverage.ready===null&&checks.measurementGateway&&typeof checks.measurementGateway.ready==="boolean"&&checks.measurementGateway.externalProviderUptime===null&&engineAssertion&&engineAssertion.required===false&&checks.planningReportService&&typeof checks.planningReportService.ready==="boolean"; state.runtimeReadiness=valid?payload:null; state.runtimeReady=valid&&(payload.status==="READY"||payload.status==="DEGRADED")&&checks.measurementGateway.ready===true&&checks.planningReportService.ready===true; status.classList.remove("checking","degraded"); var startButton=$("irv2-address-next"); if(state.runtimeReady){ if(startButton)startButton.disabled=false; status.textContent=payload.status==="READY"?"Assessment intake + report delivery ready · each property is checked separately":"Core assessment app ready · optional follow-up unavailable"; return; } status.classList.add("degraded"); if(startButton)startButton.disabled=true; status.textContent=valid?"Assessment or report route unavailable · property checks paused":"App loaded · service check unavailable"; showRecovery({code:"ENGINE_UNAVAILABLE",message:"The property review service is not ready. Retry the service check or call (678) 287-7169.",retryable:true,captureAvailable:false}); }; var loadAppReadiness=async function(){ if(LEAD_CONFIG.preview){ var previewStatus=$("irv2-appstatus"); if(previewStatus){previewStatus.classList.remove("checking");previewStatus.classList.add("degraded");previewStatus.textContent="Offline preview · services not checked";} return; } var status=$("irv2-appstatus"); if(status){status.classList.add("checking");status.textContent="Checking app + measurement + PDF service…";} var startButton=$("irv2-address-next"); if(startButton)startButton.disabled=true; try{renderAppReadiness(await getJson(API.readiness,7000));} catch(error){renderAppReadiness(null);} }; loadAppReadiness(); var normalizePresentationConfig=function(raw){var asset=raw&&raw.primaryAsset||{};var security=raw&&raw.security||{};var maps2d=raw&&raw.maps2d||{};var endpoint=String(asset.endpoint||"");var key=String(raw&&raw.browserKey||"");var enabled=raw&&raw.schema==="instant-roof-view/presentation-v2"&&asset.kind==="ADDRESS_BOUND_GOOGLE_SATELLITE_2D"&&asset.renderer==="maps-embed-api"&&asset.mapType==="satellite"&&asset.addressBindingRequired===true&&asset.serverIssuedCandidateRequired===true&&asset.evidenceRole==="PRESENTATION_ONLY_NOT_DIMENSIONAL_EVIDENCE"&&asset.enabled===true&&maps2d.enabled===true&&maps2d.role==="PRIMARY_PROPERTY_CONFIRMATION"&&security.browserKeyPurpose==="PUBLIC_BROWSER_RENDERING_ONLY"&&security.httpReferrerRestrictionRequired===true&&security.httpReferrerRestrictionAttested===true&&security.serverMeasurementKeyExposed===false&&endpoint==="https://www.google.com/maps/embed/v1/view"&&key.length>=10&&key.length<=300;return {enabled:enabled,availabilityStatus:String(asset.availabilityStatus||"UNAVAILABLE").slice(0,80),endpoint:endpoint,mapType:"satellite",zoom:20,browserKey:enabled?key:""};}; var loadPresentationConfig=async function(){if(LEAD_CONFIG.preview)return null;if(state.presentationConfig)return state.presentationConfig;if(state.presentationPromise)return state.presentationPromise;state.presentationPromise=getJson(API.presentation,10000).then(function(raw){return normalizePresentationConfig(raw);}).catch(function(){return {enabled:false,availabilityStatus:"UNAVAILABLE",endpoint:"",mapType:"satellite",zoom:20,browserKey:""};}).then(function(config){state.presentationConfig=config;state.presentationPromise=null;return config;});return state.presentationPromise;}; var officeExampleSatelliteUrl=function(report){if(LEAD_CONFIG.preview)return "";var address=String(report&&report.matchedAddress||OFFICE_EXAMPLE.matchedAddress);var config=state.presentationConfig;if(config&&config.enabled===true){try{var endpoint=new URL(config.endpoint);endpoint.pathname=endpoint.pathname.replace(/\/view$/,"/place");endpoint.search=new URLSearchParams({key:config.browserKey,q:address,zoom:String(config.zoom),maptype:"satellite"}).toString();return endpoint.toString();}catch(error){}} return ""; }; var satelliteMapUrl=function(point,candidateId,measurementPresentation,expectedMeasurementId){var config=state.presentationConfig;if(!config||config.enabled!==true||!point||!/^IRV-S-[A-Z0-9]+$/.test(String(candidateId||"")))return "";var center={lat:finiteNumber(point.lat,-90,90),lng:finiteNumber(point.lng,-180,180)};if(center.lat===null||center.lng===null)return "";if(measurementPresentation){var normalized=normalizePresentation(measurementPresentation);if(!normalized||normalized.primaryAsset.enabled!==true||normalized.primaryAsset.binding.selectedCandidateId!==candidateId||String(normalized.primaryAsset.binding.measurementId)!==String(expectedMeasurementId||"").toUpperCase())return "";if(state.preflight&&state.preflight.candidateId&&state.preflight.candidateId!==candidateId)return "";center=normalized.primaryAsset.center;}var params=new URLSearchParams({key:config.browserKey,center:center.lat.toFixed(7)+","+center.lng.toFixed(7),zoom:String(config.zoom),maptype:"satellite"});return config.endpoint+"?"+params.toString();}; var SURFACE_ALIGNMENT_PROFILE={id:"irv-surface-alignment-20260720",areaFactor:1.05,scope:"inferred_planning_only"}; var applySurfaceAlignment=function(report){ if(!report||report.demo===true||report.imported===true)return report; // Address-bound roof3d values are already measured surface values. The // legacy planning alignment factor is only valid for inferred inputs; // applying it to measured engine output would double-adjust the area. if(report.measurementEvidence==="measured"||report.measurementEvidence==="estimated")return report; var gate=normalizeReleaseGate(report.releaseGate);var verified=gate&&gate.orderReady===true&&gate.materialOrderingAllowed===true&&String(gate.pdfClassification||"").toUpperCase()==="VERIFIED_ORDER_TAKEOFF"; if(verified)return report; var area=finiteNumber(report.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);if(area===null)return report; var adjusted=Number(clamp(area*SURFACE_ALIGNMENT_PROFILE.areaFactor,250,IRV_LIMITS.surfaceAreaSqFt).toFixed(2)); report.rawUnalignedAreaSqFt=Number(area.toFixed(2));report.areaSqFt=adjusted;report.canonicalAreaSqFt=adjusted;report.squares=Number((adjusted/100).toFixed(4));report.surfaceAlignmentProfile=SURFACE_ALIGNMENT_PROFILE.id;report.areaAlignmentFactor=SURFACE_ALIGNMENT_PROFILE.areaFactor;report.measurementFormulaVersion=MEASUREMENT_FORMULA_VERSION;return report; }; var buildMeasurementSummary=function(report){ var completeness=customerPdfCompleteness(report);if(!completeness.ready)return null; var matched=String(report.matchedAddress||report.address||"").trim();var area=finiteNumber(report.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);var pitch=finiteNumber(report.pitchRise,0,IRV_LIMITS.pitchRise);var facets=finiteNumber(report.facets,1,IRV_LIMITS.facets); if(!matched||matched.length>220||area===null||pitch===null||facets===null||Math.floor(facets)!==facets)return null; var reportGate=normalizeReleaseGate(report.releaseGate);var evidence=String(report.evidence).toLowerCase();area=Number(area.toFixed(2));var geometry=buildRoofGeometrySummary(report);if(!geometry||geometry.evidenceClass!=="measured")return null;var summary={matchedAddress:matched,areaSqFt:area,squares:Number((area/100).toFixed(4)),pitch:wholePitchLabel(pitch),facets:facets,measurementStructureMatch:"matched",measurementEvidence:"measured",metricEvidence:{areaSqFt:"measured",squares:"measured",pitch:"measured",facets:"measured"},evidence:evidence,obstructionKnown:Number.isFinite(report.obstructionPercent),satelliteImageRequired:true}; var id=String(report.reportId||"").toUpperCase();if(/^[A-Z0-9][A-Z0-9-]{5,39}$/.test(id))summary.reviewId=id; var imageDate=String(report.imageryDate||"");if(/^\d{4}-\d{2}-\d{2}$/.test(imageDate)&&Date.parse(imageDate+"T00:00:00Z")<=Date.now()+86400000)summary.imageDate=imageDate; var imageQuality=String(report.imageryQuality||"").toLowerCase();if(["high","medium","low","unknown","imported"].indexOf(imageQuality)>=0)summary.imageQuality=imageQuality; if(summary.obstructionKnown)summary.obstructionPercent=Math.round(clamp(number(report.obstructionPercent),0,100)*10)/10; var lines=report.lines;var wallKey=Object.prototype.hasOwnProperty.call(lines,"wallFlashing")?"wallFlashing":"flashing";var mapped={};[["ridges","ridges"],["hips","hips"],["valleys","valleys"],["rakes","rakes"],["eaves","eaves"],["dripEdge","dripEdge"],[wallKey,"wallFlashing"],["stepFlashing","stepFlashing"],["parapets","parapets"]].forEach(function(pair){mapped[pair[1]]=Number(finiteNumber(lines[pair[0]],0,100000).toFixed(1));});summary.linealBasis=evidence==="professional_report"?"professional_report":"field_verified";summary.lineals=mapped; summary.roofGeometry=geometry;summary.orderRelease={status:reportGate.status,orderReady:true,materialOrderingAllowed:true,pdfClassification:"VERIFIED_ORDER_TAKEOFF",requiredCheckCount:reportGate.requiredCheckCount,passedCheckCount:reportGate.passedCheckCount,blockers:[],checks:reportGate.checks.slice(0,7)};summary.measurementToken=report.measurementToken; return summary; }; var renderMeasuredBridge=function(report){ var bridge=$("irv2-measured-bridge");if(!bridge)return; bridge.classList.remove("active");bridge.hidden=true; var staleEmbed=document.getElementById("irv2-3d-embed");if(staleEmbed)staleEmbed.remove(); if(!report)return; $("irv2-measured-title").textContent="Explore the 3D roof color showroom"; $("irv2-measured-copy").textContent="This is a representative demo roof. Your five-page planning report is the source for your property’s evidence and measurements."; var el3=$("irv2-3d-link");el3.href="/3d-showroom/"; var fr3=document.getElementById("irv2-3d-embed"); if(!fr3){fr3=document.createElement("iframe");fr3.id="irv2-3d-embed";fr3.loading="lazy";fr3.setAttribute("title","3D roof color showroom demo");fr3.style.cssText="display:block;width:100%;max-width:860px;height:"+(innerWidth<760?"420":"540")+"px;margin:10px auto 4px;border:1px solid #d7e0e8;border-radius:14px";el3.parentNode.insertBefore(fr3,el3);} fr3.src="/3d-showroom/?embed=1"; el3.textContent="↗ Open full screen — 52 colors and demo measurements"; bridge.hidden=false;bridge.classList.add("active"); }; var postJson=async function(url,data,timeout){ if(LEAD_CONFIG.preview)throw new Error("Network is disabled in offline preview mode."); var routeAlias=url===API.measure?"roof_measure":((url===API.planningPreview||url===API.verifiedPreview)?"planning_pdf":(url===API.structures?"structures":(url===LEAD_CONFIG.endpoint?"roof_lead":"known_api"))); var startedAt=window.performance&&typeof window.performance.now==="function"?window.performance.now():Date.now(); var effectiveTimeout=timeout||12000; if(state.workflowDeadlineMs>0){ var remaining=state.workflowDeadlineMs-Date.now(); if(remaining<=0){var missedAt=window.performance&&typeof window.performance.now==="function"?window.performance.now():Date.now();recordRuntimeEvidence(routeAlias,"timeout",missedAt-startedAt,408,true,0);var deadlineError=new Error("WORKFLOW_TIMEOUT");deadlineError.code="WORKFLOW_TIMEOUT";deadlineError.retryable=true;deadlineError.status=408;throw deadlineError;} effectiveTimeout=Math.min(effectiveTimeout,remaining); } var controller=new AbortController(); var timer=setTimeout(function(){controller.abort();},effectiveTimeout); var responseStatus=0;var responseBytes=0;var evidenceWritten=false; try{ var headers={Accept:"application/json","Content-Type":"application/json"}; if(String(url||"").charAt(0)==="/"&&/^irv-[a-f0-9]{24}$/.test(state.workflowRequestId))headers["X-IRV-Request-ID"]=state.workflowRequestId; var response=await fetch(url,{method:"POST",signal:controller.signal,cache:"no-store",referrerPolicy:"no-referrer",headers:headers,body:JSON.stringify(data||{})}); var text=await response.text(); responseStatus=response.status;responseBytes=text.length; var payload; try{payload=JSON.parse(text);}catch(e){payload=null;} if(!response.ok){ var envelope=payload&&payload.error&&typeof payload.error==="object"?payload.error:{}; var requestError=new Error(String(envelope.message||response.status+" "+response.statusText)); requestError.code=String(envelope.code||payload&&payload.code||"HTTP_"+response.status); requestError.status=response.status; requestError.retryable=envelope.retryable===true||response.status===408||response.status===429||response.status>=500; requestError.details=envelope.details&&typeof envelope.details==="object"?envelope.details:null; throw requestError; } if(!payload){ var parseError=new Error("Measurement engine returned non-JSON data"); parseError.code="INVALID_JSON_RESPONSE"; parseError.status=response.status; parseError.retryable=true; throw parseError; } var completedAt=window.performance&&typeof window.performance.now==="function"?window.performance.now():Date.now(); var outcomeClass=String(payload&&payload.status||"").toUpperCase()==="NO_MEASUREMENT"?"refused":"success"; recordRuntimeEvidence(routeAlias,outcomeClass,completedAt-startedAt,responseStatus,false,responseBytes);evidenceWritten=true; return payload; }catch(error){ if(error&&error.name==="AbortError"){ error.code=state.workflowDeadlineMs>0&&Date.now()>=state.workflowDeadlineMs?"WORKFLOW_TIMEOUT":"CLIENT_TIMEOUT"; error.retryable=true; error.status=408; } if(!evidenceWritten){ var failedAt=window.performance&&typeof window.performance.now==="function"?window.performance.now():Date.now(); recordRuntimeEvidence(routeAlias,error&&(error.code==="CLIENT_TIMEOUT"||error.code==="WORKFLOW_TIMEOUT")?"timeout":"failure",failedAt-startedAt,error&&error.status||responseStatus,error&&error.retryable===true,responseBytes); } throw error; }finally{clearTimeout(timer);} }; var normalizeHistoricalContext=function(raw){ if(!raw||raw.schema!=="instant-roof-view/historical-imagery-context-v1"||raw.currentGoogleSatellitePreserved!==true||raw.affectsMeasurement!==false||raw.affectsConfidence!==false)return null; var trigger=raw.trigger&&typeof raw.trigger==="object"?raw.trigger:{};var obstruction=finiteNumber(trigger.obstructionPercent,0,100);if(trigger.automatic!==true||trigger.thresholdPercent!==HISTORICAL_IMAGERY_TRIGGER_PERCENT||trigger.homeownerInputUsed!==false)return null; var status=String(raw.status||"").toUpperCase();var normalized={status:status,obstructionPercent:obstruction,triggered:obstruction!==null&&obstruction>=HISTORICAL_IMAGERY_TRIGGER_PERCENT,attribution:String(raw.attribution||"Authorized dated property context").slice(0,180),fallback:String(raw.fallback||"").slice(0,100),selected:null}; if(status!=="BEST_AVAILABLE_HISTORICAL_CONTEXT_SELECTED")return normalized; var selected=raw.selected&&typeof raw.selected==="object"?raw.selected:{};var presentation=selected.presentation&&typeof selected.presentation==="object"?selected.presentation:{};var tiles=(Array.isArray(presentation.tiles)?presentation.tiles:[]).map(function(tile){try{var url=new URL(String(tile&&tile.url||""));var host=url.hostname.toLowerCase();if(url.protocol!=="https:"||!(host==="arcgis.com"||host.endsWith(".arcgis.com"))||url.username||url.password||!/\/tile\//.test(url.pathname))return null;var rowOffset=Number(tile.rowOffset),columnOffset=Number(tile.columnOffset);if(!Number.isInteger(rowOffset)||!Number.isInteger(columnOffset)||Math.abs(rowOffset)>1||Math.abs(columnOffset)>1)return null;return {url:url.toString(),rowOffset:rowOffset,columnOffset:columnOffset};}catch(error){return null;}}).filter(Boolean); if(tiles.length!==9||new Set(tiles.map(function(tile){return tile.rowOffset+":"+tile.columnOffset;})).size!==9)return null; var acquisitionDate=String(selected.acquisitionDate||"");if(!/^20\d{2}-\d{2}-\d{2}$/.test(acquisitionDate))return null; normalized.selected={acquisitionDate:acquisitionDate,releaseDate:String(selected.releaseDate||"").slice(0,20),provider:"Authorized property context",source:"Dated property context",resolutionMeters:finiteNumber(selected.resolutionMeters,0,1000),accuracyMeters:finiteNumber(selected.accuracyMeters,0,10000),leafOff:selected.leafOff===true,pixelVisibilityStatus:String(selected.pixelVisibilityStatus||"NOT_PIXEL_CERTIFIED"),tiles:tiles.sort(function(a,b){return a.rowOffset-b.rowOffset||a.columnOffset-b.columnOffset;})};return normalized; }; var findHistoricalImagery=async function(){return {status:"INTERNAL_REVIEW_AVAILABLE",obstructionPercent:null,triggered:true,attribution:"Internal evidence review",fallback:"PLANNING_ASSUMPTIONS_RETAINED",selected:null};}; var renderHistoricalContext=function(report){ var view=$("irv2-history-view"),grid=$("irv2-history-grid"),meta=$("irv2-history-meta"),note=$("irv2-history-note"),alert=$("irv2-treealert");if(!view||!grid)return;view.hidden=true;grid.replaceChildren();alert.classList.remove("active");var context=normalizeHistoricalContext(report&&report.historicalImagery);var obstruction=finiteNumber(report&&report.obstructionPercent,0,100);var triggered=(context&&context.triggered===true)||(obstruction!==null&&obstruction>=HISTORICAL_IMAGERY_TRIGGER_PERCENT);if(!triggered)return; alert.classList.add("active");$("irv2-treealert-title").textContent="Limited visible roof evidence.";$("irv2-treealert-copy").textContent="The app keeps the best-available planning values labeled and routes stronger-evidence review internally. No browser request for historical imagery is made."; }; var clearStructureSelection=function(){state.chosenStructure=null;}; var validStructureBindingToken=function(token){ return typeof token==="string"&&token.length<=1024&&/^[A-Za-z0-9_-]{80,768}\.[A-Za-z0-9_-]{43}$/.test(token); }; var findStructures=async function(address){ try{ var result=await postJson(API.structures,{address:address},15000);var payload=result&&(result.data||result.result||result);var rawCandidates=payload&&Array.isArray(payload.candidates)?payload.candidates:[]; var normalizedCandidates=rawCandidates.slice(0,12).map(function(candidate){var candidateId=String(candidate&&candidate.candidateId||"");if(!/^IRV-S-[A-Z0-9]+$/.test(candidateId))return null;var center=candidate&&candidate.center||{};var lat=finiteNumber(center.lat!==undefined?center.lat:center.latitude,-90,90);var lng=finiteNumber(center.lng!==undefined?center.lng:center.longitude,-180,180);var bindingToken=String(candidate&&candidate.structureBindingToken||"");if(lat===null||lng===null||!validStructureBindingToken(bindingToken))return null;var suggestedRole=String(candidate.suggestedRole||"").toUpperCase();var footprint=finiteNumber(candidate.groundFootprintSquareFeet,1,IRV_LIMITS.planAreaSqFt);var profile=planningProfileForStructure(candidate,footprint);return {candidateId:candidateId,center:{lat:lat,lng:lng},suggestedRole:suggestedRole==="MAIN_STRUCTURE_CANDIDATE"?suggestedRole:"OTHER_BUILDING_CANDIDATE",containsAddressPoint:candidate.containsAddressPoint===true,groundFootprintSquareFeet:footprint,planningProfile:profile.id,planningProfileBasis:profile.basis,structureBindingToken:bindingToken};}); var serverPrimary=normalizedCandidates[0];if(!serverPrimary||serverPrimary.suggestedRole!=="MAIN_STRUCTURE_CANDIDATE"||serverPrimary.containsAddressPoint!==true)throw new Error("The property service did not return a safe primary-roof binding.");var candidates=normalizedCandidates.filter(Boolean); var selectionRequired=payload&&payload.selectionRequired===true||candidates.length>1;if(selectionRequired&&!candidates.length)throw new Error("Primary-roof binding was required, but no safe candidate identifier was returned."); var matchedAddress=String(payload&&payload.matchedAddress||address).slice(0,240);var bindingAddress=String(payload&&payload.structureBindingAddress||matchedAddress).slice(0,240); if(bindingAddress.trim().length<8)throw new Error("The property structure binding address was not usable."); return {selectionRequired:selectionRequired,candidates:candidates,matchedAddress:matchedAddress,structureBindingAddress:bindingAddress}; }catch(e){if(e&&e.retryable===true)throw e;var associationError=new Error("AMBIGUOUS_BUILDING");associationError.code="AMBIGUOUS_BUILDING";throw associationError;} }; var structureAnchorPoint=function(result,address){ var candidates=result&&Array.isArray(result.candidates)?result.candidates:[]; var anchor=candidates.filter(function(candidate){return candidate.containsAddressPoint===true;})[0]||candidates.filter(function(candidate){return candidate.suggestedRole==="MAIN_STRUCTURE_CANDIDATE";})[0]||candidates[0]; if(!anchor||!anchor.center||finiteNumber(anchor.center.lat,-90,90)===null||finiteNumber(anchor.center.lng,-180,180)===null){var error=new Error("ADDRESS_NOT_FOUND");error.code="ADDRESS_NOT_FOUND";throw error;} return {lat:anchor.center.lat,lng:anchor.center.lng,address:String(result.matchedAddress||address).slice(0,240)}; }; var scoreStructureCandidate=function(candidate,addressPoint){ var pointDistance=addressPoint&&candidate&&candidate.center?distanceMeters(addressPoint,candidate.center):null;var candidateDistance=Number.isFinite(pointDistance)?pointDistance:null; var score=0,reasons=[]; if(candidate&&candidate.containsAddressPoint===true){score+=46;reasons.push("address point inside candidate");} if(candidate&&candidate.suggestedRole==="MAIN_STRUCTURE_CANDIDATE"){score+=34;reasons.push("server primary-structure signal");} if(candidateDistance!==null){var distanceScore=Math.round((1-clamp(candidateDistance/90,0,1))*20);score+=distanceScore;if(candidateDistance<=18)reasons.push("near resolved address");} var footprint=finiteNumber(candidate&&candidate.groundFootprintSquareFeet,1,IRV_LIMITS.planAreaSqFt);if(footprint!==null){var footprintScore=Math.round(clamp((Math.log(footprint)-Math.log(350))/(Math.log(5200)-Math.log(350)),0,1)*12);score+=footprintScore;} return Object.assign({},candidate,{selectionScore:score,selectionDistanceMeters:candidateDistance,selectionReason:reasons.length?reasons.join(" + "):"best available address-bound candidate"}); }; var selectPrimaryStructureForAddress=function(result,preferredCandidateId,addressPoint){ var candidates=result&&Array.isArray(result.candidates)?result.candidates:[]; var refuse=function(){var error=new Error("AMBIGUOUS_BUILDING");error.code="AMBIGUOUS_BUILDING";error.retryable=false;error.captureAvailable=false;throw error;}; if(!candidates.length)refuse(); var preferred=String(preferredCandidateId||""); var primary=scoreStructureCandidate(candidates[0],addressPoint); if(primary.suggestedRole!=="MAIN_STRUCTURE_CANDIDATE"||primary.containsAddressPoint!==true||!/^IRV-S-[A-Z0-9]+$/.test(primary.candidateId)||!primary.center||finiteNumber(primary.selectionDistanceMeters,0,45)===null)refuse(); if(preferred&&primary.candidateId!==preferred)refuse(); var rankedOthers=candidates.slice(1).map(function(candidate){return scoreStructureCandidate(candidate,addressPoint);}).sort(function(left,right){return right.selectionScore-left.selectionScore;}); var runner=rankedOthers[0]||null; var margin=runner?primary.selectionScore-runner.selectionScore:12; var confidence=clamp(Math.round(38+primary.selectionScore*.48+Math.max(0,Math.min(16,margin))*1.5),35,96); primary.selectionEngine=STRUCTURE_SELECTION_ENGINE.id;primary.selectionLocked=preferred!=="";primary.selectionMargin=margin;primary.selectionConfidence=confidence; state.chosenStructure=primary;return primary; }; var findMeasure=async function(candidate,address){ var requestBody={address:address}; if(candidate&&/^IRV-S-[A-Z0-9]+$/.test(String(candidate.candidateId||""))&&candidate.center&&validStructureBindingToken(candidate.structureBindingToken)){ requestBody.candidateId=candidate.candidateId; requestBody.lat=finiteNumber(candidate.center.lat,-90,90); requestBody.lon=finiteNumber(candidate.center.lng,-180,180); requestBody.structureBindingToken=candidate.structureBindingToken; }else{ var bindingError=new Error("AMBIGUOUS_BUILDING");bindingError.code="AMBIGUOUS_BUILDING";bindingError.retryable=false;bindingError.captureAvailable=false;throw bindingError; } var result=await postJson(API.measure,requestBody,100000); var status=String(result&&result.status||"").toUpperCase(); if(status==="NO_MEASUREMENT"){ setDiag("solar","Planning assumptions applied"); var publicError=result&&result.error&&typeof result.error==="object"?result.error:{}; var noMeasurement=new Error("NO_MEASUREMENT"); noMeasurement.code=String(publicError.code||result&&result.code||"NO_MEASUREMENT"); noMeasurement.retryable=publicError.retryable===true; noMeasurement.captureAvailable=false; throw noMeasurement; } if(status!=="MEASURED"&&status!=="ESTIMATED"){ var unavailableMeasurement=new Error("NO_MEASUREMENT");unavailableMeasurement.code="NO_MEASUREMENT";throw unavailableMeasurement; } var returnedCandidate=String(result&&result.selectedCandidateId||result&&result.candidateId||result&&result.quality&&result.quality.selectedCandidateId||""); if(returnedCandidate&&candidate&&returnedCandidate!==candidate.candidateId){var candidateMismatch=new Error("AMBIGUOUS_BUILDING");candidateMismatch.code="AMBIGUOUS_BUILDING";throw candidateMismatch;} var measuredLat=finiteNumber(result&&result.lat,-90,90),measuredLng=finiteNumber(result&&result.lng,-180,180); if(measuredLat!==null&&measuredLng!==null&&candidate&&candidate.center&&distanceMeters({lat:measuredLat,lng:measuredLng},candidate.center)>45){var centerMismatch=new Error("AMBIGUOUS_BUILDING");centerMismatch.code="AMBIGUOUS_BUILDING";throw centerMismatch;} var associationVerified=!!(returnedCandidate&&candidate&&returnedCandidate===candidate.candidateId&&measuredLat!==null&&measuredLng!==null&&candidate.center&&distanceMeters({lat:measuredLat,lng:measuredLng},candidate.center)<=45); if(!associationVerified){var associationError=new Error("AMBIGUOUS_BUILDING");associationError.code="AMBIGUOUS_BUILDING";associationError.captureAvailable=false;throw associationError;} var area=finiteNumber(result&&result.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),pitch=finiteNumber(result&&result.pitchRise,0,IRV_LIMITS.pitchRise),facets=finiteNumber(result&&result.facets,1,IRV_LIMITS.facets); var areaRange=numericRange(result&&result.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(result&&result.squaresRange,2.5,IRV_LIMITS.netSquares,4); var pointEstimate=area!==null&&pitch!==null&&facets!==null&&Math.floor(facets)===facets; var footprintRange=status==="ESTIMATED"&&areaRange!==null&&squaresRange!==null&&result&&result.areaSqFt==null&&result.pitchRise==null&&result.facets==null; if((status==="MEASURED"&&!pointEstimate)||(status==="ESTIMATED"&&!pointEstimate&&!footprintRange)){ setDiag("solar","Planning assumptions applied"); var unavailableEstimate=new Error("NO_MEASUREMENT");unavailableEstimate.code="NO_MEASUREMENT";throw unavailableEstimate; } setDiag("solar",status==="MEASURED"?"Assessment measurement available":(footprintRange?"Estimated 2D range":"Estimated record")); return {payload:result,envelope:result,associationVerified:associationVerified,source:String(result.source||"Property assessment result")}; }; var findTopology=async function(){return null;}; var providerObstructionPercent=function(provider){var payload=provider&&provider.payload||{};var roof=payload.roof||{};var direct=finiteNumber(roof.unassignedGroundGapPercent,0,100);if(direct===null)direct=finiteNumber(roof.obstructionPercent,0,100);return direct;}; var isoDate=function(o){if(!o)return "Unknown";if(typeof o==="string")return o;var y=o.year||"";var m=o.month?String(o.month).padStart(2,"0"):"";var d=o.day?String(o.day).padStart(2,"0"):"";return [y,m,d].filter(Boolean).join("-")||"Unknown";}; var pitchLabel=function(deg){var rise=Math.tan(number(deg)*Math.PI/180)*12;var rounded=wholePitchRise(rise);return {rise:rounded,label:wholePitchLabel(rounded),degrees:number(deg)};}; var bearing=function(deg){var dirs=["N","NE","E","SE","S","SW","W","NW"];return dirs[Math.round(((number(deg)%360)+360)%360/45)%8];}; var uprightGeometry=function(facets,segments){ var candidates=segments.filter(function(segment){return segment.type==="ridge"||segment.type==="eave";});if(!candidates.length)candidates=segments.slice();var anchor=null,anchorSpan=0;candidates.forEach(function(segment){var span=Math.hypot(segment.x2-segment.x1,segment.y2-segment.y1);if(span>anchorSpan){anchor=segment;anchorSpan=span;}});if(!anchor||anchorSpan<.0001)return {facets:facets,segments:segments}; var points=[];facets.forEach(function(facet){(facet.outline||[]).forEach(function(point){points.push(point);});});segments.forEach(function(segment){points.push([segment.x1,segment.y1],[segment.x2,segment.y2]);});if(points.length<2)return {facets:facets,segments:segments};var cx=points.reduce(function(sum,point){return sum+point[0];},0)/points.length,cy=points.reduce(function(sum,point){return sum+point[1];},0)/points.length,angle=Math.atan2(anchor.y2-anchor.y1,anchor.x2-anchor.x1),cosine=Math.cos(angle),sine=Math.sin(angle);var rotate=function(point){var dx=point[0]-cx,dy=point[1]-cy;return [dx*cosine+dy*sine,-dx*sine+dy*cosine];};var rotated=points.map(rotate),minX=Math.min.apply(null,rotated.map(function(point){return point[0];})),maxX=Math.max.apply(null,rotated.map(function(point){return point[0];})),minY=Math.min.apply(null,rotated.map(function(point){return point[1];})),maxY=Math.max.apply(null,rotated.map(function(point){return point[1];})),width=maxX-minX,height=maxY-minY;if(width<.0001||height<.0001)return {facets:facets,segments:segments};var scale=Math.min(.84/width,.78/height),centerX=(minX+maxX)/2,centerY=(minY+maxY)/2,transform=function(point){var next=rotate(point);return [.5+(next[0]-centerX)*scale,.5+(next[1]-centerY)*scale];};return {facets:facets.map(function(facet){var copy=Object.assign({},facet);copy.outline=facet.outline.map(transform);return copy;}),segments:segments.map(function(segment){var copy=Object.assign({},segment),start=transform([segment.x1,segment.y1]),end=transform([segment.x2,segment.y2]);copy.x1=start[0];copy.y1=start[1];copy.x2=end[0];copy.y2=end[1];return copy;})}; }; var normalizeTopology=function(raw,expectedCandidate){ if(!raw||typeof raw!=="object")return null;var status=String(raw.status||raw.releaseStatus||"").toUpperCase();if(/UNAVAILABLE|FAILED|UNKNOWN|REJECTED/.test(status))return null; var drawing=raw.drawing&&typeof raw.drawing==="object"?raw.drawing:raw;var rawSegments=Array.isArray(drawing.lineSegments)?drawing.lineSegments:(Array.isArray(drawing.segments)?drawing.segments:(Array.isArray(drawing.edges)?drawing.edges:[]));var rawFacets=Array.isArray(drawing.facets)?drawing.facets:[]; var coordinate=function(value,axis){if(Array.isArray(value))return finiteNumber(value[axis==="x"?0:1],0,1);if(!value||typeof value!=="object")return null;return finiteNumber(value[axis]!==undefined?value[axis]:(value[axis+"Norm"]!==undefined?value[axis+"Norm"]:value[axis==="x"?"normalizedX":"normalizedY"]),0,1);}; var segments=rawSegments.slice(0,150).map(function(segment,index){var type=String(segment&&segment.type||segment&&segment.kind||"").toLowerCase().replace(/s$/,""),start=segment&&segment.start||segment&&segment.from,end=segment&&segment.end||segment&&segment.to;var x1=finiteNumber(segment&&segment.x1,0,1),y1=finiteNumber(segment&&segment.y1,0,1),x2=finiteNumber(segment&&segment.x2,0,1),y2=finiteNumber(segment&&segment.y2,0,1);if(x1===null)x1=coordinate(start,"x");if(y1===null)y1=coordinate(start,"y");if(x2===null)x2=coordinate(end,"x");if(y2===null)y2=coordinate(end,"y");var length=finiteNumber(segment&&segment.lengthFt!==undefined?segment.lengthFt:(number(segment&&segment.lengthMeters)>0?number(segment.lengthMeters)*3.280839895:null),0,10000);if(["ridge","hip","valley","eave","rake","other"].indexOf(type)<0||x1===null||y1===null||x2===null||y2===null||length===null)return null;return {id:/^[A-Za-z0-9._:-]{1,40}$/.test(String(segment.id||""))?String(segment.id):"L"+(index+1),type:type,lengthFt:length,x1:x1,y1:y1,x2:x2,y2:y2,evidenceClass:"inferred"};}).filter(Boolean); var facets=rawFacets.slice(0,100).map(function(facet,index){var outlineRaw=Array.isArray(facet&&facet.outline)?facet.outline:(Array.isArray(facet&&facet.polygon)?facet.polygon:[]);var outline=outlineRaw.slice(0,16).map(function(point){var x=coordinate(point,"x"),y=coordinate(point,"y");return x===null||y===null?null:[x,y];}).filter(Boolean);var pitchSource=null;if(facet&&facet.pitch!==undefined)pitchSource=facet.pitch;else if(facet&&facet.pitchRise!==undefined)pitchSource=facet.pitchRise;else{var pitchDegrees=finiteNumber(facet&&facet.pitchDegrees,0,89);if(pitchDegrees!==null)pitchSource=pitchLabel(pitchDegrees).rise;}var pitch=finiteNumber(pitchSource,0,24);var areaSource=facet&&facet.areaSqFt!==undefined?facet.areaSqFt:(facet&&facet.surfaceAreaSquareFeet!==undefined?facet.surfaceAreaSquareFeet:(facet&&facet.areaMeters2!==undefined?number(facet.areaMeters2)*M2_TO_SF:(facet&&facet.surfaceAreaMeters2!==undefined?number(facet.surfaceAreaMeters2)*M2_TO_SF:null)));var area=finiteNumber(areaSource,0,100000);if(outline.length<3||pitch===null||area===null)return null;var azimuth=finiteNumber(facet&&facet.azimuthDegrees,0,360);var direction=String(facet&&facet.slopeDirection||(azimuth===null?"unknown":bearing(azimuth))).toLowerCase();if(["n","ne","e","se","s","sw","w","nw","flat","unknown"].indexOf(direction)<0)direction="unknown";return {id:/^[A-Za-z0-9._:-]{1,40}$/.test(String(facet.id||""))?String(facet.id):"F"+(index+1),pitch:pitch,areaSqFt:area,slopeDirection:direction,outline:outline,evidenceClass:"inferred"};}).filter(Boolean); if(!segments.length||!facets.length)return null;var presentation=uprightGeometry(facets,segments);facets=presentation.facets;segments=presentation.segments;var aggregate=raw.modelLineals&&typeof raw.modelLineals==="object"?raw.modelLineals:(raw.lineals&&typeof raw.lineals==="object"?raw.lineals:{});var names={ridge:"ridges",hip:"hips",valley:"valleys",rake:"rakes",eave:"eaves"};var lines={ridges:0,hips:0,valleys:0,rakes:0,eaves:0};segments.forEach(function(segment){if(names[segment.type])lines[names[segment.type]]+=segment.lengthFt;});Object.keys(lines).forEach(function(key){var singular=key.replace(/s$/,"");var entry=aggregate[key]!==undefined?aggregate[key]:aggregate[singular];var direct=entry&&typeof entry==="object"?finiteNumber(entry.canonical3dFeet!==undefined?entry.canonical3dFeet:(entry.lengthFt!==undefined?entry.lengthFt:entry.feet),0,100000):finiteNumber(entry!==undefined?entry:aggregate[key+"Ft"],0,100000);if(direct!==null)lines[key]=direct;lines[key]=Number(lines[key].toFixed(1));});var dripEntry=aggregate.dripEdge!==undefined?aggregate.dripEdge:aggregate.drip_edge;var dripComparison=dripEntry&&typeof dripEntry==="object"?finiteNumber(dripEntry.canonical3dFeet!==undefined?dripEntry.canonical3dFeet:(dripEntry.lengthFt!==undefined?dripEntry.lengthFt:dripEntry.feet),0,100000):finiteNumber(dripEntry,0,100000);lines.dripEdge=Number((lines.eaves+lines.rakes).toFixed(1));var dripConflict=dripComparison!==null&&Math.abs(dripComparison-lines.dripEdge)>.2;var lineModeled={};Object.keys(lines).forEach(function(key){lineModeled[key]=true;});var facetDisplaySum=Number(facets.reduce(function(total,facet){return total+facet.areaSqFt;},0).toFixed(2));var areaBlock=raw.area&&typeof raw.area==="object"?raw.area:{};var canonicalAreaSqFt=finiteNumber(areaBlock.canonicalSurfaceSquareFeet,0,100000);if(canonicalAreaSqFt===null)canonicalAreaSqFt=facetDisplaySum;canonicalAreaSqFt=Number(canonicalAreaSqFt.toFixed(2));var displayTolerance=Math.max(.1,facets.length*.011);if(Math.abs(canonicalAreaSqFt-facetDisplaySum)>displayTolerance)return null;var canonicalSquares=finiteNumber(areaBlock.canonicalSquares,0,1000);if(canonicalSquares===null)canonicalSquares=canonicalAreaSqFt/100;if(Math.abs(canonicalSquares*100-canonicalAreaSqFt)>.02)return null;canonicalSquares=Number(canonicalSquares.toFixed(4));var providerAreaSqFt=finiteNumber(areaBlock.providerReportedSurfaceSquareFeet,0,100000);if(providerAreaSqFt===null)providerAreaSqFt=finiteNumber(areaBlock.providerSurfaceSquareFeet,0,100000);if(providerAreaSqFt===null){var providerAreaMeters2=finiteNumber(areaBlock.providerReportedSurfaceMeters2!==undefined?areaBlock.providerReportedSurfaceMeters2:areaBlock.providerSurfaceMeters2,0,10000);if(providerAreaMeters2!==null)providerAreaSqFt=providerAreaMeters2*M2_TO_SF;}var warningCodes=raw.safety&&Array.isArray(raw.safety.warnings)?raw.safety.warnings:[];var flags=warningCodes.slice(0,8).map(function(code){return {severity:"yellow",code:String(code).replace(/[^A-Za-z0-9._:-]/g,"_").slice(0,40),message:"Calculated roof geometry requires human and field verification."};});if(dripConflict)flags.push({severity:"yellow",code:"MODEL_PERIMETER_SOURCE_DIFFERENCE",message:"A supplied drip-edge comparison differed from the canonical eaves-plus-rakes model perimeter."}); var releaseGate=normalizeReleaseGate(raw.releaseGate);var presentationContract=normalizePresentation(raw.presentation);var property=raw.property&&typeof raw.property==="object"?raw.property:{};var propertyMeasurementId=String(property.measurementId||"").toUpperCase();var propertyCandidateId=String(property.selectedCandidateId||"");var propertyCenterRaw=property.center||{};var propertyCenter={lat:finiteNumber(propertyCenterRaw.lat!==undefined?propertyCenterRaw.lat:propertyCenterRaw.latitude,-90,90),lng:finiteNumber(propertyCenterRaw.lng!==undefined?propertyCenterRaw.lng:propertyCenterRaw.longitude,-180,180)};var expectedCandidateId=String(expectedCandidate&&expectedCandidate.candidateId||"");var validation=raw.validation&&typeof raw.validation==="object"?raw.validation:{};var fullTakeoff=validation.fullTakeoffCompleteness&&typeof validation.fullTakeoffCompleteness==="object"?validation.fullTakeoffCompleteness:{};var euler=validation.euler&&typeof validation.euler==="object"?validation.euler:{};var graphClosed=fullTakeoff.computedEdgeGraphClosed===true||euler.characteristic===2;var modelReady=raw.modelLinealsAvailable===true&&raw.modelLinealsComplete===true&&graphClosed; if(String(raw.status||"").toUpperCase()!=="INFERRED_PRELIMINARY"||!modelReady||!/^IRV-[A-Z0-9-]{3,36}$/.test(propertyMeasurementId)||!/^IRV-S-[A-Z0-9]+$/.test(propertyCandidateId)||propertyCenter.lat===null||propertyCenter.lng===null||(/^IRV-S-[A-Z0-9]+$/.test(expectedCandidateId)&&propertyCandidateId!==expectedCandidateId))return null;if(presentationContract&&(presentationContract.primaryAsset.binding.measurementId!==propertyMeasurementId||presentationContract.primaryAsset.binding.selectedCandidateId!==propertyCandidateId||distanceMeters(propertyCenter,presentationContract.primaryAsset.center)>2))return null; return {roofGeometry:{evidenceClass:"inferred",sourceLabel:"InstantRoofIQ inferred 3D plane-intersection roof geometry",lineSegments:segments,facets:facets,reviewFlags:flags},lines:lines,lineModeled:lineModeled,lineAvailable:{},complete:false,canonicalAreaSqFt:canonicalAreaSqFt,canonicalSquares:canonicalSquares,facetDisplaySumSqFt:facetDisplaySum,providerAreaSqFt:providerAreaSqFt,basis:"Address-bound 3D plane intersections + closed footprint graph · auto-upright 2D",measurementId:propertyMeasurementId,selectedCandidateId:propertyCandidateId,propertyCenter:propertyCenter,presentation:presentationContract,releaseGate:releaseGate||planningGate(),bindingComplete:!!presentationContract}; }; var parseRoofMeasure=function(provider,address,point){ var payload=provider&&provider.payload||{}; var status=String(payload.status||"").toUpperCase(); var isMeasured=status==="MEASURED",isEstimated=status==="ESTIMATED"; var refuse=function(code){var error=new Error("NO_MEASUREMENT");error.code=code||"NO_MEASUREMENT";error.captureAvailable=false;throw error;}; if(!isMeasured&&!isEstimated)refuse(); if(!provider||provider.associationVerified!==true){var associationError=new Error("AMBIGUOUS_BUILDING");associationError.code="AMBIGUOUS_BUILDING";associationError.retryable=false;associationError.captureAvailable=false;throw associationError;} if(payload.schema!=="instant-roof-view/roof3d-measurement-v1"||payload.planningEstimate!==true||payload.materialOrderingAllowed!==false)refuse("INVALID_MEASUREMENT_CONTRACT"); if(String(payload.measurementEvidence||"").toLowerCase()!==(isMeasured?"measured":"estimated"))refuse("INVALID_MEASUREMENT_EVIDENCE"); if(!/^IRV-[A-Z0-9-]{8,60}$/.test(String(payload.measurementId||""))||!/^[a-f0-9]{64}$/.test(String(payload.cacheKey||"")))refuse("INVALID_MEASUREMENT_ID"); var quality=payload.quality&&typeof payload.quality==="object"?payload.quality:{}; var anchorBasis=String(quality.anchorBasis||payload.anchorBasis||""); if(["address_point_rooftop","census_interpolated","caller_coordinates"].indexOf(anchorBasis)<0)refuse("ANCHOR_UNVERIFIED"); var centerLat=finiteNumber(payload.lat,-90,90),centerLng=finiteNumber(payload.lng,-180,180); if(centerLat===null||centerLng===null)refuse("COORDINATES_INVALID"); var mode=String(payload.measurementMode||""); var measuredModes=["roof3d_usgs_3dep_class6_ransac","roof3d_usgs_3dep_batch_grade"]; var sourceLinealBasis=String(payload.linealBasis||""),facetsBasis=String(payload.facetsBasis||""); var base={ status:status,source:provider.source,address:address,matchedAddress:payload.matchedAddress||payload.address||address, lat:centerLat,lng:centerLng,reportId:payload.measurementId,measurementToken:payload.measurementToken||"",measurementReceipt:/^[a-f0-9]{64}$/.test(String(payload.measurementReceipt||"").toLowerCase())?String(payload.measurementReceipt).toLowerCase():"", measurementMode:mode,measurementTier:String(payload.measurementTier||""),cacheKey:payload.cacheKey, planningEstimate:true,materialOrderingAllowed:false,anchorBasis:anchorBasis, measurementStructureMatch:String(payload.measurementStructureMatch||""),facetsBasis:facetsBasis, planningReason:String(payload.planningReason||""),sourceLinealBasis:sourceLinealBasis, lines:null,lineModeled:{},lineAvailable:{},lineVerified:{},linealBasis:"not_supplied", linealValidation:{modelId:"none",trainingSample:0,crossValidationFolds:0,metric:"not_validated",cvWapePct:null,interpretation:"formula_lineals_withheld",sealedHoldoutPassed:false}, roofGeometry:null,releaseGate:planningGate(),obstructionPercent:null,obstructionKnown:false, quality:{anchorBasis:anchorBasis,declineReason:String(quality.declineReason||"")} }; if(isMeasured){ var area=finiteNumber(payload.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),pitch=wholePitchRise(payload.pitchRise),facets=finiteNumber(payload.facets,1,IRV_LIMITS.facets),strictTierOne=mode==="roof3d_usgs_3dep_class6_ransac"&&sourceLinealBasis==="roof3d_3dep_pointcloud_wiring",allowedLinealBasis=["roof3d_3dep_pointcloud_wiring","calibrated_formula_required"]; if(measuredModes.indexOf(mode)<0||area===null||pitch===null||facets===null||Math.floor(facets)!==facets||area/facets<10||allowedLinealBasis.indexOf(sourceLinealBasis)<0||(!strictTierOne&&sourceLinealBasis!=="calibrated_formula_required")||(!strictTierOne&&!/^[A-Za-z0-9_:-]{3,80}$/.test(facetsBasis)))refuse("INVALID_MEASURED_RESULT"); var strictLines=null,strictVerified={},strictAvailable={};if(strictTierOne){var rawLineals=payload.lineals&&typeof payload.lineals==="object"?payload.lineals:{};strictLines={};["ridges","hips","valleys","rakes","eaves","dripEdge","flashing","wallFlashing","stepFlashing","parapets"].forEach(function(key){var aliases=key==="flashing"?["flashing","wallFlashing"]:(key==="wallFlashing"?["wallFlashing","flashing"]:[key]);var value=null;aliases.some(function(alias){value=finiteNumber(rawLineals[alias],0,100000);return value!==null;});strictLines[key]=value===null?null:Number(value.toFixed(1));strictVerified[key]=value!==null;strictAvailable[key]=value!==null;});} return Object.assign(base,{ areaSqFt:Number(area.toFixed(2)),canonicalAreaSqFt:Number(area.toFixed(2)),rawWholeAreaSqFt:Number(area.toFixed(2)),squares:Number((area/100).toFixed(4)), facets:Math.round(facets),pitchRise:pitch,pitchDegrees:null,planes:[],imageryQuality:"MEASURED",imageryDate:"Address-bound assessment evidence", lines:strictLines,lineVerified:strictVerified,lineAvailable:strictAvailable,linealBasis:strictTierOne?"roof3d_3dep_pointcloud_wiring":"not_supplied",measurementEvidence:"measured",metricEvidence:{areaSqFt:"measured",squares:"measured",pitch:"measured",facets:"measured"},evidence:"address_imagery",structureMatchReliable:true, topologyBasis:"Address-bound assessment area, pitch, and facets; lineals were not supplied",sourceEvidence:"measured" }); } var declineReason=String(quality.declineReason||"").toUpperCase().replace(/[^A-Z0-9_]/g,"_"); if(!/^[A-Z0-9_]{3,80}$/.test(declineReason)||sourceLinealBasis!=="calibrated_formula_required")refuse("INVALID_ESTIMATE_PROVENANCE"); if(mode==="ga_batch_2018_precomputed"){ var batchArea=finiteNumber(payload.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),batchPitch=wholePitchRise(payload.pitchRise),batchFacets=finiteNumber(payload.facets,1,IRV_LIMITS.facets); if(batchArea===null||batchPitch===null||batchFacets===null||Math.floor(batchFacets)!==batchFacets||!/^[A-Za-z0-9_:-]{3,80}$/.test(facetsBasis))refuse("INVALID_ESTIMATED_RESULT"); return Object.assign(base,{ areaSqFt:Number(batchArea.toFixed(2)),canonicalAreaSqFt:Number(batchArea.toFixed(2)),rawWholeAreaSqFt:Number(batchArea.toFixed(2)),squares:Number((batchArea/100).toFixed(4)), facets:Math.round(batchFacets),pitchRise:batchPitch,pitchDegrees:null,planes:[],imageryQuality:"ESTIMATED",imageryDate:"2018–2020 batch dataset", measurementEvidence:"estimated",metricEvidence:{areaSqFt:"estimated",squares:"estimated",pitch:"estimated",facets:"estimated"},evidence:"batch_dataset",structureMatchReliable:false, topologyBasis:"Estimated batch-address record; roof-edge lineals were not supplied",sourceEvidence:"estimated",fallbackReasonCode:declineReason }); } if(mode==="footprint_2d_range"){ var areaRange=numericRange(payload.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(payload.squaresRange,2.5,IRV_LIMITS.netSquares,4); if(payload.areaSqFt!=null||payload.pitchRise!=null||payload.facets!=null||areaRange===null||squaresRange===null)refuse("INVALID_2D_RANGE"); return Object.assign(base,{ areaSqFt:null,canonicalAreaSqFt:null,rawWholeAreaSqFt:null,squares:null,facets:null,pitchRise:null,pitchDegrees:null,planes:[],imageryQuality:"ESTIMATED",imageryDate:"Current 2D footprint context", measurementEvidence:"estimated",metricEvidence:{areaSqFt:"estimated_range",squares:"estimated_range",pitch:"not_measured",facets:"not_measured"},evidence:"address_imagery",structureMatchReliable:false, topologyBasis:"Measured 2D footprint with an estimated roof-area range; pitch, facets, and lineals were not measured",sourceEvidence:"estimated",fallback2D:true,captureRequired:false,internalEvidenceReview:true, areaSqFtRange:areaRange,squaresRange:squaresRange,pitchRiseRange:null,facetsRange:null,propertyBindingStatus:"server_bound_candidate_unconfirmed",unresolvedDimensions:["exact_pitch","facet_topology","roof_edge_lineals","material_order_quantity"],fallbackReasonCode:declineReason }); } refuse("UNSUPPORTED_ESTIMATE_MODE"); }; var parseSolar=function(provider,address,point){ var payload=provider.payload||{};var envelope=provider.envelope||{};var roof=payload.roof||{};var image=payload.image||{};var safety=payload.safety||{};var center=payload.center||point;var segments=Array.isArray(roof.planes)?roof.planes:[]; var diagnosticObjects=[envelope.diagnostics,envelope.measurementDiagnostics,payload.diagnostics,payload.measurementDiagnostics,roof.diagnostics].filter(function(v){return v&&typeof v==="object";}); diagnosticObjects.slice().forEach(function(d){if(d.coverage&&typeof d.coverage==="object")diagnosticObjects.push(d.coverage);if(d.areaEvidence&&typeof d.areaEvidence==="object")diagnosticObjects.push(d.areaEvidence);if(d.geometry&&typeof d.geometry==="object")diagnosticObjects.push(d.geometry);if(d.imagery&&typeof d.imagery==="object")diagnosticObjects.push(d.imagery);}); var validPlaneInputs=segments.map(function(s,index){var areaMeters2=finiteNumber(s&&s.areaMeters2,0,10000);var pitchDegrees=finiteNumber(s&&s.pitchDegrees,0,89);if(areaMeters2===null||areaMeters2<=0||pitchDegrees===null)return null;return {source:s,index:index,areaMeters2:areaMeters2,pitchDegrees:pitchDegrees,groundAreaMeters2:finiteNumber(s&&s.groundAreaMeters2,0,10000)};}).filter(Boolean); var wholeArea=finiteNumber(roof.surfaceAreaMeters2,0,10000);var wholeGround=finiteNumber(roof.groundAreaMeters2,0,10000);var buildingGround=finiteNumber(roof.buildingGroundAreaMeters2,0,10000); if(!wholeArea&&validPlaneInputs.length)wholeArea=validPlaneInputs.reduce(function(t,s){return t+s.areaMeters2;},0); if(!wholeArea)throw new Error("The building match returned no usable roof surface area."); if(!validPlaneInputs.length)throw new Error("We built your planning report from the best available address data; pitch here is an estimate. A quick on-site look confirms it exactly."); var planeArea=validPlaneInputs.reduce(function(t,s){return t+s.areaMeters2;},0);var projectedArea=validPlaneInputs.reduce(function(t,s){var ground=s.groundAreaMeters2;var radians=s.pitchDegrees*Math.PI/180;var cosine=Math.cos(radians);return t+(ground!==null&&ground>0&&cosine>.08?ground/cosine:0);},0); var rawCandidates=[wholeArea,planeArea,projectedArea].filter(function(v){return v>0;});var rawConsensus=median(rawCandidates);var surfaceCandidates=[planeArea,projectedArea].filter(function(v){return v>0;});var surfaceConsensus=median(surfaceCandidates);var areaFusion={value:planeArea>0?planeArea:(projectedArea>0?projectedArea:wholeArea),agreementPct:null,basis:planeArea>0?"direct roof-plane surface":"roof surface fallback"};if(planeArea>0&&projectedArea>0){var pairMean=(planeArea+projectedArea)/2;var pairSpread=pairMean>0?Math.abs(planeArea-projectedArea)/pairMean*100:100;areaFusion.agreementPct=pairSpread;if(pairSpread<=4){areaFusion.value=planeArea*.75+projectedArea*.25;areaFusion.basis="roof-plane surface with pitch-ground corroboration";}else if(pairSpread<=10){areaFusion.value=planeArea*.90+projectedArea*.10;areaFusion.basis="roof-plane surface with bounded pitch-ground corroboration";}else{areaFusion.value=planeArea;areaFusion.basis="direct roof-plane surface; pitch-ground cross-check diverged";}}var selectedAreaMeters2=areaFusion.value;var areaSqFt=selectedAreaMeters2*M2_TO_SF;var minArea=Math.min.apply(null,rawCandidates);var maxArea=Math.max.apply(null,rawCandidates);var consensusSpreadPct=rawConsensus>0?(maxArea-minArea)/rawConsensus*100:100; var gatewaySpread=diagnosticNumber(diagnosticObjects,["spreadPercent","consensusSpreadPct","areaSpreadPct","calculationSpreadPct"],0,200);if(gatewaySpread!==null)consensusSpreadPct=gatewaySpread; var gatewayCoverageStatus=String(roof.obstructionStatus||diagnosticText(diagnosticObjects,["status","obstructionStatus","coverageStatus"])||"UNKNOWN").toUpperCase(); if(gatewayCoverageStatus==="SEVERE"||gatewayCoverageStatus==="INCONSISTENT")throw new Error("Tree cover or shadows hid part of this roof, so this is a two-dimensional planning estimate from the best available imagery. An on-site measurement gets you exact numbers."); if(areaSqFt<250||areaSqFt>100000)throw new Error("The roof area did not pass the building-size safety check."); var planeRows=validPlaneInputs.map(function(item){var s=item.source;return {index:finiteNumber(s.index,1,1000)||item.index+1,areaSqFt:item.areaMeters2*M2_TO_SF,pitchDegrees:item.pitchDegrees,azimuthDegrees:finiteNumber(s.azimuthDegrees,0,360),heightMeters:finiteNumber(s.heightMeters,-100,10000)};}).filter(function(p){return p.areaSqFt>5;}); if(!planeRows.length)throw new Error("The available roof planes were too small to support a defensible pitch calculation."); var pitchBins={};planeRows.forEach(function(p){var label=pitchLabel(p.pitchDegrees);var key=String(label.rise);pitchBins[key]=(pitchBins[key]||0)+p.areaSqFt;});var dominantRise=0;Object.keys(pitchBins).forEach(function(key){if(!pitchBins[String(dominantRise)]||pitchBins[key]>pitchBins[String(dominantRise)])dominantRise=number(key);});var predominant={rise:dominantRise,degrees:Math.atan(dominantRise/12)*180/Math.PI};var quality=image.quality||"UNKNOWN"; var hasCoverageSignal=buildingGround>0&&wholeGround>0;var assignedCoverage=hasCoverageSignal?clamp(wholeGround/buildingGround,0,1):null;var obstructionPercent=assignedCoverage===null?null:(1-assignedCoverage)*100;var obstructionStatus=gatewayCoverageStatus.toLowerCase();var gatewayObstruction=finiteNumber(roof.unassignedGroundGapPercent,0,100);if(gatewayObstruction===null)gatewayObstruction=diagnosticNumber(diagnosticObjects,["unassignedGroundGapPercent","obstructionPercent","unassignedCoveragePercent","unassignedFootprintPct"],0,100);if(gatewayObstruction!==null)obstructionPercent=gatewayObstruction;if(!hasCoverageSignal&&gatewayObstruction===null&&/(unknown|unavailable|not available|not_available)/.test(obstructionStatus))obstructionPercent=null; var rawAreaSqFt=wholeArea*M2_TO_SF;var areaEvidenceSource=areaFusion.basis;var matchDistance=distanceMeters(point,{lat:number(center.lat||point.lat),lng:number(center.lng||point.lng)});var temporal=image.temporalAssessment&&typeof image.temporalAssessment==="object"?image.temporalAssessment:{};var imageAgeMonths=finiteNumber(temporal.ageMonths,0,1200);var imageAgeYears=imageAgeMonths!==null?imageAgeMonths/12:(image.date&&image.date.year?Math.max(0,(new Date()).getFullYear()-number(image.date.year)):null); var gatewayMatch=diagnosticNumber(diagnosticObjects,["structureCenterDistanceMeters","matchDistanceMeters","structureDistanceMeters"],0,10000);if(gatewayMatch!==null)matchDistance=gatewayMatch;var gatewayImageAge=diagnosticNumber(diagnosticObjects,["imageAgeYears","imageryAgeYears"],0,100);if(gatewayImageAge!==null&&imageAgeMonths===null)imageAgeYears=gatewayImageAge;var geometryChecks=rawCandidates.length;var gatewayChecks=diagnosticNumber(diagnosticObjects,["candidateCount","calculationPathCount","geometryChecks","areaCalculationCount"],1,10);if(gatewayChecks!==null)geometryChecks=Math.round(gatewayChecks);var independentChecks=diagnosticNumber(diagnosticObjects,["independentCrossSourceCheckCount","independentMeasurementSourceCount"],0,10);if(independentChecks===null)independentChecks=0; var topology=normalizeTopology(roof.topology||payload.roofTopology||payload.topology);var addressMatch=payload.addressMatch&&typeof payload.addressMatch==="object"?payload.addressMatch:{};var selectionConfidence=finiteNumber(state.preflight&&state.preflight.selectionConfidence,0,100);var structureMatchReliable=String(addressMatch.precision||"").toUpperCase()==="HIGH"&&addressMatch.partialMatch!==true&&matchDistance<=45&&selectionConfidence!==null&&selectionConfidence>=55; var presentationContract=normalizePresentation(payload.presentation);var releaseGate=normalizeReleaseGate(payload.releaseGate);var safetyBlocksMetrics=safety.preliminaryAreaAllowed===false||safety.requiresMeasuredOverride===true;var geometryComplete=segments.length>0&&validPlaneInputs.length===segments.length&&rawCandidates.length===3&&validPlaneInputs.every(function(item){return item.groundAreaMeters2!==null&&item.groundAreaMeters2>0;});var historicalImageryReview=safetyBlocksMetrics&&allowsHistoricalPreliminaryMetrics({safety:safety,temporal:temporal,releaseGate:releaseGate,coverageStatus:gatewayCoverageStatus,structureMatchReliable:structureMatchReliable,geometryComplete:geometryComplete,consensusSpreadPct:consensusSpreadPct,quality:quality}); if(safetyBlocksMetrics&&!historicalImageryReview)throw new Error("Tree cover or shadows hid part of this roof, so this is a two-dimensional planning estimate from the best available imagery. An on-site measurement gets you exact numbers."); var report={source:provider.source,address:address,matchedAddress:payload.matchedAddress||address,lat:number(center.lat||point.lat),lng:number(center.lng||point.lng),areaSqFt:Number(areaSqFt.toFixed(2)),rawWholeAreaSqFt:Number(rawAreaSqFt.toFixed(2)),coverageScale:1,coverageAdjustmentSqFt:0,coverageStatus:gatewayCoverageStatus,obstructionPercent:obstructionPercent,obstructionKnown:Number.isFinite(obstructionPercent),consensusSpreadPct:consensusSpreadPct,surfaceAgreementPct:areaFusion.agreementPct,geometryChecks:geometryChecks,independentChecks:independentChecks,matchDistanceMeters:matchDistance,imageAgeMonths:imageAgeMonths,imageAgeYears:imageAgeYears,diagnosticsSource:historicalImageryReview?"Historical address-bound metrics · planning confidence applied":(diagnosticObjects.length?"Primary-roof evidence fusion":"Calculated from normalized geometry"),facets:planeRows.length,pitchRise:predominant.rise,pitchDegrees:predominant.degrees,planes:planeRows,imageryQuality:quality,imageryDate:isoDate(image.date),reportId:payload.measurementId||reportId("IRV"),measurementToken:payload.measurementToken||"",structureMatchReliable:structureMatchReliable,structureSelectionConfidence:selectionConfidence,structureSelectionBasis:state.preflight&&state.preflight.selectionReason||"address-bound primary roof fusion",historicalImageryReview:historicalImageryReview,roofGeometry:null,lines:null,lineModeled:{},lineAvailable:{},lineVerified:{},linealBasis:"not_supplied",topologyBasis:historicalImageryReview?"Historical context; roof-edge topology withheld":"Roof-edge topology not supplied",areaSelectionBasis:areaEvidenceSource,presentation:presentationContract,releaseGate:releaseGate,imported:false};return !historicalImageryReview&&topology?attachTopologyForReview(report,topology):report; }; var attachTopology=function(report,topology){ if(!report||!topology)return report;var reportPresentation=normalizePresentation(report.presentation);var topologyPresentation=normalizePresentation(topology.presentation);var reportMeasurementId=String(report.reportId||"").toUpperCase();var expectedCandidateId=state.preflight&&state.preflight.candidateId||""; if(!reportPresentation||!topologyPresentation||!/^IRV-S-[A-Z0-9]+$/.test(expectedCandidateId)||reportPresentation.primaryAsset.binding.measurementId!==reportMeasurementId||topology.measurementId!==reportMeasurementId||topologyPresentation.primaryAsset.binding.measurementId!==reportMeasurementId||reportPresentation.primaryAsset.binding.selectedCandidateId!==expectedCandidateId||topology.selectedCandidateId!==expectedCandidateId||topologyPresentation.primaryAsset.binding.selectedCandidateId!==expectedCandidateId||distanceMeters(reportPresentation.primaryAsset.center,topologyPresentation.primaryAsset.center)>2)throw new Error("We could not confidently match the roof to this address. Re-enter the address, or book a quick inspection for exact numbers."); var canonicalAreaSqFt=finiteNumber(topology.canonicalAreaSqFt,250,100000);if(canonicalAreaSqFt===null)return report;var facets=topology.roofGeometry&&Array.isArray(topology.roofGeometry.facets)?topology.roofGeometry.facets:[];if(!facets.length)return report; report.providerWholeAreaSqFt=finiteNumber(topology.providerAreaSqFt,0,100000);if(report.providerWholeAreaSqFt===null)report.providerWholeAreaSqFt=finiteNumber(report.rawWholeAreaSqFt,0,100000);report.canonicalAreaSqFt=canonicalAreaSqFt;report.areaSqFt=canonicalAreaSqFt;report.squares=finiteNumber(topology.canonicalSquares,0,1000);if(report.squares===null)report.squares=canonicalAreaSqFt/100;report.providerAreaDifferenceSqFt=report.providerWholeAreaSqFt===null?null:Number((report.providerWholeAreaSqFt-canonicalAreaSqFt).toFixed(2));report.roofGeometry=topology.roofGeometry;report.planes=facets.map(function(facet,index){return {index:facet.id||index+1,areaSqFt:facet.areaSqFt,pitchDegrees:Math.atan(number(facet.pitch)/12)*180/Math.PI,direction:facet.slopeDirection,canonical:true};});report.lines=topology.lines;report.lineModeled=topology.lineModeled||{};report.lineAvailable={};report.lineVerified={};report.linealBasis="address_geometry";report.topologyBasis=topology.basis;report.facets=facets.length;report.presentation=topologyPresentation;report.releaseGate=normalizeReleaseGate(topology.releaseGate);return report; }; var attachPlanningTopology=function(report,topology){ if(!report||!topology)return report;var reportPresentation=normalizePresentation(report.presentation);var expectedCandidateId=String(state.preflight&&state.preflight.candidateId||"");var topologyCenter=topology.propertyCenter||{};if(!reportPresentation||!/^IRV-S-[A-Z0-9]+$/.test(expectedCandidateId)||reportPresentation.primaryAsset.binding.selectedCandidateId!==expectedCandidateId||topology.selectedCandidateId!==expectedCandidateId||finiteNumber(topologyCenter.lat,-90,90)===null||finiteNumber(topologyCenter.lng,-180,180)===null||distanceMeters(reportPresentation.primaryAsset.center,topologyCenter)>2)throw new Error("The inferred roof graph was not bound to the confirmed property.");var canonicalAreaSqFt=finiteNumber(topology.canonicalAreaSqFt,250,100000);var facets=topology.roofGeometry&&Array.isArray(topology.roofGeometry.facets)?topology.roofGeometry.facets:[];var segments=topology.roofGeometry&&Array.isArray(topology.roofGeometry.lineSegments)?topology.roofGeometry.lineSegments:[];if(canonicalAreaSqFt===null||!facets.length||!segments.length||!topology.lines)throw new Error("The inferred roof graph was incomplete.");report.providerWholeAreaSqFt=finiteNumber(topology.providerAreaSqFt,0,100000);if(report.providerWholeAreaSqFt===null)report.providerWholeAreaSqFt=finiteNumber(report.rawWholeAreaSqFt,0,100000);report.canonicalAreaSqFt=canonicalAreaSqFt;report.areaSqFt=canonicalAreaSqFt;report.squares=finiteNumber(topology.canonicalSquares,0,1000);if(report.squares===null)report.squares=canonicalAreaSqFt/100;report.providerAreaDifferenceSqFt=report.providerWholeAreaSqFt===null?null:Number((report.providerWholeAreaSqFt-canonicalAreaSqFt).toFixed(2));report.roofGeometry=topology.roofGeometry;report.planes=facets.map(function(facet,index){return {index:facet.id||index+1,areaSqFt:facet.areaSqFt,pitchDegrees:Math.atan(number(facet.pitch)/12)*180/Math.PI,direction:facet.slopeDirection,canonical:true};});report.lines=topology.lines;report.lineModeled=topology.lineModeled||{};report.lineAvailable={};report.lineVerified={};report.linealBasis="address_geometry";report.topologyBasis=topology.basis+" · same-candidate planning binding";report.facets=facets.length;report.presentation=reportPresentation;report.releaseGate=normalizeReleaseGate(report.releaseGate)||planningGate();report.topologyCompatibilityMode=true;return report; }; var attachTopologyForReview=function(report,topology){ if(!report||!topology)return report; try{return attachTopology(report,topology);}catch(error){try{return attachPlanningTopology(report,topology);}catch(compatibilityError){report.topologyReviewReason="The address-bound roof-edge graph was not reusable, so roof geometry and lineals remain withheld for internal evidence review.";report.roofGeometry=null;report.lines=null;report.lineModeled={};report.lineAvailable={};report.lineVerified={};report.linealBasis="not_supplied";report.topologyBasis="Roof-edge topology not supplied";return report;}} }; var previewAddress=async function(){ if(!validateIntake())return; if(LEAD_CONFIG.preview){state.previewRequest+=1;state.preflight={inputAddress:fullAddress(),matchedAddress:"Illustrative preview property",point:{lat:0,lng:0},candidateCenter:{lat:0,lng:0},candidateId:"IRV-S-DEMO",confirmed:false,manualMatch:false};state.manualMatch=false;state.propertyConfirmed=null;$('irv2-preflight-address').textContent='Illustrative preview property · no real address lookup';$('irv2-preflight-map').removeAttribute('src');$('irv2-preflight-map').hidden=true;$('irv2-preflight-placeholder').hidden=false;$('irv2-preflight-placeholder-title').textContent='Offline sample property';$('irv2-preflight-placeholder-copy').textContent='No map, address, lead, measurement, or report request is sent in this preview.';$('irv2-house-use').disabled=false;$('irv2-house-use').textContent='View Complete Sample';setJourneyStep(2);setStatus('Offline sample ready. Confirm once to preview the complete illustrative result.','info');return;} if(!state.runtimeReady){showRecovery({code:"ENGINE_UNAVAILABLE",message:"The property-check service is not ready, so no roof request was sent. Retry the service check or call (678) 287-7169.",retryable:true,captureAvailable:false});setStatus("Property check paused until the measurement and PDF routes are ready.","warn");return;} clearRecovery(); var requestId=++state.previewRequest;var button=$('irv2-address-next');var address=fullAddress()||'Property address awaiting confirmation';button.disabled=true;button.setAttribute('aria-busy','true');button.textContent='Finding your roof...';clearStructureSelection();state.preflight=null;state.propertyConfirmed=null;state.manualMatch=false;state.visibility='';$('irv2-house-use').disabled=true;$('irv2-house-use').textContent='Build My 5-Page Report';$('irv2-preflight-address').textContent=address;$('irv2-preflight-map').removeAttribute('src');$('irv2-preflight-map').hidden=true;$('irv2-preflight-placeholder').hidden=false;$('irv2-preflight-placeholder-title').textContent='Finding the property view';$('irv2-preflight-placeholder-copy').textContent='Property matching identifies the primary roof. Usable roof evidence is evaluated during the address-level review.';setJourneyStep(2);setStatus('Matching the address and primary roof.','info'); try{ if(address==='Property address awaiting confirmation')throw new Error('No address supplied.');var configPromise=loadPresentationConfig();var structures=await findStructures(address);if(requestId!==state.previewRequest)return;var matched=structures.matchedAddress||address;var point=structureAnchorPoint(structures,matched);if(matched&&matched!==address){setAddressValue(matched);$('irv2-city').value='';$('irv2-state').value='';$('irv2-zip').value='';address=matched;}var selected=selectPrimaryStructureForAddress(structures,null,point);if(requestId!==state.previewRequest)return;var config=await configPromise;if(requestId!==state.previewRequest)return;var url=satelliteMapUrl(selected.center,selected.candidateId,null);var manual=!config||config.enabled!==true||!url; state.preflight={inputAddress:address,matchedAddress:matched,point:point,candidateCenter:selected.center,candidateId:selected.candidateId,groundFootprintSquareFeet:selected.groundFootprintSquareFeet,planningProfile:selected.planningProfile,planningProfileBasis:selected.planningProfileBasis,selectionConfidence:selected.selectionConfidence,selectionMargin:selected.selectionMargin,selectionEngine:selected.selectionEngine,selectionReason:selected.selectionReason,confirmed:false,manualMatch:manual};state.manualMatch=manual;$('irv2-preflight-address').textContent=matched;$('irv2-house-use').disabled=false; if(manual){if(url){$('irv2-preflight-placeholder').hidden=true;$('irv2-preflight-map').hidden=false;$('irv2-preflight-map').src=url;}else{$('irv2-preflight-map').removeAttribute('src');$('irv2-preflight-map').hidden=true;$('irv2-preflight-placeholder').hidden=false;}$('irv2-preflight-placeholder-title').textContent='Property matched · visual preview unavailable';$('irv2-preflight-placeholder-copy').textContent='The server-bound primary roof is available. Continue for a best-available result with every assumption clearly labeled.';$('irv2-house-use').textContent='Build Planning Report';setStatus('Property matched. Continue to build the planning result.','info');} else{$('irv2-preflight-placeholder').hidden=true;$('irv2-preflight-map').hidden=false;$('irv2-preflight-map').src=url;$('irv2-house-use').textContent='Check Roof & Build Report';setStatus('Primary roof found. Confirm it, then run the address-level roof check.','info');} }catch(error){if(requestId!==state.previewRequest)return;var preflightFailure=customerSafeFailure(error);state.preflight=null;state.manualMatch=false;state.propertyConfirmed=null;$('irv2-preflight-address').textContent=address;$('irv2-preflight-map').removeAttribute('src');$('irv2-preflight-map').hidden=true;$('irv2-preflight-placeholder').hidden=false;$('irv2-preflight-placeholder-title').textContent=preflightFailure.retryable?'Property check temporarily unavailable':'Property could not be confirmed';$('irv2-preflight-placeholder-copy').textContent=preflightFailure.message;$('irv2-house-use').disabled=true;$('irv2-house-use').textContent='Check Roof & Build Report';showRecovery(preflightFailure);setStatus(preflightFailure.message,'warn');setJourneyStep(1);} finally{if(requestId===state.previewRequest){button.disabled=!state.runtimeReady;button.setAttribute('aria-busy','false');button.textContent='Find My Roof';}} }; $('irv2-address-next').addEventListener('click',previewAddress); /* The route-scoped external Places adapter is the single callback owner. It progressively mounts Google's current PlaceAutocompleteElement and leaves this native field available whenever the API is unavailable. */ if(typeof window.irvInitPlaces==='function')window.irvInitPlaces(); /* Enter / the phone keyboard's "Go" key used to reach the form's submit handler, which runs the full build, finds no preflight, and answers with "No blocker. Start the estimator once..." — a dead end for someone who just typed their address. On the address stage, Enter now does the obvious thing and looks the property up. */ ['irv2-address','irv2-city','irv2-state','irv2-zip'].forEach(function(id){ var field=$(id); if(!field)return; field.addEventListener('keydown',function(event){ if(event.key!=='Enter'||event.isComposing)return; if(state.journeyStep!==1)return; event.preventDefault(); previewAddress(); }); }); $('irv2-house-use').addEventListener('click',async function(){if(!state.preflight)return;if(state.preflight.manualMatch===true){state.manualMatch=true;state.propertyConfirmed=false;}else{state.preflight.confirmed=true;state.manualMatch=false;state.propertyConfirmed=true;}state.visibility='AUTO_DETECTED';await createAndEmailPdf();}); var invalidatePropertySelection=function(){state.previewRequest+=1;state.preflight=null;state.manualMatch=false;state.propertyConfirmed=null;state.visibility='';clearRecovery();clearStructureSelection();$('irv2-preflight-map').removeAttribute('src');$('irv2-preflight-map').hidden=true;$('irv2-preflight-placeholder').hidden=false;}; $('irv2-house-change').addEventListener('click',function(){invalidatePropertySelection();setJourneyStep(1);setStatus('Update the full address, then show the property again.','info');}); var fallbackBindingProfile=function(report){ var status=String(report&&report.propertyBindingStatus||"address_candidate_unverified");var hasRange=!!numericRange(report&&report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2);var kind=hasRange?"Estimated planning range":"Planning context";var evidence=hasRange?"Best-available estimate · internal review available":"Documented assumptions · internal review available"; if(status==="server_bound_candidate_unconfirmed")return {verified:false,badge:kind+" · server-bound candidate",evidence:"Server-bound candidate · primary roof unconfirmed · "+evidence,basis:hasRange?"Server-bound matched-property estimate":"Server-bound matched-property planning assumptions",note:"Planning result: The signed token binds the address, candidate, and center. Values remain estimated and non-orderable; internal review can refine them before a proposal.",pin:"Server-bound candidate",lock:"The signed token binds this candidate to the address and center; values remain planning assumptions until internally reviewed."}; if(status==="manual_match_required")return {verified:false,badge:kind+" · internal match review",evidence:"Address context · internal primary-roof review · "+evidence,basis:hasRange?"Matched-property estimate":"Matched-property planning assumptions",note:"Planning result: The address context is usable for a best-available estimate. Internal review can refine the primary-roof binding before a proposal.",pin:"Internal match review",lock:"Address context is retained; primary-roof identity remains an internal review item."}; return {verified:false,badge:kind+" · planning assumptions",evidence:"Matched-property planning assumptions · "+evidence,basis:hasRange?"Matched-property estimate":"Matched-property planning assumptions",note:"Planning result: The numeric estimate uses documented assumptions and remains non-orderable. Internal evidence review can refine it.",pin:"Planning estimate",lock:"The matched-property estimate remains clearly labeled and routes stronger-evidence review internally."}; }; var renderRoofPlan=function(report,satelliteUrl){ var frame=$("irv2-roof-satellite"),placeholder=$("irv2-roofplaceholder"),badge=$("irv2-diagrambadge"),fallback=report&&report.fallback2D?fallbackBindingProfile(report):null; if(!frame||!placeholder||!badge)return; if(satelliteUrl){ frame.hidden=false;placeholder.hidden=true;frame.src=satelliteUrl;badge.textContent=report&&report.demo?"Demo only":(fallback?fallback.badge:"Property view · address bound");badge.className=report&&report.demo||fallback?"irv2-badge warn":"irv2-badge good";$("irv2-plan-evidence").textContent=report&&report.demo?"Synthetic preview":(fallback?fallback.evidence:"Presentation only · verified address");$("irv2-plan-basis").textContent=fallback?fallback.basis:"Address-bound property identity";$("irv2-plan-release").textContent=report&&report.demo?"Demo values · not orderable":(fallback?"Estimated planning values · not orderable":"Planning measurements · independently gated");$("irv2-plan-note").innerHTML=report&&report.demo?"Demo: The roof quantities are synthetic and are not property evidence.":(fallback?fallback.note:"Presentation evidence: The property view supports identity and field orientation only. Released measurements retain their own evidence and release checks; unresolved lineals remain withheld.");return; } frame.removeAttribute("src");frame.hidden=true;placeholder.hidden=false;badge.textContent=report&&report.demo?"Demo only":"Property view unavailable";badge.className="irv2-badge warn";$("irv2-plan-evidence").textContent=report&&report.imported?"Imported totals only":(fallback?fallback.evidence:"Presentation not supplied");$("irv2-plan-basis").textContent=report&&report.topologyBasis||"Not supplied";$("irv2-plan-release").textContent="No image · no substitute";$("irv2-plan-note").innerHTML=report&&report.demo?"Demo: No real property data or map request is used in the sample.":(fallback?"Planning continuity: The matched-property image was unavailable. "+escapeHtml(fallback.lock)+" No generic roof image was substituted.":"Presentation evidence: The approved address-bound property view was not available. No generic roof image was substituted."); }; var measurementRows=function(report){ report=report||{};var planning=report.planningEstimate===true;var measuredInputs=report.metricEvidence&&report.metricEvidence.areaSqFt==="measured";var missing=planning?'Estimated · internal review available':'Planning baseline'; var pitchValue=finiteNumber(report.pitchRise,0,IRV_LIMITS.pitchRise),areaRange=numericRange(report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(report.squaresRange,2.5,IRV_LIMITS.netSquares,4),pitchRange=numericRange(report.pitchRiseRange,0,IRV_LIMITS.pitchRise,0),facetsRange=numericRange(report.facetsRange,1,IRV_LIMITS.facets,0),has2DRange=report.fallback2D===true&&areaRange!==null; var lines=report.lines||{}; var verified=report.lineVerified||{}; var modeled=report.lineModeled||{}; var available=report.lineAvailable||{}; var lineNumber=function(key){return finiteNumber(lines[key],0,100000);}; var lineValue=function(key){var value=lineNumber(key);if(verified[key]===true&&value!==null)return format(value,1)+" LF";if(report.linealBasis==="address_geometry"&&modeled[key]===true&&value!==null)return planningValue(report,key,value,function(next){return format(next,1)+" LF";});return missing;}; var lineBasis=function(key){var value=lineNumber(key);if(verified[key]===true){if(key==="dripEdge")return "Exact derived identity · eaves + rakes";if(value===0)return report.demo?"Illustrative verified zero · not property evidence":"Explicit verified zero";return report.demo?"Illustrative sample value · not property evidence":"Measured · signed release";}if(report.linealBasis==="address_geometry"&&modeled[key]===true){if(key==="dripEdge")return "Derived address-geometry identity · eaves + rakes";return "Address-geometry planning value";}return planning?"Not supplied · internal review available":"Planning baseline";}; var canonicalArea=finiteNumber(report.canonicalAreaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);var areaDigits=canonicalArea===null?0:2;var fallbackArea=has2DRange?format(areaRange[0],0)+"–"+format(areaRange[1],0)+" sq ft":missing;var fallbackPitch=pitchRange?wholePitchRangeLabel(pitchRange):missing;var fallbackFacets=facetsRange?format(facetsRange[0])+"–"+format(facetsRange[1]):missing;var fallbackBasis=has2DRange?"Estimated matched-property range · internal review available":"Documented planning assumptions · internal review available"; var coreRows=[ ["Total roof area",report.fallback2D?fallbackArea:(canonicalArea===null?missing:planningValue(report,"areaSqFt",report.areaSqFt,function(value){return format(value,areaDigits)+" sq ft";})),report.fallback2D?fallbackBasis:(report.demo?"Context · synthetic sample":(measuredInputs?"Assessment measurement · lineals withheld pending review":(planning?"Planning evidence · not orderable":"Independently reviewed roof surface · signed release")))], ["Predominant pitch",report.fallback2D?fallbackPitch:(pitchValue===null?missing:planningValue(report,"pitch",pitchValue,function(value){return wholePitchLabel(value);})),report.fallback2D?(pitchRange?"Estimated planning range · internal review available":"Planning assumption · internal review available"):(pitchValue===null?"Not supplied · internal review available":(report.demo?"Context · synthetic sample":(report.metricEvidence&&report.metricEvidence.pitch==="measured"?"Assessment measurement · lineals withheld pending review":(planning?"Planning input · not for ordering":"Independently reviewed pitch set · signed release"))))], ["Roof facets",report.fallback2D?fallbackFacets:(finiteNumber(report.facets,1,200)!==null?planningValue(report,"facets",report.facets,function(value){return format(value);}):missing),report.fallback2D?(facetsRange?"Estimated planning range · internal review available":"Planning assumption · internal review available"):(report.demo?"Context · synthetic sample":(measuredInputs?"Assessment measurement · lineals withheld pending review":(planning?"Planning facet count":"Independently reviewed facet register")))] ]; if(canonicalArea!==null&&finiteNumber(report.providerWholeAreaSqFt,0,IRV_LIMITS.surfaceAreaSqFt)!==null)coreRows.push(["Whole-area comparison",format(report.providerWholeAreaSqFt,2)+" sq ft","Comparison only · not used for canonical area or roofing squares"]); var linealRows=[ ["Ridges",lineValue("ridges"),lineBasis("ridges")], ["Hips",lineValue("hips"),lineBasis("hips")], ["Valleys",lineValue("valleys"),lineBasis("valleys")], ["Rakes",lineValue("rakes"),lineBasis("rakes")], ["Eaves",lineValue("eaves"),lineBasis("eaves")], ["Drip edge / starter perimeter",lineValue("dripEdge"),lineBasis("dripEdge")], ["Flashing",lineValue("flashing"),lineBasis("flashing")], ["Step flashing",lineValue("stepFlashing"),lineBasis("stepFlashing")], ["Parapets",lineValue("parapets"),lineBasis("parapets")] ]; var rowHtml=function(rows){return rows.map(function(r){return ""+r[0]+""+r[1]+""+r[2]+"";}).join("");}; var keys=["ridges","hips","valleys","rakes","eaves","dripEdge","flashing","stepFlashing","parapets"];var supplied=keys.filter(function(key){return verified[key]===true;}).length;var modeledCount=keys.filter(function(key){return modeled[key]===true;}).length; return {core:rowHtml(coreRows),lineals:rowHtml(linealRows),supplied:supplied,modeled:modeledCount,total:linealRows.length}; }; var renderPlanes=function(planes,report){ var box=$("irv2-planes"); var displayPlanes=Array.isArray(planes)?planes.slice():[]; if(!displayPlanes.length&&report&&report.roofGeometry&&Array.isArray(report.roofGeometry.facets)){ displayPlanes=report.roofGeometry.facets.map(function(facet,index){return {index:facet.id||index+1,areaSqFt:number(facet.areaSqFt),pitchDegrees:Math.atan(number(facet.pitch)/12)*180/Math.PI,direction:facet.slopeDirection};}); } if(!displayPlanes.length){ box.innerHTML='

'+(report&&report.imported?"Aggregate professional totals supplied; individual planes were not included.":"Plane register was not supplied; the planning assumptions remain non-orderable and can be refined internally.")+'

'; return; } box.innerHTML=displayPlanes.map(function(p){ var directPitch=finiteNumber(p&&p.pitch,0,24);var pitch=directPitch===null?pitchLabel(finiteNumber(p&&p.pitchDegrees,0,89)||0):{rise:wholePitchRise(directPitch),label:wholePitchLabel(directPitch)}; var direction=p.direction?String(p.direction).toUpperCase():bearing(p.azimuthDegrees); var evidence=report&&report.officeExample?"address-bound plane":"faces "+escapeHtml(direction); return '
Facet '+escapeHtml(p.index)+' · '+escapeHtml(pitch.label)+''+format(p.areaSqFt,2)+' sq ft · '+evidence+'
'; }).join(""); }; var reportPitchProfile=function(report){ var values=[];var facets=report&&report.roofGeometry&&Array.isArray(report.roofGeometry.facets)?report.roofGeometry.facets:[];var planes=report&&Array.isArray(report.planes)?report.planes:[]; if(facets.length){facets.forEach(function(facet){var pitch=wholePitchRise(facet&&facet.pitch);if(pitch!==null)values.push(pitch);});}else{planes.forEach(function(plane){var degrees=finiteNumber(plane&&plane.pitchDegrees,0,89);if(degrees!==null)values.push(pitchLabel(degrees).rise);});} var predominant=wholePitchRise(report&&report.pitchRise);if(!values.length&&predominant!==null)values.push(predominant);values=values.filter(function(value,index,list){return list.indexOf(value)===index;}).sort(function(a,b){return a-b;}); var pitchText=function(value){return wholePitchLabel(value);};if(!values.length)return {short:"Not measured",detail:"Pitch evidence was not supplied.",minimum:null,maximum:null,predominant:null};var minimum=values[0],maximum=values[values.length-1];var short=minimum===maximum?pitchText(minimum):pitchText(minimum)+"–"+pitchText(maximum);var detail=minimum===maximum?short+" across the available roof planes":short+" range";if(minimum!==maximum&&predominant!==null&&predominant>=minimum&&predominant<=maximum)detail+=" · "+pitchText(predominant)+" predominant";return {short:short,detail:detail,minimum:minimum,maximum:maximum,predominant:predominant}; }; var briefItemsHtml=function(items){return items.map(function(item){return '
  • '+escapeHtml(item.label)+''+escapeHtml(item.value)+'
  • ';}).join("");}; var renderCustomerBrief=function(report){ var brief=$("irv2-customer-brief");if(!brief)return;if(!report||report.demo){brief.hidden=true;return;}brief.hidden=false;$("irv2-brief-address").textContent=report.matchedAddress||report.address||"Matched property";var briefStatus=$("irv2-brief-status");var briefState=report.fallback2D||report.measurementEvidence==="estimated"?"PLANNING ESTIMATE · field verify":(report.planningEstimate?"PLANNING RESULT · field verify":"Verified result");briefStatus.textContent=briefState;briefStatus.className="irv2-badge "+(report.planningEstimate?"warn":"good"); var area=finiteNumber(report.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);var squares=area===null?null:area/100;var planeCount=finiteNumber(report.facets,1,IRV_LIMITS.facets);var pitch=reportPitchProfile(report);var known=[]; var measuredInputs=report.metricEvidence&&report.metricEvidence.areaSqFt==="measured"&&report.metricEvidence.pitch==="measured"&&report.metricEvidence.facets==="measured";var areaRange=numericRange(report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(report.squaresRange,2.5,IRV_LIMITS.netSquares,4),pitchRange=numericRange(report.pitchRiseRange,0,IRV_LIMITS.pitchRise,0),facetsRange=numericRange(report.facetsRange,1,IRV_LIMITS.facets,0);if(report.fallback2D){known.push({label:"Roof surface",value:areaRange?format(areaRange[0],0)+"–"+format(areaRange[1],0)+" sq ft · ESTIMATED range":format(area,0)+" sq ft · ESTIMATED"});known.push({label:"Roofing squares",value:squaresRange?format(squaresRange[0],2)+"–"+format(squaresRange[1],2)+" before waste · ESTIMATED":format(squares,2)+" before waste · ESTIMATED"});known.push({label:"Roof facets",value:facetsRange?format(facetsRange[0])+"–"+format(facetsRange[1])+" · ESTIMATED range":format(planeCount)+" · planning assumption"});known.push({label:"Pitch",value:pitchRange?wholePitchRangeLabel(pitchRange)+" · ESTIMATED range":pitch.detail+" · planning assumption"});}else if(report.planningEstimate&&!measuredInputs){var estimateTag=report.measurementEvidence==="estimated"?"estimated":"planning estimate";known.push({label:"Roof surface",value:area===null?"Not measured":format(area,0)+" sq ft · "+estimateTag});known.push({label:"Roofing squares",value:squares===null?"Not measured":format(squares,2)+" squares before waste · "+estimateTag});known.push({label:"Roof facets",value:planeCount===null?"Not measured":format(planeCount)+" · "+estimateTag});known.push({label:"Pitch",value:pitch.minimum===null?"Not measured":pitch.detail+" · "+estimateTag});}else{known.push({label:"Roof surface",value:area===null?"Not measured":format(area,0)+" sq ft · measured planning input"});known.push({label:"Roofing squares",value:squares===null?"Not measured":format(squares,2)+" squares before waste · measured area ÷ 100"});known.push({label:"Roof facets",value:planeCount===null?"Not measured":format(planeCount)+" measured planning facets"});known.push({label:"Pitch",value:pitch.minimum===null?"Not measured":pitch.detail+" · measured planning input"});}$("irv2-brief-known").innerHTML=briefItemsHtml(known); var verification=[];var imageDate=String(report.imageryDate||"").trim();if(report.fallback2D){var fallbackProfile=fallbackBindingProfile(report);verification.push({label:"Use",value:"Estimated matched-property planning result; not a material order or survey."});verification.push({label:"Binding",value:fallbackProfile.evidence+"."});verification.push({label:"Internal next step",value:"Stronger property evidence can refine the assumptions before scoping, contracting, or ordering."});}else if(report.planningEstimate){verification.push({label:"Use",value:"Evidence-labeled budgeting report; not a material order."});verification.push({label:"Evidence",value:(imageDate?imageDate+" · ":"")+"address-bound evidence where available; estimates are explicitly labeled."});verification.push({label:"Roof edges",value:report.linealBasis==="address_geometry"?"Supplied address geometry is labeled for field review.":"Lineals were not supplied and remain withheld for internal evidence review."});}else{verification.push({label:"Release",value:"All seven server checks passed for this exact property and report ID."});verification.push({label:"Evidence",value:(imageDate&&imageDate!=="Unknown"?imageDate+" · ":"")+"trusted field or professional measurement evidence accepted."});verification.push({label:"Roof edges",value:"Every required lineal is measured or an explicit verified zero; drip edge is the exact eaves-plus-rakes identity."});}$("irv2-brief-review").innerHTML=briefItemsHtml(verification); }; var renderTechnicalAudit=function(report){ var area=finiteNumber(report&&report.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);var facets=report&&report.roofGeometry&&Array.isArray(report.roofGeometry.facets)?report.roofGeometry.facets:[];var planes=report&&Array.isArray(report.planes)?report.planes:[];var areaSources=facets.length?facets:planes;var facetAreas=areaSources.map(function(facet){return finiteNumber(facet&&facet.areaSqFt,0,IRV_LIMITS.surfaceAreaSqFt);}).filter(function(value){return value!==null;});var facetSum=facetAreas.reduce(function(total,value){return total+value;},0);var pitch=reportPitchProfile(report);var planeCount=finiteNumber(report&&report.facets,1,IRV_LIMITS.facets); var areaRange=numericRange(report&&report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(report&&report.squaresRange,2.5,IRV_LIMITS.netSquares,4),pitchRange=numericRange(report&&report.pitchRiseRange,0,IRV_LIMITS.pitchRise,0),facetsRange=numericRange(report&&report.facetsRange,1,IRV_LIMITS.facets,0),has2DRange=!!(report&&report.fallback2D&&areaRange);if(report&&report.fallback2D)$("irv2-math-area").textContent=has2DRange?format(areaRange[0],0)+"–"+format(areaRange[1],0)+" sq ft · estimated 2D footprint range · no facet sum":"Not measured · no 2D dimensional range was supplied";else if(area===null)$("irv2-math-area").textContent="Unknown · roof surface was not released";else if(facetAreas.length)$("irv2-math-area").textContent="Σ "+facetAreas.length+" roof-plane surfaces = "+format(facetSum,2)+" sq ft; displayed surface = "+format(area,2)+" sq ft";else $("irv2-math-area").textContent="Whole-roof surface = "+format(area,2)+" sq ft; facet sum unavailable"; $("irv2-math-squares").textContent=report&&report.fallback2D?(squaresRange?format(squaresRange[0],2)+"–"+format(squaresRange[1],2)+" squares · ESTIMATED":format(area/100,2)+" squares · planning assumption"):(area===null?"Unknown · roof surface was not released":format(area,2)+" ÷ 100 = "+format(area/100,4)+" squares");$("irv2-math-pitch").textContent=report&&report.fallback2D?(pitchRange?wholePitchRangeLabel(pitchRange)+" estimated range":wholePitchLabel(report.pitchRise)+" planning assumption"):pitch.detail;$("irv2-math-planes").textContent=report&&report.fallback2D?(facetsRange?format(facetsRange[0])+"–"+format(facetsRange[1])+" estimated facet range":format(report.facets)+" planning assumption"):(planeCount===null?"Unknown · plane count was not supplied":format(planeCount)+" available roof planes"); var definitions=[{code:"IDENTITY",label:"Property identity"},{code:"IMAGERY_RECENCY",label:"Imagery context"},{code:"AREA",label:"Roof surface"},{code:"PITCH",label:"Roof pitch"},{code:"TOPOLOGY",label:"Roof-plan topology"},{code:"LINEALS",label:"Property lineals"},{code:"FIELD_OR_PROVIDER_EVIDENCE",label:"Evidence labeling"}];var gate=normalizeReleaseGate(report&&report.releaseGate);var checks=gate&&Array.isArray(gate.checks)?gate.checks:[];var planning=!!(report&&report.planningEstimate),fallback=!!(report&&report.fallback2D);$("irv2-release-title").textContent=fallback?"2D planning report blockers":(planning?"Planning-output audit":"Seven release checks");$("irv2-release-checks").innerHTML=definitions.map(function(definition){var check=checks.filter(function(candidate){return candidate.code===definition.code;})[0];var passed=!fallback&&(planning||!!(check&&check.passed===true));return '
  • '+escapeHtml(definition.label)+''+escapeHtml(definition.code)+''+(fallback?'Blocked':(planning?'Included':(passed?'Pass':'Blocked')))+'
  • ';}).join("");$("irv2-technical-details").open=false; }; var renderFieldRelease=function(report){ var definitions=[{code:"IDENTITY",label:"Primary roof identity"},{code:"IMAGERY_RECENCY",label:"Current condition"},{code:"AREA",label:"Roof area"},{code:"PITCH",label:"Pitch set"},{code:"TOPOLOGY",label:"Facet topology"},{code:"LINEALS",label:"All lineals"},{code:"FIELD_OR_PROVIDER_EVIDENCE",label:"Trusted field/provider evidence"}]; var gate=normalizeReleaseGate(report&&report.releaseGate);var checks=gate&&Array.isArray(gate.checks)?gate.checks:[];var planning=!!(report&&report.planningEstimate);var ready=!!(gate&&gate.orderReady===true&&gate.materialOrderingAllowed===true&&gate.pdfClassification==="VERIFIED_ORDER_TAKEOFF");var panel=$("irv2-field-release");panel.classList.toggle("ready",ready);$("irv2-field-status").textContent=report&&report.fallback2D?"Planning estimate · field verify":(planning?"5-page planning report · field verify":(ready?"Verified takeoff · 7/7 passed":"Report withheld"));$("irv2-field-checks").innerHTML=definitions.map(function(definition){var check=checks.filter(function(candidate){return candidate.code===definition.code;})[0];var passed=!!(check&&check.passed===true);var stateClass=planning?" planning":(passed?" pass":"");var stateIcon=planning?"•":(passed?"✓":"!");var stateText=planning?"planning-only":(passed?"passed":"blocked");return '
  • '+escapeHtml(definition.label)+''+stateText+'
  • ';}).join("");$("irv2-field-note").textContent=report&&report.fallback2D?"The numeric result uses matched-property evidence and documented assumptions. It remains non-orderable; internal evidence review can refine roof area, pitch, facets, and lineals before a proposal.":(planning?(report.linealBasis==="address_geometry"?"This planning package labels every released value and remains non-orderable. Field-verify the supplied address geometry before scoping.":"Area, pitch, and facet evidence is available for budgeting. Roof-edge geometry and lineals remain internal review items before scoping or ordering."):(ready?"All seven automatic checks passed. Use only the signed Verified Order Takeoff PDF for this exact report ID and property.":"A verified report is not available for this record.")); }; var qualityText=function(report){if(report.demo)return "Context · illustrative sample";if(report.fallback2D)return "ESTIMATED matched-property planning result";if(report.measurementEvidence==="estimated")return "Estimated address-bound planning record";if(report.planningEstimate&&report.metricEvidence&&report.metricEvidence.areaSqFt==="measured")return "Measured planning inputs · lineals withheld";if(report.planningEstimate)return "Planning evidence";if(report.imported)return "Context · imported report";var q=String(report.imageryQuality||"UNKNOWN").toUpperCase();if(q==="HIGH")return "Context · high image quality";if(q==="MEDIUM")return "Context · medium image quality";return "Evidence quality not recorded";}; var planningValue=function(report,key,value,formatter){var metric=report&&report.metricEvidence&&report.metricEvidence[key];if(value===null||value===undefined)return "Not measured";var display=formatter?formatter(value):String(value);if(metric==="measured")return display;if(metric==="estimated"||metric==="estimated_range")return display+" · estimated";return report&&report.planningEstimate?display+" · planning":display;}; var accuracyProfile=function(report){ var gate=normalizeReleaseGate(report.releaseGate);var completeness=customerPdfCompleteness(report); if(report.demo)return {score:"DEMO",title:"Illustrative app preview",note:"These demonstration values are synthetic and do not describe a real property.",tag:"Demo only"}; if(report.fallback2D)return {score:"ESTIMATED",title:"Best-available five-page planning result ready",note:"The numeric result uses matched-property evidence and documented assumptions. Internal evidence review can refine it; the result is not order-ready.",tag:"Estimated · budget only"}; if(report.planningEstimate)return {score:report.measurementEvidence==="estimated"?"ESTIMATED":(report.linealBasis==="address_geometry"?"PLANNING":"PARTIAL"),title:report.measurementEvidence==="estimated"?"Estimated five-page planning report ready":"Five-page planning estimate ready",note:report.linealBasis==="address_geometry"?"Released values and supplied address geometry retain their evidence labels.":"Released values retain their evidence labels; unsupported roof geometry and lineals remain internal review items.",tag:report.measurementEvidence==="estimated"?"Estimated · budget only":"Budget only"}; if(completeness.ready&&gate&&gate.orderReady===true&&gate.materialOrderingAllowed===true&&gate.pdfClassification==="VERIFIED_ORDER_TAKEOFF")return {score:"VERIFIED",title:"Verified for ordering",note:"All seven server release checks passed, every order-critical value is complete, and trusted field or professional evidence is bound to this review.",tag:"Complete · signed release"}; return {score:"WITHHELD",title:"Measured inputs needed",note:"This result is incomplete and cannot be rendered, previewed, downloaded, or emailed as a report.",tag:"No report"}; }; var updateEvidence=function(report){if(!report)return;var accuracy=accuracyProfile(report);$("irv2-accuracy-score").textContent=accuracy.score;$("irv2-accuracy-title").textContent=accuracy.title;$("irv2-accuracy-note").textContent=accuracy.note;$("irv2-accuracy-tag").textContent=accuracy.tag;}; var revealReport=function(openDetails){var details=$("irv2-web-details");details.hidden=false;details.open=openDetails===true;if(!details.open)return;var brief=$("irv2-customer-brief");var heading=brief&&!brief.hidden?$("irv2-brief-title"):$("irv2-accuracy-title");var reduceMotion=window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;details.scrollIntoView({behavior:reduceMotion?"auto":"smooth",block:"start"});setTimeout(function(){try{heading.focus({preventScroll:true});}catch(e){heading.focus();}},reduceMotion?0:350);}; var render=function(report){ var renderGate=report&&report.demo?{ready:true}:customerPdfCompleteness(report);if(!renderGate.ready&&!(report&&report.planningEstimate))throw new Error("A report needs either complete verified evidence or the planning-estimate fallback."); state.report=report;state.propertyConfirmed=(report.demo||report.imported)?null:((state.preflight&&state.preflight.confirmed===true)?true:null);var fallbackProfile=report&&report.fallback2D?fallbackBindingProfile(report):null;$("irv2-report").classList.add("active");renderMeasuredBridge(report);var planes=Array.isArray(report.planes)?report.planes:[];var pitchValue=finiteNumber(report.pitchRise,0,IRV_LIMITS.pitchRise);var canonicalArea=finiteNumber(report.canonicalAreaSqFt,250,IRV_LIMITS.surfaceAreaSqFt);var areaRange=numericRange(report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(report.squaresRange,2.5,IRV_LIMITS.netSquares,4),pitchRange=numericRange(report.pitchRiseRange,0,IRV_LIMITS.pitchRise,0),facetsRange=numericRange(report.facetsRange,1,IRV_LIMITS.facets,0);updateEvidence(report);renderCustomerBrief(report);renderTechnicalAudit(report);renderFieldRelease(report);renderBudgetSnapshot(report);renderRooferQuestions(report); $("irv2-matched").textContent=report.matchedAddress||report.address;$("irv2-source").textContent=report.demo?"Illustrative preview":(report.fallback2D?"ESTIMATED · matched-property planning result":(report.measurementEvidence==="estimated"?"ESTIMATED · property assessment range":(report.planningEstimate?"ASSESSMENT MEASUREMENT · planning use":(report.imported?"Professional import · independently reviewed":"Independently reviewed takeoff"))));$("irv2-imagery").textContent=report.demo?"Not applicable":report.imageryDate;$("irv2-reportid").textContent=report.reportId; $("irv2-area").textContent=report.fallback2D?(areaRange?format(areaRange[0],0)+"–"+format(areaRange[1],0)+" sf":"Not measured"):planningValue(report,"areaSqFt",canonicalArea,function(value){return format(value,2)+" sf";});$("irv2-squares").textContent=report.fallback2D?(squaresRange?format(squaresRange[0],2)+"–"+format(squaresRange[1],2):"Not measured"):planningValue(report,"squares",canonicalArea===null?null:report.squares,function(value){return format(value,4);});$("irv2-pitch").textContent=report.fallback2D?(pitchRange?wholePitchRangeLabel(pitchRange):"Not measured"):planningValue(report,"pitch",pitchValue,function(value){return wholePitchLabel(value);});$("irv2-facets").textContent=report.fallback2D?(facetsRange?format(facetsRange[0])+"–"+format(facetsRange[1]):"Not measured"):planningValue(report,"facets",finiteNumber(report.facets,1,IRV_LIMITS.facets),function(value){return format(value);});$("irv2-quality").textContent=qualityText(report); var obstructionKnown=Number.isFinite(report.obstructionPercent);$("irv2-obstruction").textContent=obstructionKnown?"Corroborating signal":"Not supplied";$("irv2-obstruction-note").textContent=report.demo?"Context · synthetic sample":(obstructionKnown?"Context only · obstruction signal present":"No obstruction signal was released by the measurement engine"); $("irv2-area-note").textContent=report.demo?"Context · synthetic sample":(report.fallback2D?"ESTIMATED matched-property range · internal review available":(report.metricEvidence&&report.metricEvidence.areaSqFt==="measured"?"Assessment measurement · lineals withheld pending review":(report.measurementEvidence==="estimated"?"Estimated property assessment record · not for ordering":(report.planningEstimate?"Planning estimate · not for ordering":"Independently reviewed roof surface · signed release")))); $("irv2-pitch-note").textContent=report.fallback2D?"Estimated pitch assumption · internal review available":(pitchValue===null?"Not supplied · internal review available":(report.demo?"Context · synthetic sample":(report.metricEvidence&&report.metricEvidence.pitch==="measured"?"Assessment measurement · lineals withheld pending review":(report.measurementEvidence==="estimated"?"Estimated pitch · not for ordering":(report.planningEstimate?"Planning input · not for ordering":"Independently reviewed pitch set · signed release"))))); $("irv2-diag-area").textContent=report.demo?"Context · synthetic sample":(report.fallback2D?"Estimated matched-property roof surface":(report.planningEstimate?"Planning roof-plane sum":(canonicalArea===null?"Verified professional roof total":"Verified facet sum · signed release"))); $("irv2-diag-obstruction").textContent=report.demo?"Context · synthetic":(obstructionKnown?"Corroborating signal present":"Unknown · not supplied"); $("irv2-diag-match").textContent=report.demo?"Context · demo only":(fallbackProfile?fallbackProfile.evidence:(report.imported?"Verified professional property binding":("Verified · "+format(report.matchDistanceMeters||0,1)+" m center check"))); $("irv2-diag-age").textContent=report.demo?"Context · demo only":(report.imageAgeYears===null||report.imageAgeYears===undefined?"Trusted release evidence accepted":"Verified context · "+format(report.imageAgeYears,1)+" years"); renderHistoricalContext(report); var planFacetCount=report.roofGeometry&&Array.isArray(report.roofGeometry.facets)?report.roofGeometry.facets.length:0;var rows=measurementRows(report);var providedLineals=rows.supplied+rows.modeled;$("irv2-planebadge").textContent=report.demo?"Demo only":(report.fallback2D?format(report.facets||0)+" estimated facets":(report.planningEstimate?format(planes.length||planFacetCount||report.facets||0)+" planning facets":format(planes.length||planFacetCount)+" verified facets"));$("irv2-measurements").innerHTML=rows.core;$("irv2-lineals").innerHTML=rows.lineals;$("irv2-lineals-summary").textContent=report.demo?"Illustrative lineals · synthetic values only":(report.planningEstimate?(providedLineals+" of "+rows.total+" lineal classes supplied · unresolved rows remain internal review items"):"Lineal measurements · "+rows.supplied+" measured, derived, or verified-zero values");$("irv2-lineals-details").open=false;renderPlanes(planes,report); $("irv2-takeoffbadge").textContent=report.demo?"Demo model":(report.planningEstimate?(providedLineals+" lineals supplied"):"Complete lineals");$("irv2-takeoffbadge").className=report.demo||report.planningEstimate?"irv2-badge warn":"irv2-badge good"; var candidateId=report.sampleCandidateId||state.preflight&&state.preflight.candidateId||"";var reportMapUrl=report.demo?"":(report.lat&&report.lng?satelliteMapUrl({lat:report.lat,lng:report.lng},candidateId,report.presentation,report.reportId):""); if(reportMapUrl){ $("irv2-map").hidden=false;$("irv2-map-placeholder").hidden=true;$("irv2-map").src=reportMapUrl;$("irv2-pinbadge").textContent=fallbackProfile?fallbackProfile.pin:"Property confirmed";$("irv2-property-lock-note").textContent=fallbackProfile?fallbackProfile.lock:"Confirmed before analysis · the property view supports identity, not dimensional evidence."; $("irv2-streetview").href="https://www.google.com/maps/@?api=1&map_action=pano&viewpoint="+encodeURIComponent(report.lat+","+report.lng); $("irv2-streetview").style.display="inline-flex"; }else{ $("irv2-map").removeAttribute("src");$("irv2-map").hidden=true;$("irv2-map-placeholder").hidden=false;$("irv2-pinbadge").textContent=report.demo?"Demo only":"No map"; $("irv2-map-placeholder-title").textContent=report.demo?"Sample map intentionally omitted":"Public map not included";$("irv2-map-placeholder-copy").textContent=report.demo?"The illustrative example sends no property or map request.":(fallbackProfile?fallbackProfile.lock:"The trusted professional measurement supplied the verified property binding without a public map image.");$("irv2-property-lock-note").textContent=report.demo?"Demonstration values only.":(fallbackProfile?fallbackProfile.lock:"Property identity passed the signed server release for this report ID."); $("irv2-streetview").removeAttribute("href");$("irv2-streetview").style.display="none"; } var releaseGate=normalizeReleaseGate(report.releaseGate);$("irv2-pdf-view").textContent=report.demo?"Demo values only":(report.planningEstimate?"Open 5-Page Planning Report":(releaseGate&&releaseGate.orderReady?"Open Verified Order Report":"Report Withheld")); renderRoofPlan(report,reportMapUrl); var readyMessage=report.demo?"Complete illustrative sample ready. No network request or PDF is created for demonstration-only values.":(fallbackProfile?"Your best-available numeric planning result is ready. It is non-orderable and routes stronger-evidence review internally.":(report.planningEstimate?"Evidence-labeled roof calculations are ready. Building the five-page PDF with unresolved rows marked for internal review.":(releaseGate&&releaseGate.orderReady?"The signed report passed every release check. Use only that verified PDF for ordering.":"Measurement review pending. No incomplete PDF was generated.")));setStatus(readyMessage,report.demo?"info":(report.planningEstimate?"info":(releaseGate&&releaseGate.orderReady?"good":"warn")));revealReport(report.demo===true||report.planningEstimate===true); }; var measure=async function(address,reviewOnly){ if(LEAD_CONFIG.preview)return null; var safeReviewOnly=reviewOnly===true&&state.preflight&&state.preflight.manualMatch===true&&/^IRV-S-[A-Z0-9]+$/.test(String(state.preflight.candidateId||"")); if(!state.preflight||(!safeReviewOnly&&(state.preflight.confirmed!==true||state.propertyConfirmed!==true)))throw new Error("Confirm the matched property before measurement begins."); if(state.preflight.inputAddress!==address)throw new Error("The property address changed after confirmation. Show and confirm the matched property again."); setBusy(true);setStatus("Matching the address…","info");setDiag("geo","Running");setDiag("solar","Waiting");setDiag("lines","Waiting"); try{ state.measurementError=null;clearRecovery(); var structures=await findStructures(address);var matched=structures.matchedAddress||address;var point=structureAnchorPoint(structures,matched);setStatus("Address matched. Rechecking the bound primary roof…","info");var bindingAddress=structures.structureBindingAddress||matched;var selected=selectPrimaryStructureForAddress(structures,state.preflight.candidateId,point);if(state.preflight.candidateId&&(!selected||selected.candidateId!==state.preflight.candidateId))throw new Error("The primary roof binding changed. Confirm the property again.");state.preflight.selectionConfidence=selected.selectionConfidence;state.preflight.selectionMargin=selected.selectionMargin;state.preflight.selectionReason=selected.selectionReason;state.preflight.groundFootprintSquareFeet=selected.groundFootprintSquareFeet;state.preflight.planningProfile=selected.planningProfile;state.preflight.planningProfileBasis=selected.planningProfileBasis;setStatus(safeReviewOnly?"Address-bound primary roof locked for review. Analyzing the best available evidence…":"Confirmed primary roof locked. Analyzing the best available evidence…","info"); var analysis=await Promise.all([findMeasure(selected,bindingAddress),findTopology(selected,matched)]);var provider=analysis[0];var topology=analysis[1];var report=parseRoofMeasure(provider,matched,point);var measured=report.measurementEvidence==="measured"; if(measured){var obstruction=providerObstructionPercent(provider);var historical=null;if(obstruction!==null&&obstruction>=HISTORICAL_IMAGERY_TRIGGER_PERCENT){setStatus("Heavy obstruction detected automatically. Checking dated property context while preserving the current property view…","info");historical=await findHistoricalImagery(selected,matched);}if(historical)report.historicalImagery=historical;if(report.historicalImageryReview===true)topology=null;report=attachTopologyForReview(report,topology);if(!topology&&!report.roofGeometry)report.topologyReviewReason=report.historicalImageryReview?"Dated context supports orientation only; unresolved roof-edge dimensions remain withheld.":"Property-specific roof-edge geometry was not supplied, so lineals remain withheld.";}else{topology=null;report.topologyReviewReason="Estimated results do not include independently reviewed roof-edge geometry or lineals; internal review can refine them before scoping or ordering.";} report=applySurfaceAlignment(report);if(measured&&report.roofGeometry){setDiag("lines","Geometry checked");setStatus("Address-bound measurement candidates are available. Filling the planning report with evidence labels now.","info");}else{setDiag("lines","Planning assumptions");setStatus("The best-available planning result is ready. Unsupported roof geometry and lineals remain labeled for internal review.","info");}return report; }catch(e){if(state.diagnostics.solar==="Waiting")setDiag("solar","Planning assumptions");if(state.diagnostics.lines==="Waiting")setDiag("lines","Planning assumptions");state.measurementError=customerSafeFailure(e);var fallback=buildTwoDimensionalPlanningFallback(address,state.measurementError);if(fallback){clearRecovery();setDiag("solar","Estimated assumptions");setDiag("lines","Internal review");setStatus("Measured evidence was unavailable. Building a broader five-page planning result from the matched property and documented assumptions.","info");return fallback;}setStatus(state.measurementError.message,"warn");showRecovery(state.measurementError);return null;} finally{setBusy(false);} }; var demoReport=function(){ var measurement=OFFICE_BUILDING_MEASUREMENT; var raw={ source:"Illustrative planning example", address:OFFICE_EXAMPLE.address, matchedAddress:OFFICE_EXAMPLE.matchedAddress, lat:measurement.measuredCenter.lat, lng:measurement.measuredCenter.lng, areaSqFt:measurement.surfaceAreaSqFt, rawWholeAreaSqFt:measurement.surfaceAreaSqFt, obstructionPercent:measurement.obstructionPercent, facets:measurement.planes.length, pitchRise:measurement.predominantPitchRise, pitchDegrees:measurement.predominantPitchDegrees, planes:measurement.planes.map(function(plane){return Object.assign({},plane);}), imageryQuality:measurement.imageryQuality, imageryDate:measurement.imageryDate, reportId:measurement.measurementId, structureMatchReliable:true, structureSelectionConfidence:96, areaSelectionBasis:"direct roof-plane surface", topologyBasis:"Address-bound roof planes; property-specific lineal geometry was not released", linealBasis:"not_supplied", lines:null, lineModeled:{}, roofGeometry:null, releaseGate:planningGate() }; var report=unstoppablyCompleteReport(raw,OFFICE_EXAMPLE.address,"Synthetic values demonstrate the report layout only and do not describe a real property."); return Object.assign(report,{ officeExample:false, fullBuilding:false, sampleCandidateId:OFFICE_EXAMPLE.candidateId, validationFixture:true, independentFieldTruth:false, structureFootprintSqFt:measurement.structureFootprintSqFt, rawWholeAreaSqFt:measurement.surfaceAreaSqFt, matchDistanceMeters:null, imageAgeMonths:measurement.imageAgeMonths, imageAgeYears:measurement.imageAgeMonths/12, diagnosticsSource:"Synthetic planning example · no property evidence", reportId:measurement.measurementId, demo:true }); }; var planningGate=function(){var codes=["IDENTITY","IMAGERY_RECENCY","AREA","PITCH","TOPOLOGY","LINEALS","FIELD_OR_PROVIDER_EVIDENCE"];return {status:"NOT_ORDER_READY",orderReady:false,materialOrderingAllowed:false,pdfClassification:"PRELIMINARY_REVIEW_ONLY",requiredCheckCount:codes.length,passedCheckCount:0,blockers:codes.slice(),checks:codes.map(function(code){return {code:code,status:"BLOCKED",passed:false};})};}; var planningRoofGeometry=function(input){return input&&typeof input==="object"&&(Array.isArray(input.lineSegments)||Array.isArray(input.facets))?input:null;}; var unstoppablyCompleteReport=function(source,address,reason){ var raw=source&&typeof source==="object"?source:{};var rawLines=raw.lines&&typeof raw.lines==="object"?raw.lines:{};var rawModeled=raw.lineModeled&&typeof raw.lineModeled==="object"?raw.lineModeled:{};var approvedAddressGeometry=raw.linealBasis==="address_geometry"&&raw.roofGeometry&&typeof raw.roofGeometry==="object"&&Array.isArray(raw.roofGeometry.lineSegments)&&raw.roofGeometry.lineSegments.length>0;var sourceArea=finiteNumber(raw.areaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),sourcePitch=finiteNumber(raw.pitchRise,0,IRV_LIMITS.pitchRise),sourceFacets=finiteNumber(raw.facets,1,IRV_LIMITS.facets);if(sourceArea===null||sourcePitch===null||sourceFacets===null)return {status:"ESTIMATED",planningEstimate:true,measurementEvidence:"estimated",materialOrderingAllowed:false,captureRequired:false,internalEvidenceReview:true,address:address,matchedAddress:raw.matchedAddress||address,measurementRequiredMessage:"BEST-AVAILABLE PLANNING ASSUMPTIONS",areaSqFt:2683.28,canonicalAreaSqFt:2683.28,squares:26.8328,pitchRise:6,facets:6,areaSqFtRange:[1476,3891],squaresRange:[14.76,38.91],pitchRiseRange:[4,8],facetsRange:[2,12],lines:null,linealBasis:"not_supplied",releaseGate:planningGate()};var area=sourceArea;var pitch=sourcePitch;var facets=sourceFacets;var lineKeys=["ridges","hips","valleys","rakes","eaves","dripEdge","flashing","wallFlashing","stepFlashing","parapets"];var lines={};var modeled={};var available={};var sourcePresent={};lineKeys.forEach(function(key){var sourceKey=key==="flashing"?(rawLines.flashing!==undefined?"flashing":"wallFlashing"):(key==="wallFlashing"?(rawLines.wallFlashing!==undefined?"wallFlashing":"flashing"):key);var value=approvedAddressGeometry?finiteNumber(rawLines[sourceKey],0,100000):null;sourcePresent[key]=value!==null;lines[key]=value===null?null:Number(value.toFixed(1));modeled[key]=approvedAddressGeometry&&sourcePresent[key]&&rawModeled[sourceKey]===true;available[key]=sourcePresent[key];});if(approvedAddressGeometry&&lines.eaves!==null&&lines.rakes!==null){lines.dripEdge=Number((lines.eaves+lines.rakes).toFixed(1));sourcePresent.dripEdge=true;modeled.dripEdge=modeled.eaves===true&&modeled.rakes===true;available.dripEdge=true;} var confirmed=raw.structureMatchReliable===true;var hasAddressGeometry=approvedAddressGeometry&&Object.keys(modeled).some(function(key){return modeled[key]===true;});var withheldLinealState={linealBasis:"not_supplied"};var roofGeometry=hasAddressGeometry?planningRoofGeometry(raw.roofGeometry,lines):null; var rawQuality=raw.quality&&typeof raw.quality==="object"?raw.quality:{},rawMetricFrame=rawQuality.metricFrame&&typeof rawQuality.metricFrame==="object"?rawQuality.metricFrame:{}; return { planningEstimate:true,materialOrderingAllowed:false,estimatorDirective:ESTIMATOR_DIRECTIVE.id, planningReason:String(reason||"Best available address-bound evidence was converted into a non-orderable planning result."), source:raw.source||"InstantRoofIQ planning estimator",address:address,matchedAddress:raw.matchedAddress||address, lat:finiteNumber(raw.lat,-90,90)||0,lng:finiteNumber(raw.lng,-180,180)||0, areaSqFt:area,squares:Number((area/100).toFixed(4)),canonicalAreaSqFt:area,rawWholeAreaSqFt:area, rawUnalignedAreaSqFt:finiteNumber(raw.rawUnalignedAreaSqFt,250,IRV_LIMITS.surfaceAreaSqFt), surfaceAlignmentProfile:String(raw.surfaceAlignmentProfile||""), areaAlignmentFactor:finiteNumber(raw.areaAlignmentFactor,.5,2), measurementFormulaVersion:String(raw.measurementFormulaVersion||MEASUREMENT_FORMULA_VERSION), anchorBasis:String(raw.anchorBasis||(confirmed?"address_bound_primary_structure":"unverified_property_binding")), pitchBasis:String(raw.pitchBasis||(Array.isArray(raw.planes)&&raw.planes.length?"address_bound_roof_plane_pitch":"planning_input_pitch")), pitchCalibrationId:raw.pitchCalibrationId==null?null:String(raw.pitchCalibrationId), areaBasis:String(raw.areaBasis||raw.areaSelectionBasis||"planning_input_area"), quality:{metricFrame:{ basis:String(rawMetricFrame.basis||"upstream_not_supplied"), sourceEpsg:Number.isInteger(rawMetricFrame.sourceEpsg)?rawMetricFrame.sourceEpsg:null, horizontalUnits:String(rawMetricFrame.horizontalUnits||"upstream_not_supplied"), correctionApplied:typeof rawMetricFrame.correctionApplied==="boolean"?rawMetricFrame.correctionApplied:null }}, obstructionPercent:finiteNumber(raw.obstructionPercent,0,100), obstructionKnown:finiteNumber(raw.obstructionPercent,0,100)!==null, facets:facets,pitchRise:pitch,pitchDegrees:finiteNumber(raw.pitchDegrees,0,89), planes:Array.isArray(raw.planes)?raw.planes:[],imageryQuality:String(raw.imageryQuality||"UNKNOWN"), imageryDate:raw.imageryDate||"Planning evidence date not supplied",reportId:raw.reportId||reportId("IRV-PLAN"),measurementReceipt:/^[a-f0-9]{64}$/.test(String(raw.measurementReceipt||"").toLowerCase())?String(raw.measurementReceipt).toLowerCase():"", lines:lines,lineVerified:{},lineModeled:modeled,lineAvailable:available, linealBasis:hasAddressGeometry?"address_geometry":withheldLinealState.linealBasis, linealValidation:hasAddressGeometry?(raw.linealValidation&&typeof raw.linealValidation==="object"?raw.linealValidation:{modelId:"address_geometry",trainingSample:0,crossValidationFolds:0,metric:"not_validated",cvWapePct:null,interpretation:"address_geometry_not_a_formula_model",sealedHoldoutPassed:false}):{modelId:"none",trainingSample:0,crossValidationFolds:0,metric:"not_validated",cvWapePct:null,interpretation:"formula_lineals_withheld",sealedHoldoutPassed:false}, structureMatchReliable:confirmed,measurementEvidence:"inferred",evidence:"address_imagery", roofGeometry:roofGeometry,topologyBasis:raw.topologyBasis||"Evidence-labeled planning roof schematic", presentation:raw.presentation||null,historicalImagery:raw.historicalImagery||null, releaseGate:planningGate(),imported:false,demo:false }; }; var buildTwoDimensionalPlanningFallback=function(address,failure){ var preflight=state.preflight&&typeof state.preflight==="object"?state.preflight:{}; var selected=state.chosenStructure&&typeof state.chosenStructure==="object"?state.chosenStructure:{}; var center=selected.center&&typeof selected.center==="object"?selected.center:(preflight.candidateCenter&&typeof preflight.candidateCenter==="object"?preflight.candidateCenter:preflight.point); var lat=finiteNumber(center&¢er.lat,-90,90),lng=finiteNumber(center&&(center.lng!==undefined?center.lng:center.lon),-180,180); if(lat===null||lng===null)return null; var candidateId=String(selected.candidateId||preflight.candidateId||""); if(!/^IRV-S-[A-Z0-9]+$/.test(candidateId))return null; var matched=String(preflight.matchedAddress||address||"Property address awaiting confirmation").slice(0,240); var failureCode=String(failure&&failure.code||"NO_MEASUREMENT").toUpperCase().replace(/[^A-Z0-9_]/g,"_").slice(0,64); var footprint=finiteNumber(selected.groundFootprintSquareFeet!==undefined?selected.groundFootprintSquareFeet:preflight.groundFootprintSquareFeet,250,IRV_LIMITS.planAreaSqFt); var profileInput=Object.assign({},preflight,selected);var profile=planningProfileForStructure(profileInput,footprint); var planArea=Math.min(IRV_LIMITS.planAreaSqFt,Math.max(250,footprint===null?profile.priorPlanAreaSqFt:footprint)); var assumedPitch=Math.max(0,Math.min(IRV_LIMITS.pitchRise,Math.round(profile.pitchRise))); var roofSurface=Math.min(IRV_LIMITS.surfaceAreaSqFt,planArea*Math.sqrt(1+Math.pow(assumedPitch/12,2))); var spread=footprint===null?profile.priorSpread:profile.knownFootprintSpread; var areaLow=Math.max(250,Math.round(roofSurface*(1-spread))); var areaHigh=Math.min(IRV_LIMITS.surfaceAreaSqFt,Math.round(roofSurface*(1+spread))); if(areaHigh<=areaLow)areaHigh=Math.min(IRV_LIMITS.surfaceAreaSqFt,areaLow+100); var surface=Number(roofSurface.toFixed(2)); var facets=Math.max(1,Math.min(IRV_LIMITS.facets,Math.round(profile.facets))); var propertyBindingStatus=preflight.manualMatch===true?"server_bound_candidate_unconfirmed":"server_bound_primary_candidate"; var unresolvedDimensions=["exact_roof_area","exact_pitch","facet_topology","roof_edge_lineals","material_order_quantity"]; return { status:"ESTIMATED",source:"InstantRoofIQ best-available planning result", address:address,matchedAddress:matched,lat:lat,lng:lng,reportId:reportId("IRV-2D"),sampleCandidateId:candidateId, planningEstimate:true,materialOrderingAllowed:false,captureRequired:false,internalEvidenceReview:true,fallback2D:true,rangeAvailable:true, fallbackBasis:footprint===null?"matched_property_profile_prior":"address_bound_footprint_profile_model",fallbackReasonCode:failureCode,propertyBindingStatus:propertyBindingStatus, unresolvedDimensions:unresolvedDimensions,measurementEvidence:"estimated", metricEvidence:{areaSqFt:"planning_assumption",squares:"derived_from_planning_assumption",pitch:"planning_assumption",facets:"planning_assumption"}, areaSqFt:surface,canonicalAreaSqFt:surface,rawWholeAreaSqFt:surface,squares:Number((surface/100).toFixed(4)),pitchRise:assumedPitch,pitchDegrees:null,facets:facets, areaSqFtRange:[areaLow,areaHigh],squaresRange:[Number((areaLow/100).toFixed(4)),Number((areaHigh/100).toFixed(4))],pitchRiseRange:profile.pitchRiseRange.slice(0,2),facetsRange:profile.facetsRange.slice(0,2), propertyPlanningProfile:profile.id,propertyPlanningProfileLabel:profile.label,propertyPlanningProfileBasis:profile.basis, planningAssumptions:{planAreaSqFt:planArea,pitchRisePer12:assumedPitch,complexity:profile.complexity,rangeSpreadPercent:Math.round(spread*100),propertyProfile:profile.id,profileBasis:profile.basis}, imageryQuality:"UNKNOWN",imageryDate:"Best available matched-property evidence",structureMatchReliable:false, structureSelectionConfidence:finiteNumber(preflight.selectionConfidence,0,100),anchorBasis:"address_candidate_center_2d_context_only", topologyBasis:profile.label+" with labeled assumptions; exact roof topology and lineals remain unresolved",linealBasis:"not_supplied", lines:null,lineModeled:{},lineAvailable:{},lineVerified:{},roofGeometry:null,planes:[],releaseGate:planningGate() }; }; var bytesToHex=function(bytes){return Array.from(new Uint8Array(bytes)).map(function(value){return value.toString(16).padStart(2,"0");}).join("");}; var bytesToBase64=function(bytes){var binary="",view=new Uint8Array(bytes),chunk=0x8000;for(var offset=0;offset4000000||String(blob.type).toLowerCase().indexOf("image/jpeg")!==0)return null;var bytes=await blob.arrayBuffer();var addressHash=await sha256Text(address);if(!addressHash)return null;var checksum=bytesToHex(await window.crypto.subtle.digest("SHA-256",bytes));var now=new Date().toISOString();return {verificationMethod:"manual_address_match",verifiedAt:now,capturedAt:capturedAt,addressHash:addressHash,sha256:checksum,jpegBase64:bytesToBase64(bytes)};}catch(error){return null;}finally{if(timer)window.clearTimeout(timer);} }; // Property imagery is acquired by the internal evidence pipeline, never by // the public browser. Planning-PDF creation remains fully functional when // a public-safe visual is unavailable. aerialPropertyVisual=async function(){return null;}; var planningPreviewPayload=async function(report){ var lines=report&&report.lines&&typeof report.lines==="object"?report.lines:{}; var modeled=report&&report.lineModeled&&typeof report.lineModeled==="object"?report.lineModeled:{}; var verified=report&&report.lineVerified&&typeof report.lineVerified==="object"?report.lineVerified:{}; var addressGeometry=report&&report.linealBasis==="address_geometry"&&report.roofGeometry&&typeof report.roofGeometry==="object"?report.roofGeometry:null; var strictPointcloudLineals=report&&report.linealBasis==="roof3d_3dep_pointcloud_wiring"; var handoffLineals={}; if(addressGeometry||strictPointcloudLineals){ [["ridges","ridges"],["hips","hips"],["valleys","valleys"],["rakes","rakes"],["eaves","eaves"],["wallFlashing",lines.wallFlashing!==undefined?"wallFlashing":"flashing"],["stepFlashing","stepFlashing"],["parapets","parapets"]].forEach(function(pair){ if((addressGeometry&&modeled[pair[1]]===true)||(strictPointcloudLineals&&verified[pair[1]]===true)){var value=finiteNumber(lines[pair[1]],0,100000);if(value!==null)handoffLineals[pair[0]]=value;} }); } var handoffBasis=addressGeometry&&Object.keys(handoffLineals).length?"address_geometry":(strictPointcloudLineals&&Object.keys(handoffLineals).length?"roof3d_3dep_pointcloud_wiring":"not_supplied"); var address=String(report&&report.matchedAddress||report&&report.address||fullAddress()||"Property address awaiting confirmation"); var visual=await aerialPropertyVisual(report,address); var estimateStatus=String(report&&report.status||(report&&report.measurementEvidence==="estimated"?"ESTIMATED":(report&&report.measurementEvidence==="measured"?"MEASURED":"NO_MEASUREMENT"))).toUpperCase();var estimateEvidence=report&&["measured","estimated"].indexOf(report.measurementEvidence)>=0?report.measurementEvidence:null;var areaRange=numericRange(report&&report.areaSqFtRange,250,IRV_LIMITS.surfaceAreaSqFt,2),squaresRange=numericRange(report&&report.squaresRange,2.5,IRV_LIMITS.netSquares,4),pitchRange=numericRange(report&&report.pitchRiseRange,0,IRV_LIMITS.pitchRise,0),facetsRange=numericRange(report&&report.facetsRange,1,IRV_LIMITS.facets,0);var payload={address:address,customerName:$("irv2-name").value.trim()||"Property owner",propertyMatched:false,estimate:{status:estimateStatus,measurementEvidence:estimateEvidence,planningEstimate:true,materialOrderingAllowed:false,measurementMode:String(report&&report.measurementMode||"").slice(0,80),areaSqFt:report&&report.areaSqFt===null?null:report&&report.areaSqFt,squares:report&&report.squares===null?null:report&&report.squares,pitch:wholePitchRise(report&&report.pitchRise),facets:report&&report.facets===null?null:report&&report.facets,areaSqFtRange:areaRange?areaRange.slice(0,2):null,squaresRange:squaresRange?squaresRange.slice(0,2):null,pitchRiseRange:pitchRange?pitchRange.slice(0,2):null,facetsRange:facetsRange?facetsRange.slice(0,2):null,metricEvidence:report&&report.metricEvidence&&typeof report.metricEvidence==="object"?report.metricEvidence:{},lineals:handoffLineals,linealBasis:handoffBasis,imageQuality:String(report&&report.imageryQuality||"not_recorded").toLowerCase(),roofGeometry:handoffBasis==="address_geometry"?addressGeometry:null}}; var selected=state.chosenStructure&&typeof state.chosenStructure==="object"?state.chosenStructure:{}; var selectedCenter=selected.center&&typeof selected.center==="object"?selected.center:{}; var selectedLat=finiteNumber(selectedCenter.lat,-90,90),selectedLng=finiteNumber(selectedCenter.lng!==undefined?selectedCenter.lng:selectedCenter.lon,-180,180); var selectedCandidateId=String(selected.candidateId||""),selectedBindingToken=String(selected.structureBindingToken||""); if(/^IRV-S-[A-Z0-9]+$/.test(selectedCandidateId)&&selectedLat!==null&&selectedLng!==null&&validStructureBindingToken(selectedBindingToken)){ payload.candidateId=selectedCandidateId; payload.candidateLat=selectedLat; payload.candidateLng=selectedLng; payload.structureBindingToken=selectedBindingToken; } var measurementReceipt=String(report&&report.measurementReceipt||"").toLowerCase(); if(/^[a-f0-9]{64}$/.test(measurementReceipt))payload.measurementReceipt=measurementReceipt; if(report&&report.fallback2D===true){ payload.estimate.fallback2D=true; payload.estimate.rangeAvailable=report.rangeAvailable!==false&&areaRange!==null; payload.estimate.captureRequired=false; payload.estimate.internalEvidenceReview=true; payload.estimate.propertyBindingStatus=String(report.propertyBindingStatus||"address_candidate_unverified").slice(0,64); payload.estimate.unresolvedDimensions=Array.isArray(report.unresolvedDimensions)?report.unresolvedDimensions.slice(0,5):[]; payload.estimate.fallbackReasonCode=String(report.fallbackReasonCode||"NO_MEASUREMENT").slice(0,64); } var rawArea=finiteNumber(report&&report.rawUnalignedAreaSqFt,250,IRV_LIMITS.surfaceAreaSqFt),factor=finiteNumber(report&&report.areaAlignmentFactor,.5,2),profile=String(report&&report.surfaceAlignmentProfile||""),formula=String(report&&report.measurementFormulaVersion||""); if(rawArea!==null&&factor!==null&&/^[A-Za-z0-9][A-Za-z0-9._:-]{0,79}$/.test(profile)&&/^[A-Za-z0-9][A-Za-z0-9._:-]{0,79}$/.test(formula)){payload.estimate.rawUnalignedAreaSqFt=rawArea;payload.estimate.areaFactorApplied=factor;payload.estimate.surfaceAlignmentProfile=profile;payload.estimate.measurementFormulaVersion=formula;} if(visual)payload.propertyVisual=visual; return payload; }; var planningPreviewEndpoint=function(report){ var evidence=String(report&&report.measurementEvidence||"").toLowerCase(); var status=String(report&&report.status||"").toUpperCase(); var estimated=!!(report&&(report.fallback2D===true||evidence==="estimated"||status==="ESTIMATED")); if(estimated){if(!API.planningPreview)throw new Error("Estimated planning PDF delivery is not configured.");return API.planningPreview;} var receipt=String(report&&report.measurementReceipt||"").toLowerCase(); if(evidence==="measured"&&/^[a-f0-9]{64}$/.test(receipt)){if(!API.verifiedPreview)throw new Error("Verified planning PDF delivery is not configured.");return API.verifiedPreview;} throw new Error("A verified measurement receipt or an estimated property result is required before PDF creation."); }; var createPlanningPreviewPdf=async function(report){ var endpoint=planningPreviewEndpoint(report);var payload=await planningPreviewPayload(report); if(endpoint===API.planningPreview){payload={address:payload.address,customerName:payload.customerName,candidateId:payload.candidateId,candidateLat:payload.candidateLat,candidateLng:payload.candidateLng,structureBindingToken:payload.structureBindingToken};} return postJson(endpoint,payload,30000); }; var validEvidenceJobId=function(value){return /^job_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(String(value||"").toLowerCase());}; var validEvidenceTrackingToken=function(value){return /^[A-Za-z0-9_-]{32,64}$/.test(String(value||""));}; var normalizeEvidenceStatusPayload=function(payload,jobId){ if(!payload||typeof payload!=="object"||payload.schema!=="instantroofview/assessment-status-v1"||String(payload.assessmentId||"").toLowerCase()!==jobId)return null; var status=String(payload.status||"").toUpperCase(),release=String(payload.measurementRelease||"").toUpperCase(),action=String(payload.nextAction||"").toUpperCase(); if(["QUEUED","PROCESSING","REVIEW_REQUIRED","REPORT_READY","UNAVAILABLE"].indexOf(status)<0||["NOT_RELEASED","INDEPENDENTLY_REVIEWED","ESTIMATED","UNAVAILABLE"].indexOf(release)<0||["WAIT","REVIEW","OPEN_REPORT","CONTACT_OFFICE","NONE"].indexOf(action)<0||typeof payload.reportAvailable!=="boolean")return null; if(status!=="REPORT_READY"&&(payload.reportAvailable===true||release==="INDEPENDENTLY_REVIEWED"||action==="OPEN_REPORT"))return null; if(status==="REPORT_READY"&&(payload.reportAvailable!==true||release!=="INDEPENDENTLY_REVIEWED"||action!=="OPEN_REPORT"))return null; return {schema:"instantroofview/assessment-status-v1",assessmentId:jobId,status:status,reportAvailable:payload.reportAvailable,measurementRelease:release,nextAction:action}; }; var requestEvidenceStatus=async function(jobId,trackingToken){ jobId=String(jobId||"").toLowerCase();trackingToken=String(trackingToken||""); if(!validEvidenceJobId(jobId)||!validEvidenceTrackingToken(trackingToken)||!API.evidenceStatus)return null; var controller=typeof AbortController!=="undefined"?new AbortController():null;var timer=controller?window.setTimeout(function(){controller.abort();},8000):0; try{ var options={method:"GET",headers:{Accept:"application/json","x-instantroofiq-tracking-token":trackingToken},cache:"no-store",credentials:"same-origin",redirect:"error",referrerPolicy:"same-origin"};if(controller)options.signal=controller.signal; var response=await fetch(API.evidenceStatus+"?assessmentId="+encodeURIComponent(jobId),options);var text=await response.text();if(!response.ok||text.length>16384)return null;var payload;try{payload=JSON.parse(text);}catch(e){return null;}return normalizeEvidenceStatusPayload(payload,jobId); }catch(e){return null;}finally{if(timer)window.clearTimeout(timer);} }; var renderEvidenceStatus=function(payload){ var track=$("irv2-evidence-track"),note=$("irv2-evidence-status");if(!track||!note)return; var labels={QUEUED:"Review queued",PROCESSING:"Review in progress",REVIEW_REQUIRED:"Review complete · office confirmation next",REPORT_READY:"Review complete",UNAVAILABLE:"Review status unavailable"};var label=labels[payload&&payload.status]||"Review queued"; track.hidden=false;track.disabled=false;track.textContent=payload&&["REVIEW_REQUIRED","REPORT_READY"].indexOf(payload.status)>=0?"Review status received":"Check review status";note.textContent=label+". Your immediate planning result and five-page report remain available.";note.hidden=false; }; var refreshEvidenceStatus=async function(announce){ var jobId=state.evidenceJobId,trackingToken=state.evidenceTrackingToken;if(!validEvidenceJobId(jobId)||!validEvidenceTrackingToken(trackingToken))return null;state.evidencePollCount+=1; var payload=await requestEvidenceStatus(jobId,trackingToken);if(jobId!==state.evidenceJobId||trackingToken!==state.evidenceTrackingToken)return null; if(payload){state.evidenceStatus=payload.status;renderEvidenceStatus(payload);if(payload.status==="QUEUED"||payload.status==="PROCESSING")scheduleEvidenceStatusPoll(8000);return payload;} if(announce){var note=$("irv2-evidence-status");note.textContent="Review status could not be refreshed. Your immediate planning result and five-page report remain available.";note.hidden=false;}if(state.evidencePollCount<30)scheduleEvidenceStatusPoll(12000);return null; }; var scheduleEvidenceStatusPoll=function(delay){if(state.evidencePollTimer)window.clearTimeout(state.evidencePollTimer);if(state.evidencePollCount>=30||["REVIEW_REQUIRED","REPORT_READY","UNAVAILABLE"].indexOf(state.evidenceStatus)>=0)return;state.evidencePollTimer=window.setTimeout(function(){state.evidencePollTimer=0;void refreshEvidenceStatus(false);},delay);}; var applyEvidenceTracking=function(payload){ if(!payload||payload.schema!=="instantroofview/assessment-submit-result-v1"||payload.accepted!==true)return false; var jobId=String(payload.assessmentId||"").toLowerCase(),trackingToken=String(payload.trackingToken||"");if(!validEvidenceJobId(jobId)||!validEvidenceTrackingToken(trackingToken))return false; state.evidenceJobId=jobId;state.evidenceTrackingToken=trackingToken;state.evidenceStatus=String(payload.status||"QUEUED").toUpperCase()==="PROCESSING"?"PROCESSING":"QUEUED";state.evidencePollCount=0;renderEvidenceStatus({status:state.evidenceStatus});scheduleEvidenceStatusPoll(1000);return true; }; var queueEvidenceRefinement=async function(report){ if(LEAD_CONFIG.preview||!API.evidenceQueue)return null; var address=String(report&&report.matchedAddress||report&&report.address||fullAddress()||"").trim(); if(address.length<8||address.length>180)return null; var selected=state.chosenStructure&&typeof state.chosenStructure==="object"?state.chosenStructure:{};var center=selected.center&&typeof selected.center==="object"?selected.center:{};var candidateId=String(selected.candidateId||state.preflight&&state.preflight.candidateId||"");var token=String(selected.structureBindingToken||"");var lat=finiteNumber(center.lat,-90,90),lng=finiteNumber(center.lng,-180,180);if(!/^IRV-S-[A-Z0-9]+$/.test(candidateId)||!validStructureBindingToken(token)||lat===null||lng===null)return null; try{return await postJson(API.evidenceQueue,{address:address,candidateId:candidateId,candidateLat:lat,candidateLng:lng,structureBindingToken:token},10000);}catch(e){return null;} }; var hasContactForFollowup=function(){var name=$("irv2-name").value.trim(),phone=$("irv2-phone").value.trim(),email=$("irv2-email").value.trim();var phoneOk=phone.replace(/\D/g,"").length>=10,emailOk=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);/* consent is required; one reachable contact method is enough - requiring BOTH silently discarded consented leads that gave only an email */return $("irv2-consent").checked&&name.length>=2&&(phoneOk||emailOk);}; var leadTracking=function(){var params=new URLSearchParams(window.location.search);return {source:params.get("utm_source")||"direct",medium:params.get("utm_medium")||"website",campaign:params.get("utm_campaign")||"instant-roof-view",content:params.get("utm_content")||"",landingPage:window.location.href,referrer:document.referrer||""};}; var submitLead=async function(lead){ if(LEAD_CONFIG.preview)return {preview:true,reportAvailable:false,downloadUrl:null,expiresAt:null}; if(!API.lead)throw new Error("Lead delivery is not configured."); return postJson(API.lead,lead,12000); }; var createAndEmailPdf=async function(){ clearRecovery(); if(!validateIntake()){setJourneyStep(1);return;} var name=$("irv2-name").value.trim();var phone=$("irv2-phone").value.trim();var email=$("irv2-email").value.trim();var address=state.preflight&&state.preflight.matchedAddress||fullAddress()||'Property address awaiting confirmation';var manualRoute=state.manualMatch===true&&state.preflight&&state.preflight.manualMatch===true; if(!state.preflight){setStatus("No blocker. Start the estimator once and we will create the report with the best available evidence.","info");setJourneyStep(1);return;} state.visibility="AUTO_DETECTED";var consentChecked=$("irv2-consent").checked;var smsChecked=$("irv2-sms-consent").checked;var smsEligible=smsChecked&&consentChecked&&phone.replace(/\D/g,"").length>=10; state.lead={name:name,phone:phone,email:email,address:address,treeCover:null,roofVisibility:state.visibility,propertyConfirmed:manualRoute?false:true,manualMatchRequired:manualRoute,website:$("irv2-website").value,consent:consentChecked,consentText:consentChecked?CONTACT_CONSENT_TEXT:"",smsOptin:smsEligible,smsOptinText:smsEligible?SMS_CONSENT_TEXT:"",photoCount:0,createdAt:new Date().toISOString(),tracking:leadTracking()}; state.leadDelivered=false;state.report=null;clearStructureSelection();clearPdfLink();$("irv2-report").classList.remove("active");var webDetails=$("irv2-web-details");webDetails.open=false;webDetails.hidden=true; if(LEAD_CONFIG.preview){render(demoReport());showPdfNote("Offline preview: the private roof report PDF is intentionally unavailable, and no address, lead, or measurement request was sent.");setStatus("Offline preview ready. All values are deterministic demo data; no address lookup, lead delivery, or measurement network call occurred.","info");return;} if(state.workflowActive)return; state.workflowActive=true;state.workflowDeadlineMs=Date.now()+WORKFLOW_BUDGET_MS;state.workflowRequestId=newWorkflowRequestId(); var measurementReport=null; try{ setBusy(true);setStatus("Reviewing the matched property and available evidence…","info");measurementReport=await measure(address,manualRoute);if(!measurementReport){setStatus(state.measurementError&&state.measurementError.message||REFUSAL_MESSAGES.NO_MEASUREMENT,"warn");return;}var completeness=customerPdfCompleteness(measurementReport);var measurementSummary=completeness.ready?buildMeasurementSummary(measurementReport):null;if(completeness.ready&&!measurementSummary){completeness={ready:false,blockers:["SERVER_HANDOFF_CONTRACT"]};} var reportForCustomer=measurementReport; var detectedObstruction=finiteNumber(reportForCustomer&&reportForCustomer.obstructionPercent,0,100);state.lead.treeCover=detectedObstruction===null?null:detectedObstruction>=HISTORICAL_IMAGERY_TRIGGER_PERCENT;state.lead.roofVisibility=detectedObstruction===null?"AUTO_DETECTED_UNKNOWN":(detectedObstruction>=HISTORICAL_IMAGERY_TRIGGER_PERCENT?"AUTO_DETECTED_HEAVY_OBSTRUCTION":"AUTO_DETECTED_USABLE");var historicalContext=normalizeHistoricalContext(reportForCustomer&&reportForCustomer.historicalImagery);state.lead.historicalImageryStatus=historicalContext?historicalContext.status:"NOT_TRIGGERED";var canonicalMatchedAddress=String(measurementReport.matchedAddress||"").trim();if(canonicalMatchedAddress.length>=8&&canonicalMatchedAddress.length<=220)state.lead.address=canonicalMatchedAddress; render(reportForCustomer);setBusy(true);var evidenceReviewPromise=queueEvidenceRefinement(reportForCustomer); var delivery=null;var followupDelivery=null;var contactReady=hasContactForFollowup(); if(completeness.ready&&contactReady){setStatus("Verified measurements are ready. Creating the signed five-page report…","info");delivery=await submitLead(state.lead);state.leadDelivered=true;if(!(delivery&&delivery.reportAvailable===true)){delivery=await createPlanningPreviewPdf(reportForCustomer);}}else{if(contactReady){try{followupDelivery=await submitLead(state.lead);state.leadDelivered=true;}catch(leadError){setStatus("Your planning report is still being created. Contact follow-up could not be confirmed yet.","warn");}}setStatus("Creating your evidence-labeled five-page planning PDF…","info");delivery=await createPlanningPreviewPdf(reportForCustomer);} if(delivery&&typeof delivery.reviewId==="string"&&/^[A-Z0-9][A-Z0-9-]{5,39}$/.test(delivery.reviewId)){reportForCustomer.reportId=delivery.reviewId;$("irv2-reportid").textContent=delivery.reviewId;} var pdfReady=applyPdfResponse(delivery);var evidencePayload=await evidenceReviewPromise;var evidenceQueued=applyEvidenceTracking(evidencePayload);var emailConfirmed=(delivery&&delivery.acknowledgementSent===true)||(followupDelivery&&followupDelivery.acknowledgementSent===true);if(pdfReady){var greeting=name?"Thanks, "+name+". ":"";setStatus(greeting+(completeness.ready?"Your verified five-page roof PDF is ready below.":"Your evidence-labeled five-page planning PDF is ready below; unsupported roof-edge rows remain internal review items.")+(evidenceQueued?" Evidence refinement is queued for internal review.":"")+(emailConfirmed?" A follow-up acknowledgement was emailed.":""),emailConfirmed?"good":"info");}else{setStatus("Your planning result remains visible on this page. The private PDF link could not be displayed in this browser."+(evidenceQueued?" Evidence refinement is queued for internal review.":""),"warn");} }catch(error){var workflowFailure=customerSafeFailure(error);setStatus(customerSafeWorkflowFailure(error),"warn");showRecovery(workflowFailure);} finally{setBusy(false);state.workflowActive=false;state.workflowDeadlineMs=0;state.workflowRequestId="";} }; $("irv2-form").addEventListener("submit",async function(e){e.preventDefault();if(state.journeyStep===1){await previewAddress();return;}await createAndEmailPdf();}); $("irv2-recovery-retry").addEventListener("click",async function(){ var retry=$("irv2-recovery-retry"); retry.disabled=true;retry.setAttribute("aria-busy","true");retry.textContent="Retrying…"; try{ if(!state.runtimeReady)await loadAppReadiness(); if(!state.runtimeReady)return; clearRecovery(); if(state.preflight)await createAndEmailPdf(); else if(fullAddress())await previewAddress(); else{focusAddress();setStatus("Enter the property address, then run the property check.","info");} }finally{retry.disabled=false;retry.setAttribute("aria-busy","false");retry.textContent=state.preflight?"Retry roof measurement":"Retry property check";} }); $("irv2-delivery-print").addEventListener("click",printPdf); $("irv2-evidence-track").addEventListener("click",function(){void refreshEvidenceStatus(true);}); $("irv2-roofer-qs-copy").addEventListener("click",copyRooferChecklist); $("irv2-roofer-qs-print").addEventListener("click",printRooferChecklist); var showOfficeExample=async function(){clearRecovery();clearPdfLink();var report=demoReport();render(report);revealReport(true);showPdfNote("Illustrative example: no address lookup, property evidence, lead, map, or PDF request was sent.");setStatus("Illustrative planning example ready. These synthetic values do not describe a real property.","info");}; $("irv2-demo").addEventListener("click",function(){showOfficeExample();}); $("irv2-mobile-demo").addEventListener("click",function(){$("irv2-demo").click();}); ["irv2-address","irv2-city","irv2-state","irv2-zip"].forEach(function(id){$(id).addEventListener("input",invalidatePropertySelection);}); $("irv2-reset").addEventListener("click",function(){state.report=null;state.lead=null;state.leadDelivered=false;state.propertyConfirmed=null;state.preflight=null;state.manualMatch=false;state.visibility="";state.measurementError=null;invalidatePropertySelection();$("irv2-form").reset();resetAddress();clearRecovery();clearPdfLink();renderRoofPlan(null,"");renderHistoricalContext(null);renderMeasuredBridge(null);$("irv2-report").classList.remove("active");var webDetails=$("irv2-web-details");webDetails.open=false;webDetails.hidden=true;$("irv2-map").removeAttribute("src");$("irv2-map").hidden=true;$("irv2-map-placeholder").hidden=false;$("irv2-status").setAttribute("aria-hidden","true");setJourneyStep(1);focusAddress();window.scrollTo({top:root.offsetTop,behavior:"smooth"});}); })();

    How we measure · updated 2026-08-17 17:54 UTC

    Every roof, measured from several independent sources

    We never rely on one reading. A property is measured from aerial LiDAR, its building footprint, and any commercial report available, then combined so the sources check each other. When they disagree, the published range widens — disagreement is never averaged away.

    Independent agreement8.19% median

    Across 553 Georgia properties compared against commercial roof reports. 85.2% landed within 20%.

    MEASURED, n=553
    Typical pitch0.3 rise-per-12

    Typical difference from the reference report. 73.4% agree within 1 rise-per-12.

    MEASURED
    3D roof modelsBuilt from LiDAR

    Real triangulated models generated from classified airborne returns, not artist impressions.

    LIVE
    Every reportFive pages, always

    Every measurement carries its range and the sources behind it. Nothing is presented as surveyed truth.

    LIVE

    What these numbers are, precisely. They describe how closely our measurements agree with commercial roof reports (the kind adjusters settle against). That is a real, large-sample comparison — and it is not a tape measure. No roof in that comparison was measured by hand on site, so we do not claim certified physical accuracy. Every report says so on its own evidence page.

    Measurement sources

    What is feeding a measurement today

    LIVEInspector Roofing structure gateway (owner-operated)

    Live today on the site's own authenticated route; returns ranked structure candidates with ground footprints and an address-point containment test.

    LIVEUS Census geocoder

    Address -> coordinates. Public, keyless. Known to land on road centerlines for private drives.

    LIVEOpenStreetMap building footprint

    Community-mapped building polygons via Overpass. Coverage varies; absent is reported as absent.

    LIVEUSGS 3DEP elevation

    Public national elevation service; used as an independent height cross-check.

    LIVEMicrosoft open building footprints

    Open ML-derived footprints; used only when a local extract is staged.

    AWAITING KEYGoogle Solar API (buildingInsights)

    Returns per-facet pitch, azimuth and area for many US addresses. Strongest keyed source for pitch cross-checks.

    AWAITING KEYHover

    Photogrammetry from a capture; treated as high-weight when a job exists for the address.

    AWAITING KEYRoofr

    Report-based measurements.

    AWAITING KEYRoofSnap

    Report-based measurements.

    A source without credentials contributes nothing to a measurement and is never counted as agreement.

    Independent product scorecard · v25 (BETA 5, audited)

    We grade ourselves out of 1,000 — in public

    727/ 1000  ·  v23 686 → v24 691 → v25 718 → v25.1 727
    Equal-weight mean of 9 scored areas; validated measurement accuracy excluded as N/A.
    Validated measurement accuracyN/A — not validated

    Measured agreement with commercial provider reports across 553 properties. Uncalibrated engine (the non-circular measurement): 8.19% median absolute area error, 85.2% within 20%. Shipping engine (what a report prints): 7.83% and 85.7%. Typical pitch error 0.3 rise-per-12 on both. Re-runnable: uv run python -m app.calibration Remaining gate: Stays N/A. The rubric requires signed on-roof physical audits; provider reports are explicitly not promotable to field truth. 0 roofs field-measured. Against the bars (area WAPE <3%, pitch within 0.5/12 on >=90%), today's engine is 2.7x over on area and at 63.6% on pitch — collecting the cohort now would score RUNG 0, so close the gap before spending a one-shot sealed cohort.

    Property association and coverage430 / 1000  ▲50

    Structure gateway with address-point containment; the orchestrator now READS the anchor and re-anchors the LiDAR crop when a candidate contains the address point — closing the program's signature 'computed but never read' defect class. Reachable via POST /v1/measure. Remaining gate: Signed v3 place/parcel/footprint contract still absent. Re-anchoring is proven on 1 property and depends on a live gateway with no fallback. Next artifact: persist gateway payloads across N>=20 addresses including known-wrong-geocode negative controls.

    3D completeness and truthfulness800 / 1000  ▲100

    First real LiDAR-derived 3D result in program history: 1,823-triangle mesh from 1,028 vertices, glTF 2.0 GLB independently re-parsed (chunks aligned, indices in range, zero degenerate triangles, recomputed area matches). Now wired into the product path, so the report renders real faces rather than a bare point cloud. Remaining gate: B4 now PASSES 8/8 on 6740 (collection date 2019-04-17 resolved to the day from GPS time in the point records; release_gate_pass True, orderable). The stated blocker is void. Remaining: n=1 property, and the raise below is NOT yet adversarially audited.

    Truth, provenance, cloud recoverability570 / 1000  ▲40

    sha256 pre-read tile verification with a typed failure vocabulary; the manifest size-drift trap documented (would have false-rejected the whole 409G vault); every reading carries a derived-sigma method string; the circular accuracy feedback loop is closed — the engine now reads a reviewed frozen snapshot, so re-running the harness can no longer silently change published claims. Remaining gate: No offsite backup and no restore drill. Cloud checksum verification unproven.

    Five-page report completeness985 / 1000  ▲10

    Always five Letter pages with a band on every metric and a new Evidence & Confidence page; rendered 3D from real mesh faces. Remaining gate: The measured-3D result now passes B4, so a passing fixture is reachable. Facet error is 50% median (the 75% figure was partly a corpus ceiling: ga_all_3d caps at 5 facets against an EagleView mean of 13.1). Tier-1 lineals now FIRE, on 29% of clouds at 37-88% WAPE — far from the 5% bar. Raise NOT yet adversarially audited.

    Public usability, aesthetics, human compatibility950 / 1000  ▲20

    Streaming chat with route receipts, tool timeline with inline approvals, conversation persistence/search/export, prompt library, usage card, three-state readiness ladder — all live, reachable routes. Remaining gate: Moderated homeowner/estimator studies and a full assistive-technology audit.

    Speed760 / 1000

    No change. There is no timing instrumentation in the measurement path. Remaining gate: Rejected on audit: a single ~1,000-point crop is not product speed, and the figure sits inside a range v23 already counted. Needs real instrumentation, a production SLO, and load-test history.

    Reliability and observability680 / 1000  ▲20

    Usage accounting that cannot break a completion, typed failure vocabularies, in-band stream errors with guaranteed termination, Scout ledger. 279 automated tests green. Remaining gate: Own-tests-marking-own-homework is not product reliability. Production dashboards and sustained end-to-end monitoring absent; accuracy telemetry has been dead since 2026-08-07.

    Security, privacy, recovery720 / 1000  ▲30

    Pairing-token auth with no loopback trust; SSRF default-deny including the tailnet CGNAT range; approval boundary with execution-time re-check and revision pinning; 0600 credential storage; clean secret scan. Remaining gate: Restore proof still absent.

    Qwen estimator usefulness650 / 1000  ▲60

    The operator UI half of the gate is closed and reachable: 8-agent supervised roster with grounding enforcement, tools-in-chat that search and cite, approval-gated proposals, prompt library. Remaining gate: The usefulness-evaluation half is open. Needs a recorded, replayable evaluation over K>=10 real estimator tasks with a non-mutation assertion.

    Measurement accuracy stays marked "not validated" on purpose. Our own rubric requires signed on-roof physical audits, and we have completed none. Agreement with commercial reports is a weaker claim, so it is published separately above rather than folded into this score. These v25 numbers were adversarially audited before publication and most of the increases we proposed were rejected.

    Generated from the InstantRoofIQ BETA 5 core on Inspector Roofing's own hardware · 2026-08-17 19:52 UTC · Fast lane qwen2.5:7b, Deep Think deepseek-r1:8b, both running locally.

    Roofing services & areas around North Metro Atlanta, GA

    Watch: Residential Roof Replacement in Alpharetta, GA | Inspector Roofing

    Residential Roof Replacement in Alpharetta, GA | Inspector Roofing