Files
bambuddy/static/assets/GcodeToolpathViewer-D4M17KI8.js
T
maziggy 89a9a81195 Compress and cache the web interface's asset files (#3175)
/assets was served uncompressed and without Cache-Control, so phones
downloaded the full 11 MB bundle and revalidated it on every load. Text
assets are now gzip-compressed once per file and kept in memory, and
files with a content hash in their name are marked immutable. The
pdf.js runtime data has no hash and is revalidated instead.

-----

Load pages and languages when they are needed (#3175)

Every page and all 15 languages were one 11 MB script. Pages are now
separate files loaded on first open, and only English is bundled; the
language in use loads before the first render. A tab left on an older
build reloads once when a file is gone, after the server answers
again, so a kiosk is never left on the browser's connection error page.
The service worker serves hashed files from its cache and drops the
previous build's files.
2026-10-05 14:59:11 +02:00

129 lines
27 KiB
JavaScript

import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,l as r,w as i}from"./client-BdOyoZJz.js";import{t as a}from"./createLucideIcon-Yo2YoYjm.js";import{t as o}from"./loader-circle-CB4leTZa.js";import{A as s,O as c,_ as l,a as u,i as d,l as f,m as p,p as m,r as h,t as g,w as _}from"./OrbitControls-Bbqf07B-.js";var v=a(`file-exclamation-point`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),y=e(n(),1),b={travel:0,wall:1,sparseInfill:2,solidInfill:3,skirt:4,support:5,raft:6,gapFill:7,thinWall:8,bridge:9,ironing:10,primeTower:11},x={"outer wall":b.wall,"inner wall":b.wall,perimeter:b.wall,"external perimeter":b.wall,"overhang wall":b.bridge,"overhang perimeter":b.bridge,"sparse infill":b.sparseInfill,"internal infill":b.sparseInfill,"solid infill":b.solidInfill,"internal solid infill":b.solidInfill,"top surface":b.solidInfill,"top solid infill":b.solidInfill,"bottom surface":b.solidInfill,skirt:b.skirt,"skirt/brim":b.skirt,brim:b.skirt,support:b.support,"support material":b.support,"support interface":b.support,"support material interface":b.support,"support transition":b.support,raft:b.raft,"gap fill":b.gapFill,"gap infill":b.gapFill,"thin wall":b.thinWall,"floating vertical shell":b.solidInfill,"internal bridge":b.bridge,"bottom shell":b.solidInfill,bridge:b.bridge,"bridge infill":b.bridge,"internal bridge infill":b.bridge,ironing:b.ironing,"prime tower":b.primeTower,"wipe tower":b.primeTower,custom:b.wall},S=8,C=Math.PI*2,w=.02,T=256,E=15,D=class{data=new Float32Array(1024*S);count=0;widths=[];push(e,t,n,r,i,a,o,s,c){if((this.count+1)*S>this.data.length){let e=new Float32Array(this.data.length*2);e.set(this.data),this.data=e}let l=this.count*S;this.data[l]=e,this.data[l+1]=t,this.data[l+2]=n,this.data[l+3]=r,this.data[l+4]=i,this.data[l+5]=a,this.data[l+6]=o,this.data[l+7]=c,this.count+=1,this.widths.push(s)}get length(){return this.count}toFloat32Array(){return this.data.slice(0,this.count*S)}};function O(e){let t,n=0;for(let[r,i]of e)i>n&&(t=r,n=i);return t}function k(e,t){let n=e.indexOf(t);if(n<0)return;let r=Number.parseFloat(e.slice(n+1));return Number.isFinite(r)?r:void 0}function A(e){let t=[],n=0,r=0,i=0,a=0,o=!1,s=b.wall,c=0,l=new Map,u=0,d=0,f=new D,p=0,m=!1,h=null,g=!1,_=0,v=!1,y=1/0,S=1/0,A=1/0,j=-1/0,M=-1/0,N=-1/0,P=()=>{f.length!==0&&(t.push({z:p,paths:f.toFloat32Array(),widths:f.widths}),f=new D,g=!1,h!==null&&(p=h,h=null))},F=(e,t,a,o)=>{if(o){if(!m&&g&&a!==p&&P(),g||(p=a,h=null),g=!0,!v){v=!0,n=e,r=t,i=a;return}f.push(n,r,i,s,e,t,a,c,_),u+=1,e<y&&(y=e),t<S&&(S=t),a<A&&(A=a),e>j&&(j=e),t>M&&(M=t),a>N&&(N=a)}else v&&(f.push(n,r,i,b.travel,e,t,a,0,_),d+=1);n=e,r=t,i=a,v=!0};for(let t of e.split(`
`)){let e=t.trim();if(e.length===0)continue;if(e.charCodeAt(0)===59){let t=e.slice(1).trimStart(),n=t.indexOf(`:`),r=(n>=0?t.slice(0,n):t).trim().toUpperCase(),i=n>=0?t.slice(n+1).trim():``;if(r===`FEATURE`||r===`TYPE`)s=x[i.toLowerCase()]??b.wall;else if(r===`LINE_WIDTH`||r===`WIDTH`){let e=Number.parseFloat(i);Number.isFinite(e)&&e>0&&(c=e,l.set(e,(l.get(e)??0)+1))}else if(r===`CHANGE_LAYER`||r===`LAYER_CHANGE`)m=!0,P();else if(r===`Z_HEIGHT`||r===`Z`){let e=Number.parseFloat(i);Number.isFinite(e)&&(h=e)}continue}if(e.startsWith(`M83`)){o=!0;continue}if(e.startsWith(`M82`)){o=!1;continue}if(e.startsWith(`G92`)){let t=k(e,`E`);t!==void 0&&(a=t);continue}if(e.charCodeAt(0)===84){let t=Number.parseInt(e.slice(1),10);Number.isFinite(t)&&t>=0&&t<=E&&(_=t);continue}let u=e.startsWith(`G2 `)||e.startsWith(`G3 `)||e.startsWith(`G2`)||e.startsWith(`G3`),d=e.startsWith(`G1`)||e.startsWith(`G0`);if(!d&&!u||u&&!/^G[23](\s|$)/.test(e)||d&&!/^G[01](\s|$)/.test(e))continue;let f=k(e,`X`)??n,p=k(e,`Y`)??r,g=k(e,`Z`)??i,v=k(e,`E`),y=0;v!==void 0&&(y=o?v:v-a,a=v);let S=y>0;if(u){let t=k(e,`I`)??0,a=k(e,`J`)??0,o=n+t,s=r+a,c=Math.hypot(t,a);if(c>0){let t=Math.atan2(r-s,n-o),a=Math.atan2(p-s,f-o),l=e.charCodeAt(1)===50,u=a-t;if(l){for(;u>=0;)u-=C;for(;u<-C;)u+=C}else{for(;u<=0;)u+=C;for(;u>C;)u-=C}if(f===n&&p===r){let t=Math.max(1,Math.round(k(e,`P`)??1));u=(l?-C:C)*t}let d=2*Math.acos(Math.max(-1,Math.min(1,1-w/c))),m=Math.max(1,Math.min(T,Math.ceil(Math.abs(u)/Math.max(d,.001))));for(let e=1;e<=m;e+=1){let n=e/m,r=t+u*n;F(o+c*Math.cos(r),s+c*Math.sin(r),i+(g-i)*n,S)}continue}}(f!==n||p!==r||g!==i)&&F(f,p,g,S)}return P(),{layers:t,segmentCount:u,travelCount:d,defaultWidth:O(l)??.42,bounds:u>0?{min:[y,S,A],max:[j,M,N]}:null}}function j(e){return e.map(e=>{let t=e.paths.slice();for(let e=0;e<t.length;e+=S)t[e+3]!==b.travel&&(t[e+3]=Math.min(t[e+7]+1,E));return{...e,paths:t}})}function M(e,t){if(t.size===0)return e;let n=[];for(let r of e){let e=new D;for(let n=0;n<r.paths.length;n+=S){let i=r.paths[n+3];t.has(i)||e.push(r.paths[n],r.paths[n+1],r.paths[n+2],i,r.paths[n+4],r.paths[n+5],r.paths[n+6],r.widths[n/S]??0,r.paths[n+7])}n.push({...r,paths:e.toFloat32Array(),widths:e.widths})}return n}var N=[0,1,2,0,2,3,0,3,4,0,4,5,0,5,6,0,6,1,5,4,7,5,7,6],P={0:[.42,.45,.5],1:[.85,.51,.17],2:[.21,.45,.76],3:[.35,.75,.85],4:[.16,.68,.4],5:[.66,.42,.85],6:[.55,.45,.35],7:[.95,.85,.25],8:[.9,.35,.65],9:[.9,.25,.25],10:[.6,.82,.55],11:[.3,.72,.7]};function F(e){let t=Math.round(e[0]*255),n=Math.round(e[1]*255),r=Math.round(e[2]*255);return t<<16|n<<8|r}function I(e,t){let n=e.length,r=t>0?t:.42,i=Array(n);for(let t=0;t<n;t++){let n=e[t].z;i[t]=Math.max(.02,t===0?n:n-e[t-1].z)}let a=[],o=[],s=[],c=[],l=[],u=[],d=[],f=[],p=[],m=[],h=new Float64Array(16),g=[],_=[],v=-1,y=0,b=0,x=0,S=-1,C=0,w=1e-4,T=(e,t,n,r,i,p)=>(a.push(e),o.push(t),s.push(n),u.push(r),c.push(i),l.push(p),d.push(C),f.push(!1),a.length-1);for(let t=0;t<n;t++){let n=e[t].paths,a=e[t].widths,o=i[t];if(C=t,n)for(let e=0;e<n.length;e+=8){let i=n[e+3],s=n[e],c=n[e+1],l=n[e+2],u=n[e+4],d=n[e+5],C=n[e+6];if(i===0){g.push(s,c,l,u,d,C),_.push(t);continue}let E=a&&a[e/8]>0?a[e/8]:r;i<16&&(h[i]+=Math.hypot(u-s,d-c));let D;v>=0&&S===i&&Math.abs(y-s)<w&&Math.abs(b-c)<w&&Math.abs(x-l)<w?(D=v,T(u,d,C,i,o,E)):(D=T(s,c,l,i,o,E),T(u,d,C,i,o,E)),f[D]=!0,v=D+1,y=u,b=d,x=C,S=i,p.push(D),m.push(t)}}let E=a.length,D=p.length,O=new Float32Array(E*4),k=new Float32Array(E*4),A=0,j=!1,M=1/0,N=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<E;e++){let t=c[e],n=a[e],r=o[e],i=s[e]-.5*t;O[e*4]=n,O[e*4+1]=r,O[e*4+2]=i;let d=e>0&&f[e-1],p=f[e],m=0;if(d||p){let t=d?a[e]-a[e-1]:0,n=d?o[e]-o[e-1]:0,r=d?s[e]-s[e-1]:0,i=p?a[e+1]-a[e]:0,c=p?o[e+1]-o[e]:0,l=p?s[e+1]-s[e]:0;m=Math.atan2(t*c-n*i,t*i+n*c+r*l)}k[e*4]=t,k[e*4+1]=l[e],k[e*4+2]=m,k[e*4+3]=F(P[u[e]]||P[1]),(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(m))&&(j=!0),A=Math.max(A,Math.abs(n),Math.abs(r),Math.abs(i)),n<M&&(M=n),n>L&&(L=n),r<N&&(N=r),r>R&&(R=r),i<I&&(I=i),i>z&&(z=i)}let B=new Uint32Array(D*4);for(let e=0;e<D;e++)B[e*4]=p[e],B[e*4+1]=m[e];let V={vType:new Uint8Array(E),vWidth:new Float32Array(E),vHeight:new Float32Array(E),vLayer:new Int32Array(E)};for(let e=0;e<E;e++)V.vType[e]=u[e],V.vWidth[e]=l[e],V.vHeight[e]=c[e],V.vLayer[e]=d[e];let H=new Int32Array(n+1);{let e=0;for(let t=0;t<n;t++){for(;e<D&&m[e]===t;)e++;H[t+1]=e}}let U=_.length,W=new Float32Array(U*6);for(let e=0;e<W.length;e++)W[e]=g[e];for(let e=0;e<W.length;e+=3){let t=W[e],n=W[e+1],r=W[e+2];t<M&&(M=t),t>L&&(L=t),n<N&&(N=n),n>R&&(R=n),r<I&&(I=r),r>z&&(z=r)}let G=new Int32Array(n+1);{let e=0;for(let t=0;t<n;t++){for(;e<U&&_[e]===t;)e++;G[t+1]=e}}let ee=E+U>0?{min:[M,N,I],max:[L,R,z]}:null;return{position:O,hwa:k,segIndex:B,nV:E,nSeg:D,layerSegPrefix:H,travelPos:W,travelPrefix:G,nTrav:U,layerCount:n,maxAbs:A,hasNaN:j,meta:V,typeLengths:h,bbox:ee}}var L=[[11,44,122],[19,89,133],[28,136,145],[4,214,15],[170,242,0],[252,249,3],[245,206,10],[227,136,32],[209,104,48],[194,82,60],[148,38,22]].map(e=>[e[0]/255,e[1]/255,e[2]/255]);function R(e,t,n,r){let i=r.length;if(!(n>t))return r[0];let a=(n-t)/(i-1),o=(e-t)/a,s=Math.max(0,Math.min(i-1,Math.floor(o))),c=Math.max(0,Math.min(i-1,s+1)),l=o-s,u=r[s],d=r[c];return[u[0]+(d[0]-u[0])*l,u[1]+(d[1]-u[1])*l,u[2]+(d[2]-u[2])*l]}var z=[{key:`feature`,label:`Feature type`,cont:!1,unit:``},{key:`speed`,label:`Speed`,cont:!0,unit:`mm/s`},{key:`height`,label:`Layer Height`,cont:!0,unit:`mm`},{key:`width`,label:`Line Width`,cont:!0,unit:`mm`},{key:`fan`,label:`Fan Speed`,cont:!0,unit:`%`},{key:`temp`,label:`Temperature`,cont:!0,unit:`°C`}];function B(e,t,n,r){let i=t.vType[n],a=t.vLayer[n],o=a===0;switch(e){case`height`:return t.vHeight[n];case`width`:return t.vWidth[n];case`speed`:return o?r.firstLayerSpeed:r.speedByType[i]??r.speedByType[1];case`fan`:return a<r.closeFanLayers?0:i===9?100:r.fanNormal;case`temp`:return o?r.tempFirst:r.tempNormal;default:return 0}}function V(e,t,n){let{meta:r,nV:i}=e,a=new Float32Array(i*4),o=z.find(e=>e.key===t)||z[0];if(!o.cont){for(let e=0;e<i;e++)a[e*4]=F(P[r.vType[e]]||P[1]);return{color:a,min:0,max:0,viewType:t,label:o.label,unit:o.unit,cont:!1}}let s=1/0,c=-1/0,l=new Float32Array(i);for(let e=0;e<i;e++){let i=B(t,r,e,n);l[e]=i,i<s&&(s=i),i>c&&(c=i)}Number.isFinite(s)||(s=0,c=1);for(let e=0;e<i;e++){let t=R(l[e],s,c,L);a[e*4]=F(t)}return{color:a,min:s,max:c,viewType:t,label:o.label,unit:o.unit,cont:!0}}var H=`
precision highp float;
precision highp int;
precision highp sampler2D;
precision highp usampler2D;
#define POINTY_CAPS
#define FIX_TWISTING
const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);
const float light_top_diffuse = 0.6 * 0.8;
const float light_top_specular = 0.6 * 0.125;
const float light_top_shininess = 20.0;
const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);
const float light_front_diffuse = 0.6 * 0.3;
const float ambient = 0.3;
const float emission = 0.15;
const vec3 UP = vec3(0, 0, 1);
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
uniform vec3 camera_position;
uniform sampler2D position_tex;
uniform sampler2D height_width_angle_tex;
uniform int layer_lo; // 25단계: 이중 슬라이더 하한(레이어). 범위 밖 세그먼트는 셰이더가 O(1) 클립.
uniform int layer_hi; // 상한은 instanceCount 로 컷(레이어 순 정렬).
in float vertex_id_float;
in uint seg_id_a_u; // 인스턴스 어트리뷰트(구 segment_index_tex.r) — 어트리뷰트 fetch 가 texelFetch 보다 쌈
in uint seg_layer_u; // 인스턴스 어트리뷰트(구 segment_index_tex.g)
out vec3 color;
vec3 decode_color(float col) {
int c = int(round(col));
int r = (c >> 16) & 0xFF;
int g = (c >> 8) & 0xFF;
int b = (c >> 0) & 0xFF;
float f = 1.0 / 255.0;
return f * vec3(r, g, b);
}
float lighting(vec3 eye_position, vec3 eye_normal) {
float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);
float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);
float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);
return ambient + top_diffuse + front_diffuse + top_specular + emission;
}
ivec2 tex_coord(sampler2D sampler, int id) {
ivec2 tex_size = textureSize(sampler, 0);
return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);
}
void main() {
int vertex_id = int(vertex_id_float);
int seg_layer = int(seg_layer_u);
if (seg_layer < layer_lo || seg_layer > layer_hi) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; } // 범위 밖 → 클립
int id_a = int(seg_id_a_u);
int id_b = id_a + 1;
vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;
vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_b), 0).xyz;
vec3 line = pos_b - pos_a;
float line_len = length(line);
vec3 line_dir;
if (line_len < 1e-4)
line_dir = vec3(1.0, 0.0, 0.0);
else
line_dir = line / line_len;
vec3 line_right_dir;
if (abs(dot(line_dir, UP)) > 0.9) {
line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));
}
else
line_right_dir = normalize(cross(line_dir, UP));
vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));
const vec2 horizontal_vertical_view_signs_array[16] = vec2[](
vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, 0.0), vec2(0.0, -1.0),
vec2(0.0, -1.0), vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, 0.0),
vec2(0.0, 1.0), vec2(-1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 0.0),
vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(-1.0, 0.0), vec2(0.0, 0.0)
);
int id = vertex_id < 4 ? id_a : id_b;
vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;
vec4 hwa_color = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0); // .xyz=h/w/angle, .w=packed color
vec3 height_width_angle = hwa_color.xyz;
#ifdef FIX_TWISTING
int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;
vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;
vec3 camera_view_dir = normalize(closer_pos - camera_position);
vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, closer_id), 0).xyz;
vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);
#else
vec3 camera_view_dir = normalize(endpoint_pos - camera_position);
vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);
#endif
bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >
abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));
vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];
#ifndef POINTY_CAPS
if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];
#endif
float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));
float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));
float half_height = 0.5 * height_width_angle.x;
float half_width = 0.5 * height_width_angle.y;
vec3 horizontal_dir = half_width * line_right_dir;
vec3 vertical_dir = half_height * line_up_dir;
float horizontal_sign = signs.x * view_right_sign;
float vertical_sign = signs.y * view_top_sign;
vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;
if (vertex_id == 2 || vertex_id == 7) {
float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;
if (height_width_angle.z == 0.0) {
#ifdef POINTY_CAPS
pos += line_dir_sign * line_dir * half_width;
#endif
}
else {
pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);
pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);
}
}
vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;
vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;
vec3 color_base = decode_color(hwa_color.w);
color = color_base * lighting(eye_position, eye_normal);
gl_Position = projection_matrix * vec4(eye_position, 1.0);
}
`,U=`
precision highp float;
in vec3 color;
out vec4 fragment_color;
void main() {
fragment_color = vec4(color, 1.0);
}
`;function W(e,t){let n=(t,n)=>{let r=Math.min(2048,Math.max(1,n)),i=Math.max(1,Math.ceil(n/r)),a=new Float32Array(r*i*4);a.set(t.subarray(0,Math.min(t.length,r*i*4)));let o=new e.DataTexture(a,r,i,e.RGBAFormat,e.FloatType);return o.minFilter=o.magFilter=e.NearestFilter,o.generateMipmaps=!1,o.needsUpdate=!0,o},r=n(t.position,t.nV),i=n(t.hwa,t.nV),a=new e.InstancedBufferGeometry;a.setIndex(N),a.setAttribute(`position`,new e.BufferAttribute(new Float32Array(24),3)),a.setAttribute(`vertex_id_float`,new e.BufferAttribute(new Float32Array([0,1,2,3,4,5,6,7]),1));let o=new e.InstancedInterleavedBuffer(t.segIndex,4);a.setAttribute(`seg_id_a_u`,new e.InterleavedBufferAttribute(o,1,0)),a.setAttribute(`seg_layer_u`,new e.InterleavedBufferAttribute(o,1,1)),a.instanceCount=0;let s=new e.RawShaderMaterial({glslVersion:e.GLSL3,uniforms:{view_matrix:{value:new e.Matrix4},projection_matrix:{value:new e.Matrix4},camera_position:{value:new e.Vector3},position_tex:{value:r},height_width_angle_tex:{value:i},layer_lo:{value:0},layer_hi:{value:t.layerCount}},vertexShader:H,fragmentShader:U,side:e.DoubleSide}),c=new e.Mesh(a,s),l=null;if(t.bbox){let{min:n,max:r}=t.bbox,i=new e.Vector3((n[0]+r[0])/2,(n[1]+r[1])/2,(n[2]+r[2])/2),a=Math.hypot(r[0]-n[0],r[1]-n[1],r[2]-n[2])/2+2;l=new e.Sphere(i,a)}c.frustumCulled=!!l,l&&(a.boundingSphere=l);let u=new e.Matrix4,d=new e.Vector3;c.onBeforeRender=(e,t,n)=>{s.uniforms.projection_matrix.value.copy(n.projectionMatrix),s.uniforms.view_matrix.value.multiplyMatrices(n.matrixWorldInverse,c.matrixWorld),u.copy(c.matrixWorld).invert(),n.getWorldPosition(d).applyMatrix4(u),s.uniforms.camera_position.value.copy(d)};let f=new e.BufferGeometry;f.setAttribute(`position`,new e.BufferAttribute(t.travelPos,3)),f.setDrawRange(0,0);let p=new e.LineSegments(f,new e.LineBasicMaterial({color:7041658}));p.frustumCulled=!!l,p.visible=!1,l&&(f.boundingSphere=l);let m=!1,h=0,g=t.layerCount-1,_=()=>{let e=t.travelPrefix[h],n=t.travelPrefix[g+1];f.setDrawRange(m?e*2:0,m?(n-e)*2:0)},v=(e,n)=>{let r=t.layerCount;h=Math.max(0,Math.min(r-1,e|0)),g=Math.max(h,Math.min(r-1,n|0)),s.uniforms.layer_lo.value=h,s.uniforms.layer_hi.value=g,a.instanceCount=t.layerSegPrefix[g+1],_()};return{mesh:c,travLines:p,setVisibleLayers:e=>v(0,(e|0)-1),setLayerRange:v,setTravelVisible:e=>{m=!!e,p.visible=m,_()},setColors:e=>{let t=i.image.data,n=Math.min(e.length,t.length)/4;for(let r=0;r<n;r++)t[r*4+3]=e[r*4];i.needsUpdate=!0},dispose:()=>{a.dispose(),s.dispose(),r.dispose(),i.dispose(),f.dispose(),p.material.dispose()},nSeg:t.nSeg,layerCount:t.layerCount}}var G=t(),ee=[`filament`,`feature`,`height`,`width`],te=[{type:b.wall,key:`gcodeViewer.feature.wall`,fallback:`Walls`},{type:b.sparseInfill,key:`gcodeViewer.feature.sparseInfill`,fallback:`Sparse infill`},{type:b.solidInfill,key:`gcodeViewer.feature.solidInfill`,fallback:`Solid infill`},{type:b.bridge,key:`gcodeViewer.feature.bridge`,fallback:`Bridge / overhang`},{type:b.support,key:`gcodeViewer.feature.support`,fallback:`Support`},{type:b.skirt,key:`gcodeViewer.feature.skirt`,fallback:`Skirt / brim`},{type:b.gapFill,key:`gcodeViewer.feature.gapFill`,fallback:`Gap fill`},{type:b.ironing,key:`gcodeViewer.feature.ironing`,fallback:`Ironing`},{type:b.primeTower,key:`gcodeViewer.feature.primeTower`,fallback:`Prime tower`}];function ne(e){let t=e.replace(`#`,``),n=t.length===3?t.split(``).map(e=>e+e).join(``):t,r=Number.parseInt(n.slice(0,6),16);return Number.isFinite(r)?r:44610}var re=e=>e?`rgb(${e.map(e=>Math.round(e*255)).join(`,`)})`:`transparent`;function ie(){let e=L;return e.map((t,n)=>`${re(t)} ${(n/(e.length-1)*100).toFixed(0)}%`).join(`, `)}function ae(e){return Number.isFinite(e)?Math.abs(e)<10?e.toFixed(2):e.toFixed(0):`-`}function oe({gcodeUrl:e,buildVolume:t={x:256,y:256,z:256},filamentColors:n,className:a=``}){let{t:b}=i(),x=(0,y.useRef)(null),[S,C]=(0,y.useState)(!0),[w,T]=(0,y.useState)(null),[E,D]=(0,y.useState)(!1),[O,k]=(0,y.useState)(null),N=(n?.length??0)>0,[F,L]=(0,y.useState)(N?`filament`:`feature`),R=(0,y.useRef)(!1);(0,y.useEffect)(()=>{N&&!R.current&&L(`filament`)},[N]);let[z,B]=(0,y.useState)([0,0]),[H,U]=(0,y.useState)(new Set),[oe,se]=(0,y.useState)(new Set),K=F===`filament`,q=K?oe:H,ce=[...q].sort((e,t)=>e-t).join(`,`),le=e=>{let t=t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n};K?se(t):U(t)},[J,ue]=(0,y.useState)(!1),Y=(0,y.useRef)(null),X=(0,y.useRef)(null),de=(0,y.useRef)(null),Z=(0,y.useRef)(null),fe=(0,y.useRef)(null),[pe,me]=(0,y.useState)(0),he=(0,y.useRef)(J),ge=(0,y.useRef)(z);he.current=J,ge.current=z;let _e=(0,y.useRef)(!1),Q=(0,y.useMemo)(()=>({x:t.x,y:t.y,z:t.z}),[`${t.x}x${t.y}x${t.z}`]);(0,y.useEffect)(()=>{let t=!1;C(!0),T(null),D(!1),k(null);let n={},i=r();return i&&(n.Authorization=`Bearer ${i}`),fetch(e,{headers:n}).then(async e=>{if(!e.ok){if(e.status===404){let t=await e.json().catch(()=>({}));if(typeof t.detail==`string`&&t.detail.includes(`sliced`))throw D(!0),Error(`not_sliced`)}throw Error(`Failed to load G-code`)}return e.text()}).then(e=>{if(t)return;_e.current=!1;let n=A(e);k(n),B([0,Math.max(0,n.layers.length-1)]),C(!1)}).catch(e=>{t||(e.message!==`not_sliced`&&T(e.message),C(!1))}),()=>{t=!0}},[e]),(0,y.useEffect)(()=>{let e=x.current;if(!e)return;let t=e.clientWidth||1,n=e.clientHeight||1,r=new c;r.background=new f(1710618),Y.current=r;let i=new _(45,t/n,.1,1e4);X.current=i;let a=new h({antialias:!0});a.setSize(t,n),a.setPixelRatio(Math.min(window.devicePixelRatio,2)),a.domElement.style.display=`block`,a.domElement.style.position=`absolute`,a.domElement.style.inset=`0`,e.appendChild(a.domElement);let o=new g(i,a.domElement);o.enableDamping=!0,o.dampingFactor=.05,de.current=o;let s=new m(Math.max(Q.x,Q.y),Math.ceil(Math.max(Q.x,Q.y)/16),4473924,3355443);s.position.set(Q.x/2,0,-Q.y/2),r.add(s);let l=0,u=()=>{l=requestAnimationFrame(u),o.update(),a.render(r,i)};u();let d=()=>{let t=e.clientWidth||1,n=e.clientHeight||1;i.aspect=t/n,i.updateProjectionMatrix(),a.setSize(t,n)},p=new ResizeObserver(d);return p.observe(e),window.addEventListener(`resize`,d),()=>{window.removeEventListener(`resize`,d),p.disconnect(),cancelAnimationFrame(l),o.dispose(),s.geometry.dispose(),s.material.dispose(),a.dispose(),e.removeChild(a.domElement),Y.current=null,X.current=null,de.current=null}},[Q]),(0,y.useEffect)(()=>{let e=Y.current,t=X.current,n=de.current;if(!e||!t||!n||!O||O.layers.length===0)return;let r=I(M(K?j(O.layers):O.layers,q),O.defaultWidth),i=W(d,r);fe.current=r,Z.current=i;let a=new p;if(a.rotation.x=-Math.PI/2,a.add(i.mesh),a.add(i.travLines),e.add(a),i.setTravelVisible(he.current),i.setLayerRange(ge.current[0],ge.current[1]),me(e=>e+1),!_e.current){_e.current=!0;let e=O.bounds,r=e?new u(new s(e.min[0],e.min[2],-e.max[1]),new s(e.max[0],e.max[2],-e.min[1])):new u(new s(0,0,0),new s(Q.x,1,-Q.y)),i=r.getCenter(new s),a=Math.max(r.getSize(new s).length()/2,.001),o=l.degToRad(t.fov),c=2*Math.atan(Math.tan(o/2)*t.aspect),d=1.15*Math.max(a/Math.sin(o/2),a/Math.sin(c/2));t.position.copy(i).addScaledVector(new s(.7,.5,.7).normalize(),d),t.near=Math.max(d/1e3,.01),t.far=d+a*4,t.updateProjectionMatrix(),n.target.copy(i),n.update()}return()=>{e.remove(a),i.dispose(),Z.current=null,fe.current=null}},[O,K,Q,ce]),(0,y.useEffect)(()=>{Z.current?.setLayerRange(z[0],z[1])},[z]),(0,y.useEffect)(()=>{Z.current?.setTravelVisible(J)},[J]);let $=(0,y.useMemo)(()=>{let e=fe.current;if(!e||!O)return null;if(K){let t=new Float32Array(e.nV*4);for(let r=0;r<e.nV;r+=1){let i=Math.max(0,e.meta.vType[r]-1),a=n?.[i]??n?.[0]??`#00ae42`;t[r*4]=ne(a)}return{color:t,min:0,max:0,unit:``,cont:!1}}return V(e,F,{})},[F,O,K,n,pe]);(0,y.useEffect)(()=>{$&&Z.current?.setColors($.color)},[$]);let ve=O?.layers.length??0;return E?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 text-bambu-gray ${a}`,children:[(0,G.jsx)(v,{className:`w-8 h-8`}),b(`gcodeViewer.notSliced`,`This file has not been sliced yet.`)]}):w?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-2 text-bambu-gray ${a}`,children:[(0,G.jsx)(v,{className:`w-8 h-8`}),b(`gcodeViewer.loadFailed`,`Could not load the G-code for this file.`)]}):(0,G.jsxs)(`div`,{className:`relative ${a}`,children:[(0,G.jsx)(`div`,{ref:x,className:`absolute inset-0`}),S&&(0,G.jsxs)(`div`,{className:`absolute inset-0 flex items-center justify-center gap-2 bg-bambu-dark/60 text-sm text-bambu-gray`,children:[(0,G.jsx)(o,{className:`w-4 h-4 animate-spin`}),b(`gcodeViewer.loading`,`Reading toolpath...`)]}),!S&&ve>0&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`absolute left-3 top-3 flex flex-col gap-2 rounded border border-bambu-dark-tertiary bg-bambu-dark/85 p-2`,children:[(0,G.jsx)(`div`,{className:`flex overflow-hidden rounded border border-bambu-dark-tertiary`,children:ee.filter(e=>e!==`filament`||N).map(e=>(0,G.jsx)(`button`,{type:`button`,onClick:()=>{R.current=!0,L(e)},className:`px-2 py-1 text-xs transition-colors ${F===e?`bg-bambu-green text-white`:`text-bambu-gray hover:text-white`}`,children:b(`gcodeViewer.view.${e}`,e)},e))}),(0,G.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-xs text-bambu-gray`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:J,onChange:e=>ue(e.target.checked),className:`cursor-pointer`}),b(`gcodeViewer.showTravel`,`Travel moves`)]}),K?(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:(n??[]).map((e,t)=>{let n=t+1,r=q.has(n);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,onClick:()=>le(n),"aria-pressed":!r,className:`flex w-full items-center gap-1.5 text-left text-[0.7rem] transition-opacity hover:text-white ${r?`text-bambu-gray/40`:`text-bambu-gray`}`,children:[(0,G.jsx)(`span`,{className:`inline-block h-2.5 w-2.5 shrink-0 rounded-sm border border-white/20 ${r?`opacity-25`:``}`,style:{backgroundColor:e},"aria-hidden":!0}),(0,G.jsx)(`span`,{className:r?`line-through`:``,children:b(`gcodeViewer.filamentSlot`,`Filament {{n}}`,{n:t+1})})]})},t)})}):F===`feature`?(0,G.jsx)(`ul`,{className:`flex flex-col gap-0.5`,children:te.map(e=>{let t=q.has(e.type);return(0,G.jsx)(`li`,{children:(0,G.jsxs)(`button`,{type:`button`,onClick:()=>le(e.type),"aria-pressed":!t,className:`flex w-full items-center gap-1.5 text-left text-[0.7rem] transition-opacity hover:text-white ${t?`text-bambu-gray/40`:`text-bambu-gray`}`,children:[(0,G.jsx)(`span`,{className:`inline-block h-2.5 w-2.5 shrink-0 rounded-sm ${t?`opacity-25`:``}`,style:{backgroundColor:re(P[e.type])},"aria-hidden":!0}),(0,G.jsx)(`span`,{className:t?`line-through`:``,children:b(e.key,e.fallback)})]})},e.type)})}):$&&(0,G.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,G.jsx)(`div`,{className:`h-2.5 w-full rounded-sm border border-white/10`,style:{background:`linear-gradient(to right, ${ie()})`},"aria-hidden":!0}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-[0.7rem] tabular-nums text-bambu-gray`,children:[(0,G.jsx)(`span`,{children:ae($.min)}),(0,G.jsx)(`span`,{className:`text-bambu-gray/70`,children:$.unit}),(0,G.jsx)(`span`,{children:ae($.max)})]})]})]}),(0,G.jsxs)(`div`,{className:`absolute right-3 top-3 flex flex-col items-center gap-1 rounded border border-bambu-dark-tertiary bg-bambu-dark/85 p-2`,children:[(0,G.jsx)(`span`,{className:`text-[0.65rem] tabular-nums text-bambu-gray`,children:z[1]+1}),(0,G.jsx)(`input`,{type:`range`,min:0,max:Math.max(0,ve-1),value:z[1],onChange:e=>{let t=Number(e.target.value);B(([e])=>[Math.min(e,t),t])},"aria-label":b(`gcodeViewer.topLayer`,`Top layer`),className:`h-40 w-4 cursor-pointer`,style:{writingMode:`vertical-lr`,direction:`rtl`}}),(0,G.jsx)(`input`,{type:`range`,min:0,max:Math.max(0,ve-1),value:z[0],onChange:e=>{let t=Number(e.target.value);B(([,e])=>[t,Math.max(t,e)])},"aria-label":b(`gcodeViewer.bottomLayer`,`Bottom layer`),className:`h-40 w-4 cursor-pointer`,style:{writingMode:`vertical-lr`,direction:`rtl`}}),(0,G.jsx)(`span`,{className:`text-[0.65rem] tabular-nums text-bambu-gray`,children:z[0]+1})]})]})]})}export{oe as t};