1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[64963,66087],{14014:(e,t,i)=>{function n(e){let t=e.replace(/0[xX]/g,"").replace(/[\s,:_-]/g,"");if(!t)return{bytes:new Uint8Array(0),error:null};let i=t.match(/[^0-9a-fA-F]/);if(i)return{bytes:new Uint8Array(0),error:`"${i[0]}" is not a hex digit. Hex runs 0 to 9 and A to F.`};if(t.length%2!=0)return{bytes:new Uint8Array(0),error:`Hex comes in pairs and this has ${t.length} digits, so one is missing.`};let n=new Uint8Array(t.length/2);for(let e=0;e<n.length;e++)n[e]=parseInt(t.slice(2*e,2*e+2),16);return{bytes:n,error:null}}function r(e,t=""){let i=[];for(let t of e)i.push(t.toString(16).padStart(2,"0"));return i.join(t)}function a(e,t){let i=Math.min(e.length,t),n=[];for(let t=0;t<i;t+=16){let r=e.subarray(t,Math.min(t+16,i)),a="",s="";for(let e=0;e<16;e++)if(a+=e<r.length?`${r[e].toString(16).padStart(2,"0")} `:" ",7===e&&(a+=" "),e<r.length){let t=r[e];s+=t>=32&&t<127?String.fromCharCode(t):"."}n.push(`${t.toString(16).padStart(8,"0")} ${a} |${s}|`)}return n.join("\n")}function s(e){let t=0;for(let i of e)(127===i||i<32&&9!==i&&10!==i&&13!==i)&&t++;return t}function o(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}i.d(t,{XA:()=>o,_Q:()=>n,ek:()=>a,nj:()=>r,w4:()=>s})},64963:(e,t,i)=>{i.d(t,{ED:()=>D,EX:()=>E,Fh:()=>R,GB:()=>s,Jh:()=>F,Tz:()=>p,_z:()=>H,f0:()=>P,fm:()=>g,jD:()=>S,oH:()=>U,readDensities:()=>T,withDensity:()=>L,yo:()=>W});var n=i(14014);function r(e){return Math.round(e/.0254)}function a(e){return .0254*e}function s(e,t){let i=Math.pow(10,t);return Math.round(e*i)/i}function o(e,t,i){e[t]=i>>8&255,e[t+1]=255&i}function l(e,t,i){e[t]=i>>>24&255,e[t+1]=i>>>16&255,e[t+2]=i>>>8&255,e[t+3]=255&i}function h(e,t){let i=e[t],n=e[t+1];return void 0===i||void 0===n?-1:i<<8|n}function u(e,t){let i=e[t],n=e[t+1],r=e[t+2],a=e[t+3];return void 0===i||void 0===n||void 0===r||void 0===a?-1:(i<<24|n<<16|r<<8|a)>>>0}function d(e,t,i){let n=e[t],r=e[t+1];return void 0===n||void 0===r?-1:i?r<<8|n:n<<8|r}function c(e,t,i){let n=e[t],r=e[t+1],a=e[t+2],s=e[t+3];return void 0===n||void 0===r||void 0===a||void 0===s?-1:i?(s<<24|a<<16|r<<8|n)>>>0:(n<<24|r<<16|a<<8|s)>>>0}function m(e,t,i,n){n?(e[t]=255&i,e[t+1]=i>>>8&255,e[t+2]=i>>>16&255,e[t+3]=i>>>24&255):l(e,t,i)}function f(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(e[i]!==t[i])return!1;return!0}function p(e){let t=t=>t<e.length?e[t]??-1:-1;if(255===t(0)&&216===t(1))return"jpeg";if(137===t(0)&&80===t(1)&&78===t(2)&&71===t(3))return"png";if(66===t(0)&&77===t(1))return"bmp";if(71===t(0)&&73===t(1)&&70===t(2))return"gif";if(82===t(0)&&73===t(1)&&70===t(2)&&70===t(3)&&87===t(8))return"webp";if(73===t(0)&&73===t(1)&&42===t(2)||77===t(0)&&77===t(1)&&42===t(3))return"tiff";if(102===t(4)&&116===t(5)&&121===t(6)&&112===t(7)){let e=String.fromCharCode(t(8),t(9),t(10),t(11));return e.startsWith("avif")||e.startsWith("avis")?"avif":"heic"}return"unknown"}let g={jpeg:"JPEG",png:"PNG",bmp:"BMP",webp:"WebP",gif:"GIF",tiff:"TIFF",heic:"HEIC",avif:"AVIF",unknown:"unrecognized file"},x=[74,70,73,70,0];function y(e,t,i){for(let n=0;n<i.length;n++)if(e[t+n]!==i.charCodeAt(n))return!1;return!0}function w(e){let t={iccRanges:[],truncated:!1};if(255!==e[0]||216!==e[1])return t;let i=2;for(;i+3<e.length&&255===e[i];){;let n=e[i+1];if(void 0===n)break;if(216===n||1===n||n>=208&&n<=215){i+=2;continue}if(218===n)return t.sosAt=i,t;if(217===n)return t;let r=h(e,i+2);if(r<2||i+2+r>e.length)break;224===n&&r>=16&&function(e,t){for(let i=0;i<x.length;i++)if(e[t+4+i]!==x[i])return!1;return!0}(e,i)&&void 0===t.jfifAt?(t.jfifAt=i,t.jfifLen=r):225===n&&void 0===t.exifAt&&y(e,i+4,"Exif\0\0")?(t.exifAt=i,t.exifLen=r,t.tiffAt=i+10):237===n&&void 0===t.app13At&&y(e,i+4,"Photoshop 3.0\0")?(t.app13At=i,t.app13Len=r):226===n&&y(e,i+4,"ICC_PROFILE\0")?t.iccRanges.push({start:i,end:i+2+r}):n>=192&&n<=207&&196!==n&&200!==n&&204!==n&&void 0===t.sofAt&&(t.sofAt=i),i+=2+r}return t.truncated=!0,t}let b=[137,80,78,71,13,10,26,10];function v(e){let t=[];for(let i=0;i<b.length;i++)if(e[i]!==b[i])return{chunks:t,truncated:!0};let i=8;for(;i+8<=e.length;){let n=u(e,i);if(n<0||i+12+n>e.length)break;
1let r=String.fromCharCode(e[i+4]??0,e[i+5]??0,e[i+6]??0,e[i+7]??0);if(t.push({type:r,at:i,len:n}),"IEND"===r)return{chunks:t,truncated:!1};i+=12+n}return{chunks:t,truncated:!0}}let k=null;function M(e){if(!k){let e=new Uint32Array(256);for(let t=0;t<256;t++){let i=t;for(let e=0;e<8;e++)i=1&i?0xedb88320^i>>>1:i>>>1;e[t]=i>>>0}k=e}let t=0xffffffff;for(let i=0;i<e.length;i++){let n=e[i];void 0!==n&&(t=((k[(t^n)&255]??0)^t>>>8)>>>0)}return(0xffffffff^t)>>>0}function j(e,t,i){if(t+8>e.length||i<8)return null;let n=e[t],r=73===n;if(!r&&77!==n||42!==d(e,t+2,r))return null;let a=c(e,t+4,r);if(a<8||a+2>i)return null;let s={little:r},o=d(e,t+a,r);if(o<0||o>512)return null;for(let n=0;n<o;n++){let o=t+a+2+12*n;if(o+12>t+i||o+12>e.length)break;let l=d(e,o,r);if(282===l||283===l){let n=d(e,o+2,r),a=c(e,o+4,r);if(5!==n||1!==a)continue;let h=c(e,o+8,r),u=t+h;if(h<8||h+8>i||u+8>e.length)continue;let m=c(e,u,r),f=c(e,u+4,r),p=f>0?m/f:void 0;282===l?(s.xAt=u,s.x=p):(s.yAt=u,s.y=p)}else if(296===l){if(3!==d(e,o+2,r))continue;s.unitAt=o+8,s.unit=d(e,o+8,r)}}return void 0===s.xAt&&void 0===s.yAt&&void 0===s.unitAt?null:s}function $(e,t,i){let n=Math.min(t+2+i,e.length),r=t+4+14;for(;r+12<=n&&y(e,r,"8BIM");){let t=h(e,r+4),i=r+6,a=e[i];if(void 0===a||(i+=1+a,(1+a)%2==1&&(i+=1),i+4>n))break;let s=u(e,i);if(s<0)break;let o=i+4;if(o+s>n)break;if(1005===t&&s>=16)return{at:o,h:u(e,o)/65536,v:u(e,o+8)/65536};r=o+s+s%2}return null}let N={jfif:"JFIF header",exif:"EXIF resolution tags",photoshop:"Photoshop resolution block",phys:"pHYs chunk",bmp:"BMP header"},P={jfif:"browsers, viewers and most print shops",exif:"photo apps and metadata tools",photoshop:"Photoshop and the other Adobe apps",phys:"PNG-aware editors, including Photoshop and GIMP",bmp:"Windows apps that read the DIB header"};function A(e,t){if(void 0===t.x||void 0===t.y)return;let i=s(t.x,2),n=s(t.y,2),r=e.values.find(e=>.05>Math.abs(e.x-i)&&.05>Math.abs(e.y-n));r?r.containers.push(t.container):e.values.push({x:i,y:n,containers:[t.container]})}function I(e){let t=a(e);if(e>0&&t<40)return`This field counts pixels per meter, and ${e} of them works out to ${s(t,2)} DPI. A value that low usually means some other program wrote a DPI number straight into a field that measures meters.`}function T(e){let t=p(e),i={format:t,records:[],anyValue:!1,values:[],truncated:!1};if("jpeg"===t){let t=w(e);if(i.truncated=t.truncated,void 0!==t.jfifAt){let n=t.jfifAt,r=e[n+11]??0,a=h(e,n+12),o=h(e,n+14),l={container:"jfif",label:N.jfif,present:!0};1===r?(l.x=a,l.y=o,l.stored=`${a} x ${o} dots per inch`):2===r?(l.x=2.54*a,l.y=2.54*o,l.stored=`${a} x ${o} dots per centimeter, which is ${s(2.54*a,2)} x ${s(2.54*o,2)} DPI`):(l.stored=`${a} to ${o}`,l.note="The units byte is 0, so those two numbers are an aspect ratio, not a resolution. This file records no physical size."),i.records.push(l),A(i,l)}else i.records.push({container:"jfif",label:N.jfif,present:!1,note:"No JFIF header in this file."});let n=void 0!==t.tiffAt&&void 0!==t.exifLen?j(e,t.tiffAt,t.exifLen-8):null;if(n&&void 0!==n.x){let e=3===n.unit,t=e?2.54*n.x:n.x,r=void 0!==n.y?e?2.54*n.y:n.y:t,a={container:"exif",label:N.exif,present:!0,x:t,y:r,stored:e?`${s(n.x,4)} x ${s(n.y??n.x,4)} per centimeter, which is ${s(t,2)} x ${s(r,2)} DPI`:`${s(n.x,4)} x ${s(n.y??n.x,4)} per inch`};void 0===n.unit&&(a.note="There is no ResolutionUnit tag, so inches are assumed, which is what the EXIF spec defaults to."),e&&(a.note="ResolutionUnit says centimeters, so the stored number is not the DPI. The DPI is the converted value."),i.records.push(a),A(i,a)}else i.records.push({container:"exif",label:N.exif,present:!1,note:n?"This file has an EXIF block, but no XResolution tag inside it.":"No EXIF resolution tags in this file."});let r=void 0!==t.app13At&&void 0!==t.app13Len?$(e,t.app13At,t.app13Len):null;if(r){let e={container:"photoshop",label:N.photoshop,present:!0,x:r.h,y:r.v,stored:`${s(r.h,4)} x ${s(r.v,4)} pixels per inch`};i.records.push(e),A(i,e)}else i.records.push({container:"photoshop",label:N.photoshop,present:!1,note:"No Photoshop resource block in this file. Photoshop writes one when it saves, other software mostly does not."})}else if("png"===t){let{chunks:t,truncated:n}=v(e);i.truncated=n;let r=t.find(e=>"pHYs"===e.type);if(r&&9===r.len){let t=u(e,r.at+8),n=u(e,r.at+12),o=e[r.at+16]??0,l={container:"phys",label:N.phys,present:!0};1===o?(l.x=a(t),l.y=a(n),l.stored=`${t} x ${n} pixels per meter, which is ${s(l.x,4)} x ${s(l.y,4)} DPI`,l.note=I(t)):(l.stored=`${t} to ${n}`,l.note="The unit byte is 0, so those two numbers set an aspect ratio and nothing else. This file records no physical resolution."),i.records.push(l),A(i,l)}else i.records.push({container:"phys",label:N.phys,present:!1,note:"No pHYs chunk, so this PNG records no physical resolution at all."});let o=t.find(e=>"eXIf"===e.type);if(o){let t=C(e,o.at+8,o.len),n=j(e,t.at,t.len);if(n&&void 0!==n.x){let e=3===n.unit,t=e?2.54*n.x:n.x,r=void 0!==n.y?e?2.54*n.y:n.y:t,a={container:"exif",label:"EXIF resolution tags (eXIf chunk)",present:!0,x:t,y:r,stored:`${s(n.x,4)} x ${s(n.y??n.x,4)} per ${e?"centimeter":"inch"}`};i.records.push(a),A(i,a)}}}else if("bmp"===t)if(c(e,14,!0)>=40&&e.length>=46){let t=0|c(e,38,!0),n=0|c(e,42,!0),r={container:"bmp",label:N.bmp,present:!0};t>0&&n>0?(r.x=a(t),r.y=a(n),r.stored=`${t} x ${n} pixels per meter, which is ${s(r.x,4)} x ${s(r.y,4)} DPI`,r.note=I(t)):r.note="The resolution fields are set to 0, which means unset. This file records no physical size.",i.records.push(r),A(i,r)}else i.records.push({container:"bmp",label:N.bmp,present:!1,note:"This BMP uses the old 12-byte header, which has nowhere to put a resolution."});return i.anyValue=i.records.some(e=>void 0!==e.x),i}let S=65535,F=1;function C(e,t,i){return y(e,t,"Exif\0\0")?{at:t+6,len:Math.max(0,i-6)}:{at:t,len:i}}function z(e,t){let i=[],n=e.little,r=new Uint8Array(8);if(m(r,0,t,n),m(r,4,1,n),void 0!==e.xAt&&i.push({at:e.xAt,remove:8,insert:r.slice()}),void 0!==e.yAt&&e.yAt!==e.xAt&&i.push({at:e.yAt,remove:8,insert:r.slice()}),void 0!==e.unitAt){let t=new Uint8Array(2);n?(t[0]=2,t[1]=0):o(t,0,2),i.push({at:e.unitAt,remove:2,insert:t})}return{edits:i,unitWas:e.unit}}function D(e,t){let i=Math.max(F,Math.min(S,Math.round(t))),n=p(e),u=[],d=[];if("jpeg"===n){let t=w(e);if(t.truncated&&void 0===t.sosAt)return{ok:!1,outcomes:u,ranges:[],bytesChanged:0,reason:"This JPEG ends in the middle of a segment, so it cannot be read safely. The file is damaged."};if(void 0!==t.jfifAt){let n=t.jfifAt+11,r=function(e){let t=new Uint8Array(5);return t[0]=1,o(t,1,e),o(t,3,e),t}(i),a=f(e.subarray(n,n+5),r),s=h(e,t.jfifAt+12),l=h(e,t.jfifAt+14);a||d.push({at:n,remove:5,insert:r}),u.push({container:"jfif",label:N.jfif,status:a?"unchanged":"written",detail
1:a?`Already ${i} DPI, so not a byte was touched here.`:s!==l?`Was ${s} x ${l}, and both axes now read ${i}.`:`Now reads ${i} DPI on both axes.`})}else d.push({at:2,remove:0,insert:function(e){let t=new Uint8Array(18);return t[0]=255,t[1]=224,o(t,2,16),t.set(x,4),t[9]=1,t[10]=1,t[11]=1,o(t,12,e),o(t,14,e),t[16]=0,t[17]=0,t}(i)}),u.push({container:"jfif",label:N.jfif,status:"inserted",detail:`This JPEG had no JFIF header, so an 18 byte one was added right after the start marker, recording ${i} DPI.`});let n=void 0!==t.tiffAt&&void 0!==t.exifLen?j(e,t.tiffAt,t.exifLen-8):null;if(n&&void 0!==n.xAt){let{edits:e,unitWas:t}=z(n,i);d.push(...e),u.push({container:"exif",label:N.exif,status:"written",detail:3===t?`Now reads ${i} per inch. The unit was set to centimeters before, so it was switched to inches to match.`:`Now reads ${i} per inch.`})}else u.push({container:"exif",label:N.exif,status:"absent",detail:n?"This file has an EXIF block with no resolution tags in it. Adding tags shifts every offset that follows them, so nothing was written here.":"This file has no EXIF resolution tags, so nothing was written there. Software that reads only EXIF will still find no resolution."});let r=void 0!==t.app13At&&void 0!==t.app13Len?$(e,t.app13At,t.app13Len):null;if(r){let e=new Uint8Array(4);l(e,0,65536*i),d.push({at:r.at,remove:4,insert:e.slice()}),d.push({at:r.at+8,remove:4,insert:e.slice()}),u.push({container:"photoshop",label:N.photoshop,status:"written",detail:`Was ${s(r.h,2)} DPI, now ${i}. This is the one Photoshop reads first.`})}else u.push({container:"photoshop",label:N.photoshop,status:"absent",detail:"There is no Photoshop resource block here to patch. Photoshop will fall back to the EXIF or JFIF value."})}else if("png"===n){let{chunks:t,truncated:n}=v(e);if(n)return{ok:!1,outcomes:u,ranges:[],bytesChanged:0,reason:"This PNG has a chunk that runs past the end of the file, so it cannot be edited safely. The file is damaged."};let o=t.find(e=>"pHYs"===e.type),h=function(e){let t=r(e),i=new Uint8Array(21);return l(i,0,9),i[4]=112,i[5]=72,i[6]=89,i[7]=115,l(i,8,t),l(i,12,t),i[16]=1,l(i,17,M(i.subarray(4,17))),i}(i);if(o){let t=f(e.subarray(o.at,o.at+12+o.len),h);t||d.push({at:o.at,remove:12+o.len,insert:h}),u.push({container:"phys",label:N.phys,status:t?"unchanged":"written",detail:t?`Already ${r(i)} pixels per meter, so it was left alone.`:`Replaced, not duplicated. It now holds ${r(i)} pixels per meter, which reads back as ${s(a(r(i)),4)} DPI.`})}else{let e=t.find(e=>"IDAT"===e.type||"IEND"===e.type);if(!e)return{ok:!1,outcomes:u,ranges:[],bytesChanged:0,reason:"This PNG has no image data chunk, so there is nowhere to put the resolution."};d.push({at:e.at,remove:0,insert:h}),u.push({container:"phys",label:N.phys,status:"inserted",detail:`A 21 byte pHYs chunk was added ahead of the image data, holding ${r(i)} pixels per meter.`})}let c=t.find(e=>"eXIf"===e.type);if(c){let t=C(e,c.at+8,c.len),n=j(e,t.at,t.len);if(n&&void 0!==n.xAt){let t=c.at+8,r=e.slice(t,t+c.len),{edits:a}=z(n,i);for(let e of a)r.set(e.insert,e.at-t);let s=new Uint8Array(4+r.length);s.set(e.subarray(c.at+4,c.at+8),0),s.set(r,4);let o=new Uint8Array(r.length+4);o.set(r,0),l(o,r.length,M(s)),d.push({at:t,remove:c.len+4,insert:o}),u.push({container:"exif",label:"EXIF resolution tags (eXIf chunk)",status:"written",detail:`Now reads ${i} per inch, and the chunk checksum was recalculated over the new bytes.`})}}}else{if("bmp"!==n)return{ok:!1,outcomes:u,ranges:[],bytesChanged:0,reason:E(n)};if(40>c(e,14,!0)||e.length<46)return{ok:!1,outcomes:u,ranges:[],bytesChanged:0,reason:"This BMP uses the old 12 byte header, which has no resolution fields to write."};let t=r(i),o=new Uint8Array(8);m(o,0,t,!0),m(o,4,t,!0);let l=f(e.subarray(38,46),o);l||d.push({at:38,remove:8,insert:o}),u.push({container:"bmp",label:N.bmp,status:l?"unchanged":"written",detail:l?`Already ${t} pixels per meter on both axes.`:`Both axes now hold ${t} pixels per meter, which reads back as ${s(a(t),4)} DPI.`})}let{out:g,ranges:y,changed:b}=function(e,t){let i=[...t].sort((e,t)=>e.at-t.at),n=[],r=-1;for(let e of i)e.at<r||(n.push(e),r=e.at+e.remove);let a=0;for(let e of n)a+=e.insert.length-e.remove;let s=new Uint8Array(e.length+a),o=[],l=0,h=0,u=0;for(let t of n){s.set(e.subarray(l,t.at),h),h+=t.at-l,l=t.at;let i=h;if(s.set(t.insert,h),t.remove===t.insert.length){let n=0;for(;n<t.insert.length;){if(e[l+n]===t.insert[n]){n++;continue}let r=n;for(;r<t.insert.length&&e[l+r]!==t.insert[r];)r++;o.push({start:i+n,end:i+r}),u+=r-n,n=r}}else o.push({start:i,end:i+t.insert.length,replaced:t.remove}),u+=t.insert.length;h+=t.insert.length,l+=t.remove}return s.set(e.subarray(l),h),{out:s,ranges:o,changed:u}}(e,d);return{ok:!0,bytes:g,outcomes:u,ranges:y,bytesChanged:b}}function E(e){switch(e){case"webp":return"WebP has no standard field for physical resolution, so there is nothing to tag. Convert it to PNG or JPEG and the resolution can be written into that file instead.";case"gif":return"GIF has no resolution field at all. It was designed for screens, and a screen has no inches.";case"avif":return"AVIF stores its resolution differently and cannot be tagged here. Convert it to PNG or JPEG instead.";case"heic":return"A HEIC cannot be tagged in place. Convert it to PNG or JPEG and the resolution goes into that file.";case"tiff":return"TIFF is not handled here. Editing its resolution tags moves offsets throughout the file, and this tool will not write a change it cannot check.";default:return"This file is not a JPEG, PNG or BMP, so it has no resolution field this tool can write."}}function R(e){return"jpeg"===e||"png"===e||"bmp"===e}function U(e,t,i){if("jpeg"===i){let i=w(e),n=w(t);if(void 0===i.sosAt||void 0===n.sosAt)return{ok:!1,detail:"The compressed image data could not be located in one of the two files."};let r=e.subarray(i.sosAt);return f(r,t.subarray(n.sosAt))?{ok:!0,detail:`Every one of the ${r.length.toLocaleStr
1ing()} compressed bytes from the start of the image data to the end of the file is identical.`}:{ok:!1,detail:"The compressed image data differs between the two files."}}if("png"===i){let i=v(e).chunks.filter(e=>"IDAT"===e.type),n=v(t).chunks.filter(e=>"IDAT"===e.type);if(!i.length||i.length!==n.length)return{ok:!1,detail:"The image data chunks do not line up between the two files."};let r=0;for(let a=0;a<i.length;a++){let s=i[a],o=n[a];if(!s||!o)return{ok:!1,detail:"The image data chunks do not line up between the two files."};if(!f(e.subarray(s.at,s.at+12+s.len),t.subarray(o.at,o.at+12+o.len)))return{ok:!1,detail:"An image data chunk changed."};r+=s.len}return{ok:!0,detail:`All ${i.length} image data chunk${1===i.length?"":"s"}, ${r.toLocaleString()} compressed bytes, are identical.`}}if("bmp"===i){let i=c(e,10,!0),n=c(t,10,!0);if(i<0||i!==n)return{ok:!1,detail:"The pixel data does not start in the same place in both files."};let r=e.subarray(i);return f(r,t.subarray(n))?{ok:!0,detail:`All ${r.length.toLocaleString()} bytes of pixel data are identical.`}:{ok:!1,detail:"The pixel data differs between the two files."}}return{ok:!1,detail:"There is no way to check the image data of this format."}}function W(e,t,i){let n=[];if("jpeg"===i){let i=w(e),r=w(t);
1if(void 0!==i.exifAt&&void 0!==i.exifLen&&void 0!==r.exifAt&&void 0!==r.exifLen){let a=f(e.subarray(i.exifAt,i.exifAt+2+i.exifLen),t.subarray(r.exifAt,r.exifAt+2+r.exifLen));n.push(a?"EXIF block: unchanged, every byte":"EXIF block: kept, with the resolution tags patched")}else void 0!==i.exifAt&&void 0===r.exifAt&&n.push("EXIF block: lost");let a=i.iccRanges.reduce((e,t)=>e+(t.end-t.start),0),s=r.iccRanges.reduce((e,t)=>e+(t.end-t.start),0);a>0&&n.push(a===s?`Color profile: unchanged, ${a.toLocaleString()} bytes`:"Color profile: changed")}else if("png"===i){let i=v(e).chunks.filter(e=>"pHYs"!==e.type),r=v(t).chunks.filter(e=>"pHYs"!==e.type),a=i.map(e=>e.type).join(","),s=r.map(e=>e.type).join(",");n.push(a===s?`Every other chunk: still there, in the same order (${i.length} of them)`:"Chunk list: changed")}return n}function H(e){let t=p(e);if("jpeg"===t){let t=w(e);if(void 0!==t.sofAt){let i=h(e,t.sofAt+5),n=h(e,t.sofAt+7);if(n>0&&i>0)return{width:n,height:i}}return{width:0,height:0}}if("png"===t){let{chunks:t}=v(e),i=t.find(e=>"IHDR"===e.type);if(i){let t=u(e,i.at+8),n=u(e,i.at+12);if(t>0&&n>0)return{width:t,height:n}}return{width:0,height:0}}if("bmp"===t){let t=c(e,14,!0);if(t>=40){let t=0|c(e,18,!0),i=0|c(e,22,!0);if(t>0)return{width:t,height:Math.abs(i)}}else if(12===t){let t=d(e,18,!0),i=d(e,20,!0);if(t>0)return{width:t,height:Math.abs(i)}}return{width:0,height:0}}if("gif"===t)return{width:d(e,6,!0),height:d(e,8,!0)};if("webp"===t){let t=12;for(;t+8<=e.length;){let i=String.fromCharCode(e[t]??0,e[t+1]??0,e[t+2]??0,e[t+3]??0),n=c(e,t+4,!0);if(n<0||t+8+n>e.length)break;let r=t+8;if("VP8X"===i)return{width:1+((e[r+4]??0)|(e[r+5]??0)<<8|(e[r+6]??0)<<16),height:1+((e[r+7]??0)|(e[r+8]??0)<<8|(e[r+9]??0)<<16)};if("VP8 "===i){let t=16383&d(e,r+6,!0),i=16383&d(e,r+8,!0);if(t>0&&i>0)return{width:t,height:i};break}if("VP8L"===i){let t=e[r+1]??0,i=e[r+2]??0,n=e[r+3]??0;return{width:1+((63&i)<<8|t),height:1+((15&(e[r+4]??0))<<10|n<<2|(192&i)>>6)}}t=r+n+n%2}}return{width:0,height:0}}async function L(e,t){let i=new Uint8Array(await e.arrayBuffer());return"image/jpeg"===e.type?new Blob([(0,n.XA)(function(e,t){if("jpeg"!==p(e))return e;let i=D(e,t);return i.ok&&i.bytes?i.bytes:e}(i,t))],{type:e.type}):"image/png"===e.type?new Blob([(0,n.XA)(function(e,t){if("png"!==p(e))return e;let i=D(e,t);return i.ok&&i.bytes?i.bytes:e}(i,t))],{type:e.type}):e}},66087:(e,t,i)=>{i.r(t),i.d(t,{default:()=>C});var n=i(95155),r=i(12115),a=i(97003),s=i(33789),o=i(90235),l=i(86507),h=i(33534),u=i(25016),d=i(70134);let c="2026-08-14",m=[{id:"uk-printed",label:"UK passport, printed",short:"35 x 45 mm",kind:"printed",physical:{unit:"mm",width:35,height:45},minPixels:null,head:{basis:"physical",unit:"mm",min:29,max:34},fileBytes:null,background:"plain cream or light gray",source:{url:"https://www.gov.uk/photos-for-passports/photo-requirements",quote:"measure 45 millimetres (mm) high by 35mm wide (the standard size used in photo booths in the UK) ... The image of you - from the crown of your head to your chin - must be between 29mm and 34mm high.",checkedOn:c}},{id:"uk-digital",label:"UK passport, digital upload",short:"600 x 750 px minimum",kind:"digital",physical:null,minPixels:{width:600,height:750},head:{basis:"fraction",min:29/45,max:34/45,derivedFrom:"worked out from the printed rule (29mm to 34mm of head in a 45mm tall photo), because the digital page states a pixel minimum and no separate head measurement"},fileBytes:{min:51200,max:0xa00000},background:"plain cream or light gray",source:{url:"https://www.gov.uk/photos-for-passports",quote:"at least 600 pixels wide and 750 pixels tall ... at least 50KB and no more than 10MB",checkedOn:c}}],f="custom";function p(e,t){return"mm"===t?e:25.4*e}function g(e){let t=e.head;if("fraction"===t.basis)return{min:t.min,max:t.max};let i=e.physical;if(!i)return{min:t.min,max:t.max};let n=p(i.height,i.unit);return n<=0?{min:0,max:1}:{min:p(t.min,t.unit)/n,max:p(t.max,t.unit)/n}}function x(e){return e.physical&&e.physical.height>0?e.physical.width/e.physical.height:e.minPixels&&e.minPixels.height>0?e.minPixels.width/e.minPixels.height:1}function y(e,t){return e.physical?{width:Math.max(1,Math.round(("in"===e.physical.unit?e.physical.width:e.physical.width/25.4)*t)),height:Math.max(1,Math.round(("in"===e.physical.unit?e.physical.height:e.physical.height/25.4)*t))}:e.minPixels?{width:e.minPixels.width,height:e.minPixels.height}:{width:600,height:600}}let w=[{id:"4x6in",label:"4 x 6 inch photo print",widthMm:101.6,heightMm:152.39999999999998},{id:"10x15cm",label:"10 x 15 cm photo print",widthMm:100,heightMm:150},{id:"a4",label:"A4 paper",widthMm:210,heightMm:297},{id:"letter",label:"US Letter paper",widthMm:215.89999999999998,heightMm:279.4}];function b(e){let t=e.angleDeg*Math.PI/180,i=Math.abs(Math.cos(t)),n=Math.abs(Math.sin(t));return{w:Math.max(1,e.srcW*i+e.srcH*n),h:Math.max(1,e.srcW*n+e.srcH*i)}}function v(e,t){let i=t.angleDeg*Math.PI/180,n=Math.cos(i),r=Math.sin(i),a=b(t),s=e.x-t.srcW/2,o=e.y-t.srcH/2;return t.mirror&&(s=-s),{x:s*n-o*r+a.w/2,y:s*r+o*n+a.h/2}}function k(e,t){let i=t.angleDeg*Math.PI/180,n=Math.cos(i),r=Math.sin(i),a=b(t),s=e.x-a.w/2,o=e.y-a.h/2,l=s*n+o*r;return t.mirror&&(l=-l),{x:l+t.srcW/2,y:-s*r+o*n+t.srcH/2}}function M(e,t,i,n,r){let a=Math.abs(i.y-t.y),s=Math.max(1,e.h),o=Math.max(1,Math.round(r.height)),l=Math.round(a/s*o),h=l/o,u=g(n),d=n.physical,c="percent",m=null,f=100*h,p=100*u.min,x=100*u.max;d&&(c="physical",m=d.unit,f=h*d.height,p=u.min*d.height,x=u.max*d.height);let y=h>=u.min-1e-9&&h<=u.max+1e-9,w=0;
1y||(w=h<u.min?p-f:f-x);let b=["head height from your two markers","photo shape and output pixel size"];return n.minPixels&&b.push("minimum pixel size for upload"),{headFramePx:a,cropHeightPx:s,headOutputPx:l,outputHeight:o,fraction:h,domain:c,unit:m,value:f,rangeMin:p,rangeMax:x,pass:y,missBy:Math.max(0,w),checked:b}}function j(e,t,i,n){let r=Math.abs(t.y-e.y),a=g(i),s=(a.min+a.max)/2,o=x(i);if(r<1||s<=0||o<=0)return{ok:!1,rect:{x:0,y:0,w:n.w,h:n.h},problem:"Place both markers on the photo first, one on the top of the hair and one under the chin.",neededW:0,neededH:0};let l=r/s,h=l*o;if(h>n.w+.5||l>n.h+.5)return{ok:!1,rect:{x:0,y:0,w:Math.min(n.w,h),h:Math.min(n.h,l)},problem:`To put the head at ${(100*s).toFixed(1)}% of the frame the crop needs to be ${Math.round(h)} by ${Math.round(l)} pixels, and your picture is only ${Math.round(n.w)} by ${Math.round(n.h)}. Move the camera back and retake, or use a larger original.`,neededW:h,neededH:l};let u=Math.min(e.y,t.y),d=(e.x+t.x)/2-h/2,c=u-(l-r)*.35;return{ok:!0,rect:{x:d=Math.max(0,Math.min(n.w-h,d)),y:c=Math.max(0,Math.min(n.h-l,c)),w:h,h:l},problem:null,neededW:h,neededH:l}}function $(e,t){let i=Math.max(1,Math.min(t.w,e.w)),n=Math.max(1,Math.min(t.h,e.h));return{w:i,h:n,x:Math.max(0,Math.min(t.w-i,e.x)),y:Math.max(0,Math.min(t.h-n,e.y))}}function N(e,t){return"in"===t?`${e.toFixed(3)} in`:"mm"===t?`${e.toFixed(1)} mm`:`${e.toFixed(1)}%`}var P=i(64963),A=i(31258),I=i(14827);let T="h-9 w-full rounded-md border border-input bg-background px-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";function S(e){let t=e.lastIndexOf(".");return t>0?e.slice(0,t):e}function F(e,t){let i=Number(e);return Number.isFinite(i)?i:t}function C(){let[e,t]=(0,r.useState)(null),[i,c]=(0,r.useState)("uk-printed"),[C,z]=(0,r.useState)("2"),[D,E]=(0,r.useState)("2"),[R,U]=(0,r.useState)("in"),[W,H]=(0,r.useState)("1"),[L,B]=(0,r.useState)("1.375"),[J,G]=(0,r.useState)(300),[X,q]=(0,r.useState)(0),[O,Y]=(0,r.useState)(!1),[_,K]=(0,r.useState)({x:0,y:0,w:100,h:128}),[V,Q]=(0,r.useState)(null),[Z,ee]=(0,r.useState)(null),[et,ei]=(0,r.useState)("crown"),[en,er]=(0,r.useState)("image/jpeg"),[ea,es]=(0,r.useState)(.92),[eo,el]=(0,r.useState)(""),[eh,eu]=(0,r.useState)("4x6in"),[ed,ec]=(0,r.useState)(0),[em,ef]=(0,r.useState)(0),[ep,eg]=(0,r.useState)(!1),[ex,ey]=(0,r.useState)(null),[ew,eb]=(0,r.useState)(null),[ev,ek]=(0,r.useState)(null),[eM,ej]=(0,r.useState)(!1),[e$,eN]=(0,r.useState)(null),[eP,eA]=(0,r.useState)(null),eI=(0,r.useRef)(null),eT=(0,r.useRef)(null),eS=(0,r.useRef)({kind:"none"}),eF=(0,r.useRef)(null),eC=(0,r.useRef)(null),ez=(0,r.useRef)(!1),eD=(0,r.useRef)(0),eE=(0,r.useMemo)(()=>{let e=m.find(e=>e.id===i);if(e)return e;let t=Math.max(1,F(C,2)),n=Math.max(1,F(D,2)),r=Math.max(.1,F(W,1)),a=Math.min(Math.max(r,F(L,1.375)),n);return{id:f,label:"Your own numbers",short:`${t} x ${n} ${R}`,kind:"printed",physical:{unit:R,width:t,height:n},minPixels:null,head:{basis:"physical",unit:R,min:r,max:a},fileBytes:null,background:null,source:null}},[i,C,D,R,W,L]),eR=(0,r.useMemo)(()=>({srcW:e?.width??1,srcH:e?.height??1,angleDeg:X,mirror:O}),[e,X,O]),eU=(0,r.useMemo)(()=>b(eR),[eR]),eW=(0,r.useMemo)(()=>y(eE,J),[eE,J]),eH=(0,r.useMemo)(()=>x(eE),[eE]),eL=(0,r.useMemo)(()=>g(eE),[eE]),eB=(0,r.useMemo)(()=>V?v(V,eR):null,[V,eR]),eJ=(0,r.useMemo)(()=>Z?v(Z,eR):null,[Z,eR]),eG=(0,r.useMemo)(()=>e&&eB&&eJ?M(_,eB,eJ,eE,eW):null,[e,_,eB,eJ,eE,eW]),eX=(0,r.useMemo)(()=>!e||_.w>=eW.width-.5&&_.h>=eW.height-.5?null:{haveW:Math.round(_.w),haveH:Math.round(_.h),needW:eW.width,needH:eW.height},[e,_,eW]),eq=(0,r.useMemo)(()=>w.find(e=>e.id===eh)??w[0],[eh]),eO=(0,r.useMemo)(()=>(function(e,t){if(e.physical)return{widthMm:p(e.physical.width,e.physical.unit),heightMm:p(e.physical.height,e.physical.unit)};let i=y(e,t),n=t>0?t:300;return{widthMm:i.width/n*25.4,heightMm:i.height/n*25.4}})(eE,J),[eE,J]),eY=(0,r.useMemo)(()=>eq?function(e,t,i,n,r){let a=e.widthMm-2*r,s=e.heightMm-2*r;if(t<=0||i<=0||a<=0||s<=0)return{across:0,down:0,copies:0,spareWmm:0,spareHmm:0};let o=Math.max(0,Math.floor((a+n)/(t+n)+1e-6)),l=Math.max(0,Math.floor((s+n)/(i+n)+1e-6));return{across:o,down:l,copies:o*l,spareWmm:a-(o>0?o*t+(o-1)*n:0),spareHmm:s-(l>0?l*i+(l-1)*n:0)}}(eq,eO.widthMm,eO.heightMm,ed,em):{across:0,down:0,copies:0,spareWmm:0,spareHmm:0},[eq,eO,ed,em]);(0,r.useEffect)(()=>
1{if(ez.current)return;ez.current=!0;let e=new URLSearchParams(window.location.search);if(![...e.keys()].length)return;let t=e.get("spec");t&&(m.some(e=>e.id===t)||t===f)&&c(t);let i=Number(e.get("dpi"));Number.isFinite(i)&&i>=72&&i<=1200&&G(Math.round(i));let n=e.get("cw"),r=e.get("cht"),a=e.get("cu");n&&z(n),r&&E(r),("mm"===a||"in"===a)&&U(a);let s=e.get("hmin"),o=e.get("hmax");s&&H(s),o&&B(o);let l=e.get("sheet");l&&w.some(e=>e.id===l)&&eu(l);let h=Number(e.get("gut"));Number.isFinite(h)&&h>=0&&h<=30&&ec(h);let u=Number(e.get("mar"));Number.isFinite(u)&&u>=0&&u<=30&&ef(u),eb("Settings loaded from the link. A link never carries the photograph, so choose your own picture below.")},[]);let e_=(0,r.useCallback)(()=>{let e=new URLSearchParams;return e.set("spec",i),e.set("dpi",String(J)),e.set("sheet",eh),e.set("gut",String(ed)),e.set("mar",String(em)),i===f&&(e.set("cw",C),e.set("cht",D),e.set("cu",R),e.set("hmin",W),e.set("hmax",L)),e},[i,J,eh,ed,em,C,D,R,W,L]),eK=(0,r.useCallback)(e=>{if(!e.type.startsWith("image/"))return void ek("That does not look like an image file. A JPG or PNG straight off a phone is fine.");let i=URL.createObjectURL(e),n=new Image;n.onload=()=>{eC.current&&URL.revokeObjectURL(eC.current),eC.current=i,t({name:e.name,width:n.naturalWidth,height:n.naturalHeight,el:n,objectUrl:i}),q(0),Y(!1),ey(null),ek(null),eN(null),eA(null),eg(!1);let r=n.naturalWidth/2;Q({x:r,y:.18*n.naturalHeight}),ee({x:r,y:.52*n.naturalHeight})},n.onerror=()=>{URL.revokeObjectURL(i),ek("The browser could not decode that image. Try saving it as a JPG or PNG first.")},n.src=i},[]);(0,r.useEffect)(()=>()=>{eC.current&&URL.revokeObjectURL(eC.current)},[]),(0,r.useEffect)(()=>{function e(e){let t=e.clipboardData?.items;if(t)for(let i=0;i<t.length;i++){let n=t[i];if(!n||"file"!==n.kind)continue;let r=n.getAsFile();if(r&&r.type.startsWith("image/")){eK(r),e.preventDefault();return}}}return window.addEventListener("paste",e),()=>window.removeEventListener("paste",e)},[eK]),(0,r.useEffect)(()=>{if(!e){eT.current=null;return}let t=b(eR),i=(0,d.$t)(Math.max(1,Math.round(t.w)),Math.max(1,Math.round(t.h)));if(!i)return;let{canvas:n,ctx:r}=i;r.imageSmoothingQuality="high",r.save(),r.translate(n.width/2,n.height/2),r.rotate(X*Math.PI/180),r.scale(O?-1:1,1),r.drawImage(e.el,-e.width/2,-e.height/2),r.restore(),eT.current=n,ey(null)},[e,eR,X,O]);let eV=(0,r.useCallback)(()=>{if(!e||!eB||!eJ)return;let t=M(_,eB,eJ,eE,eW),i=j(eB,eJ,eE,eU);if(!i.ok){eN(null),ek(i.problem);return}let n=$(i.rect,eU);K(n),ek(null);let r=M(n,eB,eJ,eE,eW);eN(`Head was ${N(t.value,t.unit)}, now ${N(r.value,r.unit)}. The target range is ${N(r.rangeMin,r.unit)} to ${N(r.rangeMax,r.unit)}.`)},[e,eB,eJ,eE,eW,eU,_]),eQ=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(!e||!eB||!eJ)return;let t=`${e.objectUrl}|${i}`;if(eQ.current===t)return;eQ.current=t;let n=j(eB,eJ,eE,eU);if(n.ok)return void K($(n.rect,eU));let r=eU.w,a=r/eH;a>eU.h&&(r=(a=eU.h)*eH),K($({x:(eU.w-r)/2,y:(eU.h-a)/2,w:r,h:a},eU))},[e,eB,eJ,eE,eU,eH,i]);let eZ=(0,r.useRef)(eH);(0,r.useEffect)(()=>{e&&(1e-6>Math.abs(eZ.current-eH)||(eZ.current=eH,K(e=>{let t=e.x+e.w/2,i=e.y+e.h/2,n=e.h,r=n*eH;return r>eU.w&&(n=(r=eU.w)/eH),$({x:t-r/2,y:i-n/2,w:r,h:n},eU)})))},[eH,eU,e]);let e0=(0,r.useMemo)(()=>{let e=Math.min(560/eU.w,620/eU.h,1);return{scale:e,w:Math.round(eU.w*e),h:Math.round(eU.h*e)}},[eU]),e1=(0,r.useCallback)(()=>{let e=eI.current,t=eT.current;if(!e||!t)return;let i=Math.min(2,window.devicePixelRatio||1);e.style.width=`${e0.w}px`,e.style.height=`${e0.h}px`;let n=(0,d.lH)(e,Math.round(e0.w*i),Math.round(e0.h*i));if(!n)return;n.setTransform(i,0,0,i,0,0),n.clearRect(0,0,e0.w,e0.h),n.drawImage(t,0,0,e0.w,e0.h);let r=e0.scale,a={x:_.x*r,y:_.y*r,w:_.w*r,h:_.h*r};for(let[e,t]of(n.fillStyle="rgba(0,0,0,0.45)",n.fillRect(0,0,e0.w,a.y),n.fillRect(0,a.y+a.h,e0.w,e0.h-a.y-a.h),n.fillRect(0,a.y,a.x,a.h),n.fillRect(a.x+a.w,a.y,e0.w-a.x-a.w,a.h),n.strokeStyle="#ffffff",n.lineWidth=1.5,n.strokeRect(a.x+.5,a.y+.5,a.w-1,a.h-1),n.fillStyle="#ffffff",[[a.x,a.y],[a.x+a.w,a.y],[a.x,a.y+a.h],[a.x+a.w,a.y+a.h]]))n.fillRect(e-4,t-4,8,8);let s=(eL.min+eL.max)/2,o=a.y+a.h*(1-s)*.35,l=o+a.h*s;for(let e of(n.strokeStyle="rgba(56,189,248,0.9)",n.setLineDash([5,4]),n.lineWidth=1,[o,l]))n.beginPath(),n.moveTo(a.x,e),n.lineTo(a.x+a.w,e),n.stroke();for(let[e,t,i]of(n.setLineDash([]),[[eB,"#22c55e","crown"],[eJ,"#f97316","chin"]])){if(!e)continue;let a=e.x*r,s=e.y*r;n.strokeStyle=t,n.globalAlpha=.75,n.lineWidth=1,n.beginPath(),n.moveTo(0,s),n.lineTo(e0.w,s),n.stroke(),n.globalAlpha=1,n.beginPath(),n.arc(a,s,et===i?9:7,0,2*Math.PI),n.fillStyle=t,n.fill(),n.strokeStyle="#ffffff",n.lineWidth=2,n.stroke()}let h=eS.current,u=eF.current;if("marker"===h.kind&&u){let e=Math.min(e0.w-48-4,Math.max(52,u.x*r)),i=u.y*r>e0.h/2?56:e0.h-48-8;n.save(),n.beginPath(),n.arc(e,i,48,0,2*Math.PI),n.closePath(),n.clip(),n.fillStyle="#111827",n.fillRect(e-48,i-48,96,9
16);n.drawImage(t,u.x-12,u.y-12,24,24,e-48,i-48,96,96),n.strokeStyle="rgba(255,255,255,0.9)",n.lineWidth=1,n.beginPath(),n.moveTo(e-48,i),n.lineTo(e+48,i),n.stroke(),n.restore(),n.strokeStyle="rgba(255,255,255,0.9)",n.lineWidth=2,n.beginPath(),n.arc(e,i,48,0,2*Math.PI),n.stroke()}},[e0,_,eB,eJ,et,eL]);function e2(e){let t=e.currentTarget.getBoundingClientRect();return{x:(e.clientX-t.left)/e0.scale,y:(e.clientY-t.top)/e0.scale}}function e5(e){e.currentTarget.hasPointerCapture(e.pointerId)&&e.currentTarget.releasePointerCapture(e.pointerId),eS.current={kind:"none"},eF.current=null,e1()}function e4(t,i){if(!e)return;let n="crown"===et?eB:eJ;if(!n)return;let r=k({x:Math.max(0,Math.min(eU.w,n.x+t)),y:Math.max(0,Math.min(eU.h,n.y+i))},eR);"crown"===et?Q(r):ee(r)}(0,r.useEffect)(()=>{e1()},[e1]);let e8=(0,r.useCallback)(()=>{let e=eT.current;if(!e||!eB||!eJ)return;let t=Math.min(400,Math.max(60,Math.round(eW.width/2))),i=Math.max(1,Math.round(t/eH||1)),n=(0,d.$t)(t,i,{willReadFrequently:!0});if(!n)return;let{ctx:r}=n;r.drawImage(e,_.x,_.y,_.w,_.h,0,0,t,i);let a=r.getImageData(0,0,t,i).data,s=function(e,t,i,n){let r=Math.min(t.y,i.y),a=Math.max(t.y,i.y),s=Math.max(1,a-r),o=.39*s;return{box:{x:((t.x+i.x)/2-o-e.x)*n,y:(r-.08*s-e.y)*n,w:2*o*n,h:1.13*s*n},skipBelowY:(a-e.y)*n}}(_,eB,eJ,t/Math.max(1,_.w)),o=function(e,t,i,n,r=.12,a=2){if(t<8||i<8)return null;let s=Math.max(2,Math.round(Math.min(t,i)*r)),o=Math.max(1,Math.round(a)),l=n.box,h=0,u=0,d=0,c=0,m=0,f=0,p=0;for(let r=0;r<i&&!(r>=n.skipBelowY);r+=o){let n=r<s||r>=i-s;for(let i=0;i<t;i+=o){let a=i<s||i>=t-s;if(!n&&!a||i>=l.x&&i<l.x+l.w&&r>=l.y&&r<l.y+l.h)continue;let o=(r*t+i)*4,g=e[o],x=e[o+1],y=e[o+2];void 0!==g&&void 0!==x&&void 0!==y&&(u+=g,d+=x,c+=y,m+=g*g,f+=x*x,p+=y*y,h++)}}if(h<50)return null;let g=(e,t)=>{let i=e/h;return[i,Math.sqrt(Math.max(0,t/h-i*i))]},[x,y]=g(u,m),[w,b]=g(d,f),[v,k]=g(c,p);return{samples:h,mean:[x,w,v],sd:[y,b,k],bandShare:r}}(a,t,i,s);ey(o),o?eb(null):eb("Not enough background left around the head to measure. Widen the crop and try again.")},[_,eB,eJ,eW,eH]),e3=(0,r.useCallback)(()=>{let e=eT.current;if(!e)return null;let t=(0,d.$t)(eW.width,eW.height);if(!t)return null;let{canvas:i,ctx:n}=t;return n.imageSmoothingQuality="high",n.fillStyle="#ffffff",n.fillRect(0,0,i.width,i.height),n.drawImage(e,_.x,_.y,_.w,_.h,0,0,i.width,i.height),i},[_,eW]);
1function e6(){if(!e)return"Choose a photo first.";if(!eB||!eJ)return"Place both markers before exporting.";let t=M(_,eB,eJ,eE,eW);return t.pass||ep?eX&&!ep?`Not exporting. Your crop is ${eX.haveW} by ${eX.haveH} pixels and this size at ${J} DPI needs ${eX.needW} by ${eX.needH}. Enlarging it will not add detail that is not there. Use a bigger original, lower the DPI, or tick the box below.`:null:`Not exporting. Measured on the ${eW.width} by ${eW.height} pixels this file will actually contain, the head comes out ${N(t.value,t.unit)} against a required ${N(t.rangeMin,t.unit)} to ${N(t.rangeMax,t.unit)}, missing by ${N(t.missBy,t.unit)}. Use Fit the head, or tick the box below to export it as it is.`}async function e9(e,t){let i=await new Promise(i=>e.toBlob(i,en,t));return i?(0,P.withDensity)(i,J):null}async function e7(e,t){let i=.4,n=.95,r=null;for(let a=0;a<10;a++){let a=(i+n)/2,s=await e9(e,a);if(!s)break;s.size<=t?(r={blob:s,q:a},i=a):n=a}if(r)return{blob:r.blob,q:r.q,failed:!1};let a=await e9(e,.4);return a?{blob:a,q:.4,failed:!0}:null}async function te(){let t=e6();if(t)return void ek(t);let i=e3();if(!i)return;let n=++eD.current;ej(!0),ek(null);try{let t=eo.trim(),r=t?Math.round(1024*F(t,0)):0;if(t&&r<=0)return void ek(`"${t}" is not a size in KB, so nothing was targeted. Clear it or type a number.`);let a=null,s="";if(r>0&&"image/jpeg"===en){let e=await e7(i,r);if(n!==eD.current)return;if(!e)return void ek("The browser could not encode that image.");if(e.failed)return void ek(`Could not reach ${(0,A.z)(r)} without going below the quality floor. The smallest this gets at ${eW.width} by ${eW.height} pixels is ${(0,A.z)(e.blob.size)}. Nothing was downloaded, because the alternative is shrinking the picture below the size this document needs.`);a=e.blob,s=`landed at ${(0,A.z)(e.blob.size)} on quality ${Math.round(100*e.q)}`}else{if(a=await e9(i,ea),n!==eD.current)return;a&&(s=`${(0,A.z)(a.size)}`)}if(!a)return void ek("The browser could not encode that image.");let o=function(e,t){let i=e.fileBytes;return i?t<i.min?{pass:!1,side:"under",missBy:i.min-t,min:i.min,max:i.max}:t>i.max?{pass:!1,side:"over",missBy:t-i.max,min:i.min,max:i.max}:{pass:!0,side:null,missBy:0,min:i.min,max:i.max}:{pass:!0,side:null,missBy:0,min:null,max:null}}(eE,a.size);if(!o.pass&&!ep)return void ek("under"===o.side?`Not downloading. The file came out ${(0,A.z)(a.size)}, which is ${(0,A.z)(o.missBy)} under the ${(0,A.z)(o.min??0)} minimum this size states, and an upload under that gets rejected. Raise the JPEG quality, clear the target size, or tick the box below to take it as it is.`:`Not downloading. The file came out ${(0,A.z)(a.size)}, which is ${(0,A.z)(o.missBy)} over the ${(0,A.z)(o.max??0)} maximum this size states. Lower the quality or type a target size, or tick the box below to take it as it is.`);o.pass||(s+=", outside the stated upload range");let l="image/png"===en?"png":"jpg";(0,I.WN)(a,`${S(e?.name??"photo")}-${eE.id}.${l}`),eA(`${eW.width} by ${eW.height} pixels at ${J} DPI, ${s}.`)}finally{n===eD.current&&ej(!1)}}async function tt(){let t=e6();if(t)return void ek(t);if(!eq||eY.copies<1)return void ek("No copies fit on that sheet at this size. Try a bigger sheet or a smaller gutter.");let i=eT.current;if(!i||!eB||!eJ)return;let n=++eD.current;ej(!0),ek(null);try{let t=e=>Math.round(e/25.4*J),r=t(eq.widthMm),a=t(eq.heightMm);if(r>d.QP||a>d.QP||r*a>d.gA)return void ek(`${eq.label} at ${J} DPI works out at ${r} by ${a} pixels, which is past what a browser canvas will hold, and it would come back blank rather than wrong. Drop to a lower resolution or a smaller paper size. The single photo download is unaffected.`);let s=(0,d.$t)(r,a);if(!s)return;let{canvas:o,ctx:l}=s;l.imageSmoothingQuality="high",l.fillStyle="#ffffff",l.fillRect(0,0,o.width,o.height);let h=t(eO.widthMm),u=t(eO.heightMm),c=t(ed),m=eY.across*h+(eY.across-1)*c,f=eY.down*u+(eY.down-1)*c,p=Math.round((o.width-m)/2),g=Math.round((o.height-f)/2);for(let e=0;e<eY.down;e++)for(let t=0;t<eY.across;t++){let n=M(_,eB,eJ,eE,{width:h,height:u});
1if(!n.pass&&!ep)return void ek(`Stopped on the copy in row ${e+1}, column ${t+1}. At ${h} by ${u} pixels the head measures ${N(n.value,n.unit)} and the range is ${N(n.rangeMin,n.unit)} to ${N(n.rangeMax,n.unit)}. No sheet was written.`);let r=p+t*(h+c),a=g+e*(u+c);l.drawImage(i,_.x,_.y,_.w,_.h,r,a,h,u)}l.strokeStyle="rgba(0,0,0,0.55)",l.lineWidth=1;for(let e=0;e<=eY.across;e++){let t;t=0===e?p:e===eY.across?p+m:p+e*h+(e-1)*c+c/2,l.beginPath(),l.moveTo(Math.round(t)+.5,g),l.lineTo(Math.round(t)+.5,g+f),l.stroke()}for(let e=0;e<=eY.down;e++){let t;t=0===e?g:e===eY.down?g+f:g+e*u+(e-1)*c+c/2,l.beginPath(),l.moveTo(p,Math.round(t)+.5),l.lineTo(p+m,Math.round(t)+.5),l.stroke()}let x=o.height-(g+f),y="no room on this layout for the ruler bar",w=p+t(66)<o.width;if(x>t(4)&&m>=t(50)){let e=g+f+Math.round(x/2);l.fillStyle="#000000",l.fillRect(p,e,t(50),Math.max(1,t(1))),w&&(l.font=`${Math.max(8,t(3))}px sans-serif`,l.fillText("50 mm",p+t(50)+t(2),e+t(2))),y="a 50 mm ruler bar is printed under the grid, measure it to confirm the scale"}let b=await new Promise(e=>o.toBlob(e,"image/jpeg",.95));if(n!==eD.current)return;if(!b)return void ek("The browser could not encode the sheet.");let v=await (0,P.withDensity)(b,J);(0,I.WN)(v,`${S(e?.name??"photo")}-sheet-${eq.id}.jpg`),eA(`${eY.copies} copies on ${eq.label}, ${o.width} by ${o.height} pixels at ${J} DPI, ${y}.`)}finally{n===eD.current&&ej(!1)}}let ti=m.find(e=>e.id===i)??null,tn=eE.head,tr="fraction"===tn.basis?tn.derivedFrom:null,ta=g(m[0]??eE);return(0,n.jsxs)("div",{className:"space-y-6",children:[(0,n.jsx)(l.H,{onFile:eK,label:"Your photo",title:"Click to choose a photo, drag one into the box, or paste with Ctrl+V",hint:"JPG, PNG or WebP. It stays on your device, there is no upload. An iPhone HEIC only opens in Safari, so on any other browser set the camera to Most Compatible or export a JPG first."}),ev&&(0,n.jsx)("p",{className:"rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive",children:ev}),ew&&!ev&&(0,n.jsx)("p",{className:"rounded-md border border-input bg-muted/40 p-3 text-sm text-muted-foreground",children:ew}),e&&(0,n.jsxs)("div",{className:"grid gap-6 lg:grid-cols-[auto_1fr]",children:[(0,n.jsxs)("div",{className:"space-y-3",children:[(0,n.jsx)("canvas",{ref:eI,tabIndex:0,onPointerDown:function(t){if(!e)return;let i=e2(t),n=16/e0.scale;if(t.currentTarget.setPointerCapture(t.pointerId),eF.current=i,eB&&Math.hypot(i.x-eB.x,i.y-eB.y)<n){eS.current={kind:"marker",which:"crown"},ei("crown"),e1();return}if(eJ&&Math.hypot(i.x-eJ.x,i.y-eJ.y)<n){eS.current={kind:"marker",which:"chin"},ei("chin"),e1();return}let r=14/e0.scale;for(let[e,t,n]of[["nw",_.x,_.y],["ne",_.x+_.w,_.y],["sw",_.x,_.y+_.h],["se",_.x+_.w,_.y+_.h]])if(Math.abs(i.x-t)<r&&Math.abs(i.y-n)<r){let t={x:"nw"===e||"sw"===e?_.x+_.w:_.x,y:"nw"===e||"ne"===e?_.y+_.h:_.y};eS.current={kind:"resize",handle:e,anchor:t};return}i.x>=_.x&&i.x<=_.x+_.w&&i.y>=_.y&&i.y<=_.y+_.h&&(eS.current={kind:"move",dx:i.x-_.x,dy:i.y-_.y})},onPointerMove:function(t){let i=eS.current;if("none"===i.kind||!e)return;let n=e2(t);eF.current=n;let r={x:Math.max(0,Math.min(eU.w,n.x)),y:Math.max(0,Math.min(eU.h,n.y))};if("marker"===i.kind){let e=k(r,eR);"crown"===i.which?Q(e):ee(e),e1();return}if("move"===i.kind)return void K(e=>$({...e,x:n.x-i.dx,y:n.y-i.dy},eU));let a=Math.max(16,Math.max(Math.abs(r.x-i.anchor.x),Math.abs(r.y-i.anchor.y)*eH)),s=a/eH;s=(a=Math.min(a=Math.min(a,eU.w),(s=Math.min(s,eU.h))*eH))/eH,K($({x:"ne"===i.handle||"se"===i.handle?i.anchor.x:i.anchor.x-a,y:"sw"===i.handle||"se"===i.handle?i.anchor.y:i.anchor.y-s,w:a,h:s},eU))},onPointerUp:e5,onPointerCancel:e5,onKeyDown:function(e){let t=e.shiftKey?10:1;if("ArrowUp"===e.key)e4(0,-t);else if("ArrowDown"===e.key)e4(0,t);else if("ArrowLeft"===e.key)e4(-t,0);else{if("ArrowRight"!==e.key)return;e4(t,0)}e.preventDefault()},className:"touch-none rounded-md border border-input bg-muted","aria-label":"Photo with the crop and the two head markers"}),(0,n.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[(0,n.jsx)("span",{children:"Marker:"}),(0,n.jsx)(a.$,{type:"button",size:"sm",variant:"crown"===et?"default":"outline",onClick:()=>ei("crown"),children:"Top of hair"}),(0,n.jsx)(a.$,{type:"button",size:"sm",variant:"chin"===et?"default":"outline",onClick:()=>ei("chin"),children:"Under the chin"}),(0,n.jsx)(a.$,{type:"button",size:"sm",variant:"ghost",onClick:()=>e4(0,-1),children:"Up 1 px"}),(0,n.jsx)(a.$,{type:"button",size:"sm",variant:"ghost",onClick:()=>e4(0,1),children:"Down 1 px"})]}),(0,n.jsx)("p",{className:"text-xs text-muted-foreground",children:"The green marker goes on the top of the hair as it naturally sits, not on the skull. That is the placement people get wrong, and it is the one that changes the verdict. Click the canvas and use the arrow keys for single pixels, shift and arrow for ten."})]}),(0,n.jsxs)("div",{className:"space-y-5",children:[(0,n.jsxs)("div",{className:"space-y-2",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-size",children:"Size"}),(0,n.jsxs)("select",{id:"ppm-size",value:i,onChange:e=>c(e.target.value),className:T,children:[m.map(e=>(0,n.jsxs)("option",{value:e.id,children:[e.label," (",e.short,")"]},e.id)),(0,n.jsx)("option",{value:f,children:"Your own numbers"})]}),ti&&(0,n.jsxs)("div",{className:"rounded-md border border-input bg-muted/40 p-3 text-xs text-muted-foreground",children:[(0,n.jsxs)("p",{className:"italic",children:["â",ti.source.quote,"â"]}),(0,n.jsxs)("p",{className:"mt-1",children:[(0,n.jsx)("a",{className:"underline",href:ti.source.url,target:"_blank",rel:"noopener noreferrer",children:ti.source.url}
1),", which we read on ",ti.source.checkedOn,". That is our check date, not the date the page was published."]}),tr&&(0,n.jsxs)("p",{className:"mt-1",children:["Head range ",tr,"."]}),ti.background&&(0,n.jsxs)("p",{className:"mt-1",children:["The same page asks for a ",ti.background," background. We report what yours measures, further down, and we do not change it for you."]})]}),i===f&&(0,n.jsxs)("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-5",children:[(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-cw",className:"text-xs",children:"Width"}),(0,n.jsx)(s.p,{id:"ppm-cw",value:C,onChange:e=>z(e.target.value)})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-chh",className:"text-xs",children:"Height"}),(0,n.jsx)(s.p,{id:"ppm-chh",value:D,onChange:e=>E(e.target.value)})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-cu",className:"text-xs",children:"Unit"}),(0,n.jsxs)("select",{id:"ppm-cu",value:R,onChange:e=>U("mm"===e.target.value?"mm":"in"),className:T,children:[(0,n.jsx)("option",{value:"in",children:"inches"}),(0,n.jsx)("option",{value:"mm",children:"mm"})]})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-hmin",className:"text-xs",children:"Head min"}),(0,n.jsx)(s.p,{id:"ppm-hmin",value:W,onChange:e=>H(e.target.value)})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-hmax",className:"text-xs",children:"Head max"}),(0,n.jsx)(s.p,{id:"ppm-hmax",value:L,onChange:e=>B(e.target.value)})]}),(0,n.jsx)("p",{className:"col-span-2 text-xs text-muted-foreground sm:col-span-5",children:"These are your numbers, copied off your own form. We are not vouching for them, and the readout below measures against whatever you type here."})]})]}),eG&&(0,n.jsxs)("div",{className:(0,u.cn)("rounded-md border p-3 text-sm",eG.pass?"border-emerald-500/40 bg-emerald-500/10":"border-amber-500/50 bg-amber-500/10"),children:[(0,n.jsxs)("p",{className:"font-medium",children:["Head measures ",N(eG.value,eG.unit),". Required"," ",N(eG.rangeMin,eG.unit)," to"," ",N(eG.rangeMax,eG.unit),"."," ",eG.pass?"That is inside the range.":`Out by ${N(eG.missBy,eG.unit)}.`]}),(0,n.jsxs)("p",{className:"mt-1 text-xs text-muted-foreground",children:["Measured on the ",eW.width," by ",eW.height," pixels the file will contain, where the head takes up ",eG.headOutputPx," of them. Checked here:"," ",eG.checked.join(", "),". Nothing else on the photo is being judged."]}),(0,n.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2",children:[(0,n.jsx)(a.$,{type:"button",size:"sm",onClick:()=>eV(),children:"Fit the head"}),(0,n.jsx)(a.$,{type:"button",size:"sm",variant:"outline",onClick:e8,children:"Measure the background"})]}),e$&&(0,n.jsx)("p",{className:"mt-2 text-xs text-muted-foreground",children:e$})]}),ex&&(0,n.jsxs)("p",{className:"rounded-md border border-input bg-muted/40 p-3 text-xs text-muted-foreground",children:["Background band, ",ex.samples," pixels sampled from the outer"," ",Math.round(100*ex.bandShare),"% of the crop with the head skipped. Average color is red ",Math.round(ex.mean[0]),", green ",Math.round(ex.mean[1]),", blue"," ",Math.round(ex.mean[2]),". Spread is ",ex.sd[0].toFixed(1),", ",ex.sd[1].toFixed(1),","," ",ex.sd[2].toFixed(1),". These are measurements, not a verdict. A spread in the low single figures usually means a flat wall, and a large one usually means a shadow, a pattern or a fold. Nobody publishes a number to test against, so we are not inventing one."]}),(0,n.jsxs)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:[(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-dpi",className:"text-xs",children:"Print resolution"}),(0,n.jsxs)("select",{id:"ppm-dpi",value:J,onChange:e=>G(Number(e.target.value)),className:T,children:[(0,n.jsx)("option",{value:300,children:"300 DPI"}),(0,n.jsx)("option",{value:400,children:"400 DPI"}),(0,n.jsx)("option",{value:600,children:"600 DPI"}),(0,n.jsx)("option",{value:1200,children:"1200 DPI"})]})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsxs)(o.J,{htmlFor:"ppm-angle",className:"text-xs",children:["Straighten ",X.toFixed(1)," deg"]}),(0,n.jsx)("input",{id:"ppm-angle",type:"range",min:-10,max:10,step:.1,value:X,onChange:e=>q(Number(e.target.value)),className:"w-full"})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{className:"text-xs",children:"Selfie flip"}),(0,n.jsx)(a.$,{type:"button",variant:O?"default":"outline",className:"w-full",onClick:()=>Y(e=>!e),children:O?"Flipped":"Flip"})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-fmt",className:"text-xs",children:"File type"}),(0,n.jsxs)("select",{id:"ppm-fmt",value:en,onChange:e=>er("image/png"===e.target.value?"image/png":"image/jpeg"),className:T,children:[(0,n.jsx)("option",{value:"image/jpeg",children:"JPEG"}),(0,n.jsx)("option",{value:"image/png",children:"PNG"})]})]})]}),(0,n.jsxs)("p",{className:"text-xs text-muted-foreground",children:["At ",J," DPI this size wants ",eW.width," by ",eW.height," pixels, and your crop is currently ",Math.round(_.w)," by ",Math.round(_.h),"."," ",eX?"That is fewer pixels than the size needs, so enlarging it would invent detail rather than find it.":"That is enough to fill it without stretching."," ","The resolution is written into the file itself, so a print shop knows how big to make it."]}),(0,n.jsxs)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-3",children:["image/jpeg"===en&&(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsxs)(o.J,{htmlFor:"ppm-q",className:"text-xs",children:["JPEG quality ",Math.round(100*ea)]}),(0,n.jsx)("input",{id:"ppm-q",type:"range",min:40,max:95,value:Math.round(100*ea),onChange:e=>es(Number(e.target.value)/100),className:"w-full"})]}),"image/jpeg"===en&&(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-target",className:"text-xs",children:"Target size in KB"}),(0,n.jsx)(s.p,{id:"ppm-target",inputMode:"numeric",placeholder:"optional",value:eo,onChange:e=>el(e.target.value)})]}),(0,n.jsx)("div",{className:"flex items-end",children:(0,n.jsx)(a.$,{type:"button",className:"w-full",disabled:eM,onClick:te,children:eM?"Working":"Download the photo"})})]}),eE.fileBytes&&(0,n.jsxs)("p",{className:"text-xs text-muted-foreground",children:["The source for this size states an upload range of ",(0,A.z)(eE.fileBytes.min)," to"," ",(0,A.z)(eE.fileBytes.max),". Type a target above and the quality is searched for you rather than guessed at."]}),(0,n.jsxs)("label",{className:"flex items-start gap-2 text-xs text-muted-foreground",children:[(0,n.jsx)("input",{type:"checkbox",checked:ep,onChange:e=>eg(e.target.checked),className:"mt-0.5"}),(0,n.jsx)("span",{children:"Export even when the measurement fails. Sometimes you want the file anyway. Ticking this does not make the photo compliant, it only stops us blocking the download."})]}),(0,n.jsxs)("div",{className:"space-y-2 rounded-md border border-input p-3",children:[(0,n.jsx)("p",{className:"text-sm font-medium",children:"Print sheet"}),(0,n.jsxs)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:[(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsx)(o.J,{htmlFor:"ppm-sheet",className:"text-xs",children:"Paper"}),(0,n.jsx)("select",{id:"ppm-sheet",value:eh,onChange:e=>eu(e.target.value),className:T,children:w.map(e=>(0,n.jsx)("option",{value:e.id,children:e.label},e.id))})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsxs)(o.J,{htmlFor:"ppm-gutter",className:"text-xs",children:["Gutter ",ed," mm"]}),(0,n.jsx)("input",{id:"ppm-gutter",type:"range",min:0,max:10,value:ed,onChange:e=>ec(Number(e.target.value)),className:"w-full"})]}),(0,n.jsxs)("div",{className:"space-y-1",children:[(0,n.jsxs)(o.J,{htmlFor:"ppm-margin",className:"text-xs",children:["Edge margin ",em," mm"]}),(0,n.jsx)("input",{id:"ppm-margin",type:"range",min:0,max:15,value:em,onChange:e=>ef(Number(e.target.value)),className:"w-full"})]}),(0,n.jsx)("div",{className:"flex items-end",children:(0,n.jsx)(a.$,{type:"button",variant:"secondary",className:"w-full",disabled:eM||eY.copies<1,onClick:tt,children:"Download the sheet"})})]}),(0,n.jsxs)("p",{className:"text-xs text-muted-foreground",children:[eY.copies," copies, ",eY.across," across by ",eY.down," down, on"," ",eq?.label??"the sheet",". That count comes from the paper, the photo size and the gutter, so it changes as you move the sliders. Spare space left over is"," ",eY.spareWmm.toFixed(1)," mm across and ",eY.spareHmm.toFixed(1)," mm down. Print it at 100 percent with fit to page turned off, or every millimeter here is wrong by the time it reaches paper."]})]}),eP&&(0,n.jsxs)("p",{className:"rounded-md border border-input bg-muted/40 p-3 text-xs text-muted-foreground",children:["Saved: ",eP]}),(0,n.jsx)("p",{className:"text-xs text-muted-foreground",children:"This measures the head against the size you picked and reports the background as numbers. It cannot tell you whether the photo will be accepted. Shadows, glare on glasses, hair across the face, expression, headwear and focus are all grounds for rejection and none of them are geometry. We are not affiliated with any passport office."}),(0,n.jsx)("p",{className:"text-xs text-muted-foreground",children:"A shared link carries your size, resolution and sheet settings. It does not carry the photograph, and it never will."})]})]}),!e&&(0,n.jsxs)("div",{className:"rounded-md border border-input bg-muted/40 p-4 text-sm text-muted-foreground",children:[(0,n.jsx)("p",{children:"Every size in the picker shows the government page the numbers came from and the date we read it. There is no United States preset, because the State Department page would not load for us and we are not going to type in a
1number we could not check. Use your own numbers for a 2 by 2 inch photo and the tool measures against those instead."}),(0,n.jsxs)("p",{className:"mt-2",children:["Sizes on offer:"," ",m.map(e=>`${e.label} at ${e.short}`).join(", "),", plus anything you type yourself in millimeters or inches. Head range for the UK printed size works out at"," ",(100*ta.min).toFixed(1),"% to ",(100*ta.max).toFixed(1),"% of the picture height, and that percentage is calculated from the millimeters rather than stored, so it cannot drift away from its source."]}),(0,n.jsxs)("p",{className:"mt-2",children:["One more number worth knowing before you start: ",p(2,"in").toFixed(1)," mm is exactly two inches. Plenty of sites round that to 51."]})]}),(0,n.jsx)(h.ToolActions,{getParams:e_,title:"Passport Photo Maker"})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.