#target illustrator if (app.documents.length === 0) { alert("No document open"); exit(); } var doc = app.activeDocument; // ================= UI ================= var win = new Window("dialog", "CTP Optimizer v3.2 – Mixed Calculation"); win.alignChildren = "fill"; // Calculation Mode var pMode = win.add("panel", undefined, "Calculation Mode"); var modeDesign = pMode.add("radiobutton", undefined, "Design Object Mode"); var modeTag = pMode.add("radiobutton", undefined, "Tag Size Mode"); modeDesign.value = true; // Sheet Capacity Option var pCap = win.add("panel", undefined, "Sheet Capacity"); var capManual = pCap.add("radiobutton", undefined, "Manual"); var capAuto = pCap.add("radiobutton", undefined, "Auto (from tag size)"); capAuto.value = true; pCap.add("statictext", undefined, "Capacity:"); var capInput = pCap.add("edittext", undefined, "12"); capInput.characters = 5; // Sheet / Tag Panel var pSheet = win.add("panel", undefined, "Sheet / Tag Size"); var sheetInput = pSheet.add("edittext", undefined, "11x14 in"); sheetInput.characters = 15; var tagWidth = pSheet.add("edittext", undefined, "4"); tagWidth.characters = 5; var tagHeight= pSheet.add("edittext", undefined, "6"); tagHeight.characters = 5; var unitDrop = pSheet.add("dropdownlist", undefined, ["mm","cm","in"]); unitDrop.selection = 0; // Gap & Margin var pMargin = win.add("panel", undefined, "Margins & Gap (mm)"); pMargin.orientation = "grid"; pMargin.add("statictext", undefined, "Left"); var mL = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Right"); var mR = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Top"); var mT = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Bottom"); var mB = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Gap"); var gapInput = pMargin.add("edittext", undefined, "5"); // Quantity Input var pQty = win.add("panel", undefined, "Mixed Quantity (Size-Qty)"); var qtyInput = pQty.add("edittext", undefined, "XS-500\nM-800\nL-500\nXL-200\nXXL-100",{multiline:true}); qtyInput.preferredSize.height = 120; // Result Panel var pRes = win.add("panel", undefined, "Result"); var resTxt = pRes.add("edittext", undefined, "", {multiline:true, readonly:true}); resTxt.preferredSize.height = 220; // Buttons var btns = win.add("group"); var calcBtn = btns.add("button", undefined, "Calculate"); var copyBtn = btns.add("button", undefined, "Copy"); var pdfBtn = btns.add("button", undefined, "Export PDF"); btns.add("button", undefined, "Close", {name:"cancel"}); // ================= FUNCTIONS ================= function parseSheet(str){ var unit = "in"; if (/mm/i.test(str)) unit="mm"; if (/cm/i.test(str)) unit="cm"; var n = str.match(/([\d\.]+)\s*x\s*([\d\.]+)/i); if(!n) return null; var w = parseFloat(n[1]); var h = parseFloat(n[2]); if(unit=="mm"){ w*=2.8346; h*=2.8346; } else if(unit=="cm"){ w*=28.346; h*=28.346; } else{ w*=72; h*=72; } return {w:w,h:h}; } function tagSizeToPt(w,h,unit){ if(unit=="mm"){ return {w:w*2.8346,h:h*2.8346}; } else if(unit=="cm"){ return {w:w*28.346,h:h*28.346}; } else{ return {w:w*72,h:h*72}; } } function buildMix(qtyMap, capacity){ var sheets=[]; var totalQty=0; for(var k in qtyMap){ totalQty+=qtyMap[k]; } var maxWaste=Math.ceil(totalQty*0.05); // max 5% waste while(true){ var sheet={}; var filled=0; // greedy fill smallest qty first var keys=Object.keys(qtyMap).sort(function(a,b){return qtyMap[a]-qtyMap[b];}); for(var i=0;i0 && filled