*{flex:1} button{padding:11px;border:none;border-radius:10px;font-size:14px;font-weight:700;cursor:pointer;width:100%;margin-bottom:6px} .bp{background:#0f4a2e;color:#fff}.bs{background:#fff;color:#0f4a2e;border:1.5px solid #0f4a2e} .msg{padding:8px;border-radius:8px;margin:6px 0;font-size:12px}.msg.ok{background:#d4edda;color:#155724}.msg.er{background:#f8d7da;color:#721c24}.msg.info{background:#fff3cd;color:#856404} .snap{display:flex;align-items:center;justify-content:center;gap:8px;border-radius:12px;padding:14px;font-size:15px;font-weight:700;cursor:pointer;border:none;width:100%;margin-bottom:8px} .preview{width:100%;max-height:300px;object-fit:contain;border-radius:8px;margin:8px 0;border:1px solid #eaeaea;display:none} .spinner{display:inline-block;width:18px;height:18px;border:3px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}} table{width:100%;border-collapse:collapse;font-size:13px}th{background:#f0faf4;padding:8px 6px;text-align:left;font-weight:700;color:#0f4a2e;border-bottom:2px solid #c8e6c9}td{padding:6px;border-bottom:1px solid #f0f0f0}td input{padding:6px;margin:0;font-size:12px;border:1px solid #e0e0e0;border-radius:6px;width:100%}.del{color:#c0392b;cursor:pointer;font-weight:700;font-size:18px;text-align:center} .cnt{font-size:12px;color:#888;font-weight:400} .tabs{display:flex;gap:4px;margin-bottom:8px}.tabs button{flex:1;padding:8px;border:1.5px solid #e0e0e0;border-radius:8px;background:#fafafa;font-weight:600;font-size:12px;color:#555}.tabs button.on{background:#0f4a2e;color:#fff;border-color:#0f4a2e} #pin{position:fixed;inset:0;background:linear-gradient(145deg,#0f4a2e,#1B6B4A 50%,#0f4a2e);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:200;color:#fff} #pin.hide{display:none} #pin h1{font-size:24px}#pin p{font-size:11px;opacity:.6;margin:4px 0 28px} #pin input{width:180px;padding:12px;font-size:26px;text-align:center;border:2px solid rgba(255,255,255,.25);border-radius:14px;background:rgba(255,255,255,.08);color:#fff;letter-spacing:14px;outline:none;-webkit-text-security:disc} #pin .ub{margin-top:14px;padding:11px 44px;background:#fff;color:#0f4a2e;border:none;border-radius:12px;font-size:15px;font-weight:700;cursor:pointer;width:auto} #pin .er{color:#ffd700;font-size:11px;margin-top:10px;min-height:14px}

Reel Label Office

Enter PIN to access

var GKEY="AIzaSyCl8now0usLtADlCtmAIl40ruO-zq7DYNQ"; var SURL="https://script.google.com/macros/s/AKfycby__Fs9eQg7SKkFxU9QsjpOQMTO-_D4a1SXa6kEnKz0L3s_3h1laqDGgFbOKkz0kt3n/exec"; var WCC={18:[139,0,0],19:[165,42,42],20:[178,34,34],21:[205,92,92],22:[220,20,60],24:[210,105,30],25:[204,85,0],26:[230,126,34],27:[212,120,26],28:[218,165,32],30:[184,134,11],31:[155,135,12],32:[128,128,0],33:[107,142,35],34:[85,107,47],36:[34,139,34],37:[46,139,87],38:[32,178,170],39:[0,139,139],40:[0,128,128],42:[70,130,180],43:[65,105,225],44:[0,0,205],45:[0,0,139],46:[25,25,112],48:[75,0,130],49:[106,13,173],50:[128,0,128],51:[139,0,139],52:[199,21,133]}; var CM2IN={'81':32,'81.00':32,'86.5':34,'86.50':34,'91.5':36,'91.50':36,'96.5':38,'96.50':38}; var aPin='',rid=0; document.getElementById('pinIn').addEventListener('keyup',function(e){if(e.key==='Enter')doPin()}); function doPin(){var p=document.getElementById('pinIn').value.trim();if(p==='4872'||p==='6263'){aPin=p;document.getElementById('pin').classList.add('hide');document.getElementById('app').style.display='block'}else{document.getElementById('pinEr').textContent='Wrong PIN';document.getElementById('pinIn').value=''}} function setTab(n){document.querySelectorAll('.tabs button').forEach(function(b,i){b.classList.toggle('on',i===n)});document.getElementById('tab0').style.display=n===0?'block':'none';document.getElementById('tab1').style.display=n===1?'block':'none'} function addRow(off,rno,bf,gsm,w,wt,pt){rid++;var tr=document.createElement('tr');var ptOpts=['Kraft','VK','Duplex','Imported Kraft','WKL','Others'];var ptSel='';tr.innerHTML=''+ptSel+'x';tr.querySelectorAll('input,select').forEach(function(el,ei,all){el.addEventListener('keydown',function(e){if((e.key==='Tab'||e.key==='Enter')&&ei===all.length-2&&!tr.nextElementSibling){e.preventDefault();addRow();document.getElementById('tb').lastElementChild.querySelector('input').focus();}});});;document.getElementById('tb').appendChild(tr);upCnt()} function upCnt(){var rows=document.getElementById('tb').querySelectorAll('tr'),f=0,tw=0;rows.forEach(function(r){var inp=r.querySelectorAll('input');if(inp[0]&&inp[0].value.trim()){f++;tw+=parseInt(inp[5]&&inp[5].value)||0}});document.getElementById('cnt').textContent=f?'('+f+' reels)':'';document.getElementById('totalWt').textContent=tw?tw.toLocaleString()+' KG':'0 KG';// update row numbers document.getElementById('tb').querySelectorAll('tr').forEach(function(r,i){var n=r.querySelector('.rn');if(n)n.textContent=i+1;});} function cmToIn(v){v=String(v).trim();if(CM2IN[v])return CM2IN[v];var n=parseFloat(v);if(n>=70&&n<=100)return Math.round(n/2.54);return n} function onPhoto(inp){if(!inp.files||!inp.files[0])return;var file=inp.files[0];document.getElementById('snapTxt').innerHTML=' Reading...';document.getElementById('ocrMsg').innerHTML='
Processing... 5-10 seconds
';if(file.type==='application/pdf'){var reader=new FileReader();reader.onload=function(e){var pdfData=new Uint8Array(e.target.result);pdfjsLib.GlobalWorkerOptions.workerSrc='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';pdfjsLib.getDocument({data:pdfData}).promise.then(function(pdf){pdf.getPage(1).then(function(page){page.getTextContent().then(function(tc){var items=tc.items;var textByY={};items.forEach(function(it){var yKey=Math.round(it.transform[5]);if(!textByY[yKey])textByY[yKey]=[];textByY[yKey].push({x:it.transform[4],str:it.str})});var rows=Object.keys(textByY).sort(function(a,b){return b-a}).map(function(y){return textByY[y].sort(function(a,b){return a.x-b.x}).map(function(it){return it.str}).join(' ')});var text=rows.join('\n');(function(){var wds=text.trim().split(/\s+/).filter(function(w){return w.length>0});var avgLen=wds.reduce(function(s,w){return s+w.length},0)/(wds.length||1);var garbled=avgLen<1.8;var parsed=(!garbled&&text.replace(/\s/g,'').length>50)?parseOCR(text):[];if(parsed.length>0){document.getElementById('snapTxt').textContent='Camera';document.getElementById('tb').innerHTML='';parsed.forEach(function(r){addRow(r.off,r.rollNo||'',r.bf||16,r.gsm||'120',r.w,r.wt,r.pt||'Kraft')});addRow();addRow();document.getElementById('ocrMsg').innerHTML='
Found '+parsed.length+' reels from PDF!
';}else{if(garbled)document.getElementById('ocrMsg').innerHTML='
Garbled PDF text layer detected — switching to Vision OCR...
';var vp2=page.getViewport({scale:3.0});var cv2=document.getElementById('cv'),ctx2=cv2.getContext('2d');cv2.width=vp2.width;cv2.height=vp2.height;page.render({canvasContext:ctx2,viewport:vp2}).promise.then(function(){document.getElementById('preview').src=cv2.toDataURL('image/jpeg',0.9);document.getElementById('preview').style.display='block';callV(cv2.toDataURL('image/jpeg',0.85).split(',')[1]);});}})()})})}).catch(function(err){document.getElementById('snapTxt').textContent='Camera';document.getElementById('ocrMsg').innerHTML='
PDF error: '+err.message+'
'})};reader.readAsArrayBuffer(file)}else{document.getElementById('preview').src=URL.createObjectURL(file);document.getElementById('preview').style.display='block';var reader=new FileReader();reader.onload=function(e){var img=new Image();img.onload=function(){var cv=document.getElementById('cv'),ctx=cv.getContext('2d');var s=Math.min(1600/img.width,1600/img.height,1);cv.width=img.width*s;cv.height=img.height*s;ctx.drawImage(img,0,0,cv.width,cv.height);callV(cv.toDataURL('image/jpeg',0.85).split(',')[1])};img.src=e.target.result};reader.readAsDataURL(file)}} function callV(b64){if(!GKEY){document.getElementById('ocrMsg').innerHTML='
Add your Gemini API key in the code (GKEY variable)
';document.getElementById('snapTxt').textContent='Camera';return;}document.getElementById('ocrMsg').innerHTML='
Reading with Gemini AI...
';var prompt='This is a paper reel packing slip. Extract every reel as a JSON array. Each object must have: rollNo (string, the reel/roll number exactly as printed), gsm (number), bf (number, the BF value, default 16 if not shown), width (number in inches, convert CM to inches: 81=32 86.5=34 91.5=36 96.5=38), weight (number in kg), paperType (string: Kraft/VK/Duplex/Imported Kraft/WKL/Others). Return ONLY the JSON array, no explanation.';fetch('https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key='+GKEY,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({contents:[{parts:[{inlineData:{mimeType:'image/jpeg',data:b64}},{text:prompt}]}]})}).then(function(r){if(!r.ok)throw new Error('HTTP '+r.status);return r.json();}).then(function(result){document.getElementById('snapTxt').textContent='Camera';var raw=result.candidates&&result.candidates[0]&&result.candidates[0].content&&result.candidates[0].content.parts&&result.candidates[0].content.parts[0]&&result.candidates[0].content.parts[0].text||'';var clean=raw.replace(/```json|```/g,'').trim();try{var arr=JSON.parse(clean);if(!Array.isArray(arr)||!arr.length)throw new Error('empty');document.getElementById('tb').innerHTML='';arr.forEach(function(r){addRow(r.rollNo||'',r.rollNo||'',r.bf||16,String(r.gsm||120),r.width||r.w||0,r.weight||r.wt||0,r.paperType||'Kraft');});addRow();addRow();document.getElementById('ocrMsg').innerHTML='
✓ Gemini found '+arr.length+' reels
';document.getElementById('pasteBox').value=clean;}catch(e){document.getElementById('ocrMsg').innerHTML='
Could not parse Gemini response. Raw text in Quick Paste.
';document.getElementById('pasteBox').value=clean;setTab(0);}}).catch(function(err){document.getElementById('snapTxt').textContent='Camera';var msg=err.message.match(/Load failed|Failed to fetch|NetworkError/i)?'Network error — check API key and connection':err.message;document.getElementById('ocrMsg').innerHTML='
Gemini error: '+msg+'
';})}*{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,sans-serif;background:#f0f2f5;padding:10px;max-width:700px;margin:0 auto} h1{font-size:20px;color:#0f4a2e;margin-bottom:2px}.sub{font-size:11px;color:#888;margin-bottom:12px} .card{background:#fff;border-radius:12px;padding:14px;margin-bottom:10px;border:1px solid #eaeaea}.card h3{font-size:14px;font-weight:700;color:#0f4a2e;margin-bottom:8px} label{font-size:12px;font-weight:600;color:#555;display:block;margin-bottom:2px} input,select,textarea{width:100%;padding:9px;border:1.5px solid #e0e0e0;border-radius:8px;font-size:13px;margin-bottom:6px}input:focus,textarea:focus,select:focus{border-color:#0f4a2e;outline:none} textarea{font-family:monospace;font-size:12px;line-height:1.5} .row{display:flex;gap:8px}.row>*{flex:1} button{padding:11px;border:none;border-radius:10px;font-size:14px;font-weight:700;cursor:pointer;width:100%;margin-bottom:6px} .bp{background:#0f4a2e;color:#fff}.bs{background:#fff;color:#0f4a2e;border:1.5px solid #0f4a2e} .msg{padding:8px;border-radius:8px;margin:6px 0;font-size:12px}.msg.ok{background:#d4edda;color:#155724}.msg.er{background:#f8d7da;color:#721c24}.msg.info{background:#fff3cd;color:#856404} .snap{display:flex;align-items:center;justify-content:center;gap:8px;border-radius:12px;padding:14px;font-size:15px;font-weight:700;cursor:pointer;border:none;width:100%;margin-bottom:8px} .preview{width:100%;max-height:300px;object-fit:contain;border-radius:8px;margin:8px 0;border:1px solid #eaeaea;display:none} .spinner{display:inline-block;width:18px;height:18px;border:3px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}} table{width:100%;border-collapse:collapse;font-size:13px}th{background:#f0faf4;padding:8px 6px;text-align:left;font-weight:700;color:#0f4a2e;border-bottom:2px solid #c8e6c9}td{padding:6px;border-bottom:1px solid #f0f0f0}td input{padding:6px;margin:0;font-size:12px;border:1px solid #e0e0e0;border-radius:6px;width:100%}.del{color:#c0392b;cursor:pointer;font-weight:700;font-size:18px;text-align:center} .cnt{font-size:12px;color:#888;font-weight:400} .tabs{display:flex;gap:4px;margin-bottom:8px}.tabs button{flex:1;padding:8px;border:1.5px solid #e0e0e0;border-radius:8px;background:#fafafa;font-weight:600;font-size:12px;color:#555}.tabs button.on{background:#0f4a2e;color:#fff;border-color:#0f4a2e} #pin{position:fixed;inset:0;background:linear-gradient(145deg,#0f4a2e,#1B6B4A 50%,#0f4a2e);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:200;color:#fff} #pin.hide{display:none} #pin h1{font-size:24px}#pin p{font-size:11px;opacity:.6;margin:4px 0 28px} #pin input{width:180px;padding:12px;font-size:26px;text-align:center;border:2px solid rgba(255,255,255,.25);border-radius:14px;background:rgba(255,255,255,.08);color:#fff;letter-spacing:14px;outline:none;-webkit-text-security:disc} #pin .ub{margin-top:14px;padding:11px 44px;background:#fff;color:#0f4a2e;border:none;border-radius:12px;font-size:15px;font-weight:700;cursor:pointer;width:auto} #pin .er{color:#ffd700;font-size:11px;margin-top:10px;min-height:14px}

Reel Label Office

Enter PIN to access