@zinejs/core 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ZineJS={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=Object.defineProperty,n=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},r=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r};function i(e,t={}){let{direction:n=`ltr`,cover:r=!1,singlePage:i=!1}=t;if(e<=0)return[];let a=t=>t>=0&&t<e?t:null,o=[];if(i)for(let t=0;t<e;t++)o.push({left:null,right:t});else if(r){o.push({left:null,right:0});for(let t=1;t<e;t+=2)o.push({left:a(t),right:a(t+1)})}else for(let t=0;t<e;t+=2)o.push({left:a(t),right:a(t+1)});return n===`rtl`?o.map(e=>({left:e.right,right:e.left})):o}function a(e,t){return e<t}function o(e,t,n){let r=[],i=Math.max(0,e-n),a=Math.min(t-1,e+n);for(let e=i;e<=a;e++)r.push(e);return r}var s=class{#e;#t=new Set;constructor(e=2){this.#e=e}get mounted(){return[...this.#t].sort((e,t)=>e-t)}update(e,t){let n=new Set(o(e,t,this.#e)),r=[...n].filter(e=>!this.#t.has(e)).sort((e,t)=>e-t),i=[...this.#t].filter(e=>!n.has(e)).sort((e,t)=>e-t);for(let e of i)this.#t.delete(e);for(let e of r)this.#t.add(e);return{toMount:r,toEvict:i}}},c=class{#e=new Map;on(e,t){let n=this.#e.get(e);return n||(n=new Set,this.#e.set(e,n)),n.add(t),()=>this.off(e,t)}off(e,t){this.#e.get(e)?.delete(t)}emit(e,...t){let n=t[0],r=this.#e.get(e);if(r)for(let e of[...r])e(n)}clear(){this.#e.clear()}},l={idle:{grab:`dragging`,panStart:`zoomed-panning`,flip:`animating`},dragging:{release:`animating`},animating:{settle:`idle`},"zoomed-panning":{panEnd:`idle`}};function u(e,t){return l[e][t]??null}var d=class{#e;constructor(e=`idle`){this.#e=e}get state(){return this.#e}send(e){let t=u(this.#e,e);return t!==null&&(this.#e=t),t}},ee=.3,f=class{#e;#t=null;#n=null;#r=null;#i=null;constructor(e={}){this.#e=e}get active(){return this.#t!==null}down(e,t,n,r){if(this.#t!==null)return;this.#t=e;let i={x:t,y:n,t:r};this.#n=i,this.#r=i,this.#i=i,this.#e.onStart?.({x:t,y:n,t:r})}move(e,t,n,r){e!==this.#t||this.#n===null||(this.#r=this.#i,this.#i={x:t,y:n,t:r},this.#e.onMove?.({x:t,y:n,dx:t-this.#n.x,dy:n-this.#n.y}))}up(e,t,n,r){this.#a(e,t,n,r,!1)}cancel(e,t,n,r){this.#a(e,t,n,r,!0)}#a(e,t,n,r,i){if(e!==this.#t||this.#n===null)return;let a=this.#n,o=this.#i??a,s=this.#r??a,c=o.t-s.t,l=c>0?(o.x-s.x)/c:0,u=c>0?(o.y-s.y)/c:0,d=Math.hypot(l,u);this.#o(),this.#e.onEnd?.({x:t,y:n,dx:t-a.x,dy:n-a.y,dt:r-a.t,vx:l,vy:u,swipe:!i&&d>ee,canceled:i})}#o(){this.#t=null,this.#n=null,this.#r=null,this.#i=null}};function p(e,t){let{pointer:n,pinch:r}=t,i=e=>{let t=e;n?.down(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.down(t.pointerId,t.clientX,t.clientY)},a=e=>{let t=e;n?.move(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.move(t.pointerId,t.clientX,t.clientY)},o=e=>{let t=e;n?.up(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.up(t.pointerId)},s=e=>{let t=e;n?.cancel(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.cancel(t.pointerId)};return e.addEventListener(`pointerdown`,i),e.addEventListener(`pointermove`,a),e.addEventListener(`pointerup`,o),e.addEventListener(`pointercancel`,s),()=>{e.removeEventListener(`pointerdown`,i),e.removeEventListener(`pointermove`,a),e.removeEventListener(`pointerup`,o),e.removeEventListener(`pointercancel`,s)}}function m(e,t){return Math.hypot(e.x-t.x,e.y-t.y)}var h=class{#e;#t=new Map;#n=0;#r=!1;constructor(e={}){this.#e=e}get pinching(){return this.#r}down(e,t,n){if(!(this.#t.has(e)||this.#t.size>=2)&&(this.#t.set(e,{x:t,y:n}),this.#t.size===2)){let{a:e,b:t}=this.#a();this.#n=m(e,t),this.#r=!0,this.#e.onPinchStart?.({centerX:(e.x+t.x)/2,centerY:(e.y+t.y)/2,distance:this.#n})}}move(e,t,n){let r=this.#t.get(e);if(!r||(r.x=t,r.y=n,!this.#r))return;let{a:i,b:a}=this.#a();this.#e.onPinchMove?.({centerX:(i.x+a.x)/2,centerY:(i.y+a.y)/2,scale:this.#n>0?m(i,a)/this.#n:1})}up(e){this.#i(e)}cancel(e){this.#i(e)}#i(e){this.#t.delete(e)&&this.#r&&this.#t.size<2&&(this.#r=!1,this.#n=0,this.#e.onPinchEnd?.())}#a(){let e=[...this.#t.values()],t=e[0],n=e[1];if(!t||!n)throw Error(`pinch requires two active pointers`);return{a:t,b:n}}};function g(e,t,n){let{width:r,height:i}=t;if(e.x<0||e.x>r||e.y<0||e.y>i)return`outside`;let a=e.x<=n||e.x>=r-n,o=e.y<=n||e.y>=i-n;return a&&o?`corner`:`page`}function _(e){let t=e<0?0:e>1?1:e,n=Math.sin(t*Math.PI);return{angle:t*Math.PI,curl:n,shadowAlpha:n}}var v=n((()=>{})),y=r({CssRenderer:()=>S});function b(e){let t=e===`forward`?`to right`:`to left`;return[`linear-gradient(${t}, rgba(0,0,0,0.6), rgba(0,0,0,0.15) 40%, rgba(0,0,0,0) 60%)`,`linear-gradient(${t}, transparent 40%, rgba(255,255,255,0.32) 66%, transparent 90%)`,`linear-gradient(${t}, transparent 66%, rgba(0,0,0,0.35))`].join(`,`)}var x,S,C=n((()=>{v(),x=180/Math.PI,S=class{#e=null;#t;#n;#r;#i;#a;#o;#s;#c;#l;mount(e){let t=e.ownerDocument;return this.#e=e,this.#t=t.createElement(`div`),this.#t.className=`zine-clip`,this.#t.style.cssText=`position:relative;width:100%;height:100%;overflow:hidden;`,this.#n=t.createElement(`div`),this.#n.className=`zine-viewport`,this.#n.style.cssText=`position:absolute;inset:0;transform-origin:0 0;`,this.#r=t.createElement(`div`),this.#r.className=`zine-book`,this.#r.style.cssText=`position:absolute;inset:0;perspective:2000px;transform-style:preserve-3d;`,this.#i=this.#u(t,`zine-page-left`,`left:0;`),this.#a=this.#u(t,`zine-page-right`,`right:0;`),this.#o=t.createElement(`div`),this.#o.className=`zine-leaf`,this.#o.style.cssText=`position:absolute;top:0;width:50%;height:100%;transform-style:preserve-3d;display:none;`,this.#s=t.createElement(`canvas`),this.#s.className=`zine-leaf-front`,this.#s.style.cssText=`position:absolute;inset:0;width:100%;height:100%;backface-visibility:hidden;`,this.#c=t.createElement(`canvas`),this.#c.className=`zine-leaf-back`,this.#c.style.cssText=`position:absolute;inset:0;width:100%;height:100%;backface-visibility:hidden;transform:rotateY(180deg);`,this.#l=t.createElement(`div`),this.#l.className=`zine-leaf-shadow`,this.#l.style.cssText=`position:absolute;inset:0;opacity:0;pointer-events:none;`,this.#l.style.background=b(`forward`),this.#o.append(this.#s,this.#c,this.#l),this.#r.append(this.#i,this.#a,this.#o),this.#n.append(this.#r),this.#t.append(this.#n),e.append(this.#t),Promise.resolve()}destroy(){this.#t?.remove(),this.#e=null}renderSpread(e,t,n){n?.fill?(this.#i.style.width=`100%`,this.#a.style.display=`none`,this.#d(this.#i,t.right??t.left)):(this.#i.style.width=`50%`,this.#a.style.display=``,this.#d(this.#i,t.left),this.#d(this.#a,t.right)),this.#o.style.display=`none`,this.#o.style.transform=``,this.#l.style.opacity=`0`}beginFlip(e,t,n,r){r?.fill?(this.#i.style.width=`100%`,this.#a.style.display=`none`,this.#o.style.width=`100%`,this.#o.style.left=`0`,this.#o.style.transformOrigin=n===`forward`?`left center`:`right center`,this.#d(this.#i,t.right??t.left),this.#d(this.#s,e.right??e.left),this.#d(this.#c,t.right??t.left)):(this.#i.style.width=`50%`,this.#a.style.display=``,this.#o.style.width=`50%`,n===`forward`?(this.#d(this.#i,e.left),this.#d(this.#a,t.right),this.#d(this.#s,e.right),this.#d(this.#c,t.left),this.#o.style.left=`50%`,this.#o.style.transformOrigin=`left center`):(this.#d(this.#a,e.right),this.#d(this.#i,t.left),this.#d(this.#s,e.left),this.#d(this.#c,t.right),this.#o.style.left=`0`,this.#o.style.transformOrigin=`right center`)),this.#o.style.display=`block`,this.#o.style.transform=`rotateY(0deg)`,this.#l.style.background=b(n),this.#l.style.opacity=`0`}setFlipProgress(e,t){let n=_(e),r=n.angle*x;this.#o.style.display=`block`,this.#o.style.transform=`rotateY(${t===`forward`?-r:r}deg)`,this.#l.style.opacity=String(n.shadowAlpha)}setViewTransform(e,t,n){this.#n.style.transform=`translate(${t}px, ${n}px) scale(${e})`}measure(){let e=this.#e,t=e?.clientWidth??0,n=e?.clientHeight??0;return{containerWidth:t,containerHeight:n,pageWidth:t/2,pageHeight:n}}#u(e,t,n){let r=e.createElement(`canvas`);return r.className=t,r.style.cssText=`position:absolute;top:0;width:50%;height:100%;${n}`,r}#d(e,t){let n=e.getContext(`2d`);if(t===null){n?.clearRect(0,0,e.width,e.height);return}e.width=t.width,e.height=t.height,n?.drawImage(t,0,0)}}}));function w(e){let t=e.getContext(`webgl2`,{alpha:!0,premultipliedAlpha:!0,antialias:!0,depth:!1,stencil:!1,preserveDrawingBuffer:!0});if(t===null)throw Error(`WebglRenderer: could not create a WebGL2 context.`);return t}var T=n((()=>{}));function E(e,t,n){let r=e.createProgram();if(r===null)throw Error(`WebglRenderer: could not create a program.`);let i=D(e,e.VERTEX_SHADER,t),a=D(e,e.FRAGMENT_SHADER,n);if(e.attachShader(r,i),e.attachShader(r,a),e.linkProgram(r),e.deleteShader(i),e.deleteShader(a),!e.getProgramParameter(r,e.LINK_STATUS)){let t=e.getProgramInfoLog(r);throw e.deleteProgram(r),Error(`WebglRenderer: program link failed: ${t??`unknown error`}`)}return r}function D(e,t,n){let r=e.createShader(t);if(r===null)throw Error(`WebglRenderer: could not create a shader.`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r);throw e.deleteShader(r),Error(`WebglRenderer: shader compile failed: ${t??`unknown error`}`)}return r}var O=n((()=>{}));function k(e){let t=e.createTexture();if(t===null)throw Error(`WebglRenderer: could not create a texture.`);return e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),t}function A(e,t,n){e.bindTexture(e.TEXTURE_2D,t),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!1),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n)}var j=n((()=>{})),te=r({WebglRenderer:()=>z}),M,N,P,F,I,L,R,z,B=n((()=>{v(),T(),O(),j(),M=`#version 300 es
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ZineJS={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=Object.defineProperty,n=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},r=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r};function i(e,t={}){let{direction:n=`ltr`,mode:r=`cover`}=t;if(e<=0)return[];let i=t=>t>=0&&t<e?t:null,a=[];if(r===`single`)for(let t=0;t<e;t++)a.push({left:null,right:t});else if(r===`double`)for(let t=0;t<e;t+=2)a.push({left:i(t),right:i(t+1)});else if(r===`cover`){a.push({left:null,right:0});for(let t=1;t<e;t+=2)a.push({left:i(t),right:i(t+1)})}else if(a.push({left:null,right:0}),e>1){for(let t=1;t<=e-2;t+=2)a.push({left:i(t),right:t+1<=e-2?i(t+1):null});a.push({left:e-1,right:null})}return n===`rtl`?a.map(e=>({left:e.right,right:e.left})):a}function a(e,t){return e<t}function o(e,t,n){let r=[],i=Math.max(0,e-n),a=Math.min(t-1,e+n);for(let e=i;e<=a;e++)r.push(e);return r}var s=class{#e;#t=new Set;constructor(e=2){this.#e=e}get mounted(){return[...this.#t].sort((e,t)=>e-t)}update(e,t){let n=new Set(o(e,t,this.#e)),r=[...n].filter(e=>!this.#t.has(e)).sort((e,t)=>e-t),i=[...this.#t].filter(e=>!n.has(e)).sort((e,t)=>e-t);for(let e of i)this.#t.delete(e);for(let e of r)this.#t.add(e);return{toMount:r,toEvict:i}}},c=class{#e=new Map;on(e,t){let n=this.#e.get(e);return n||(n=new Set,this.#e.set(e,n)),n.add(t),()=>this.off(e,t)}off(e,t){this.#e.get(e)?.delete(t)}emit(e,...t){let n=t[0],r=this.#e.get(e);if(r)for(let e of[...r])e(n)}clear(){this.#e.clear()}},l={idle:{grab:`dragging`,panStart:`zoomed-panning`,flip:`animating`},dragging:{release:`animating`},animating:{settle:`idle`},"zoomed-panning":{panEnd:`idle`}};function u(e,t){return l[e][t]??null}var d=class{#e;constructor(e=`idle`){this.#e=e}get state(){return this.#e}send(e){let t=u(this.#e,e);return t!==null&&(this.#e=t),t}},f=.3,p=class{#e;#t=null;#n=null;#r=null;#i=null;constructor(e={}){this.#e=e}get active(){return this.#t!==null}down(e,t,n,r){if(this.#t!==null)return;this.#t=e;let i={x:t,y:n,t:r};this.#n=i,this.#r=i,this.#i=i,this.#e.onStart?.({x:t,y:n,t:r})}move(e,t,n,r){e!==this.#t||this.#n===null||(this.#r=this.#i,this.#i={x:t,y:n,t:r},this.#e.onMove?.({x:t,y:n,dx:t-this.#n.x,dy:n-this.#n.y}))}up(e,t,n,r){this.#a(e,t,n,r,!1)}cancel(e,t,n,r){this.#a(e,t,n,r,!0)}#a(e,t,n,r,i){if(e!==this.#t||this.#n===null)return;let a=this.#n,o=this.#i??a,s=this.#r??a,c=o.t-s.t,l=c>0?(o.x-s.x)/c:0,u=c>0?(o.y-s.y)/c:0,d=Math.hypot(l,u);this.#o(),this.#e.onEnd?.({x:t,y:n,dx:t-a.x,dy:n-a.y,dt:r-a.t,vx:l,vy:u,swipe:!i&&d>f,canceled:i})}#o(){this.#t=null,this.#n=null,this.#r=null,this.#i=null}};function m(e,t){let{pointer:n,pinch:r}=t,i=e=>{let t=e;n?.down(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.down(t.pointerId,t.clientX,t.clientY)},a=e=>{let t=e;n?.move(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.move(t.pointerId,t.clientX,t.clientY)},o=e=>{let t=e;n?.up(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.up(t.pointerId)},s=e=>{let t=e;n?.cancel(t.pointerId,t.clientX,t.clientY,t.timeStamp),r?.cancel(t.pointerId)};return e.addEventListener(`pointerdown`,i),e.addEventListener(`pointermove`,a),e.addEventListener(`pointerup`,o),e.addEventListener(`pointercancel`,s),()=>{e.removeEventListener(`pointerdown`,i),e.removeEventListener(`pointermove`,a),e.removeEventListener(`pointerup`,o),e.removeEventListener(`pointercancel`,s)}}function h(e,t){return Math.hypot(e.x-t.x,e.y-t.y)}var g=class{#e;#t=new Map;#n=0;#r=!1;constructor(e={}){this.#e=e}get pinching(){return this.#r}down(e,t,n){if(!(this.#t.has(e)||this.#t.size>=2)&&(this.#t.set(e,{x:t,y:n}),this.#t.size===2)){let{a:e,b:t}=this.#a();this.#n=h(e,t),this.#r=!0,this.#e.onPinchStart?.({centerX:(e.x+t.x)/2,centerY:(e.y+t.y)/2,distance:this.#n})}}move(e,t,n){let r=this.#t.get(e);if(!r||(r.x=t,r.y=n,!this.#r))return;let{a:i,b:a}=this.#a();this.#e.onPinchMove?.({centerX:(i.x+a.x)/2,centerY:(i.y+a.y)/2,scale:this.#n>0?h(i,a)/this.#n:1})}up(e){this.#i(e)}cancel(e){this.#i(e)}#i(e){this.#t.delete(e)&&this.#r&&this.#t.size<2&&(this.#r=!1,this.#n=0,this.#e.onPinchEnd?.())}#a(){let e=[...this.#t.values()],t=e[0],n=e[1];if(!t||!n)throw Error(`pinch requires two active pointers`);return{a:t,b:n}}};function _(e,t,n){let{width:r,height:i}=t;if(e.x<0||e.x>r||e.y<0||e.y>i)return`outside`;let a=e.x<=n||e.x>=r-n,o=e.y<=n||e.y>=i-n;return a&&o?`corner`:`page`}var v,y,b=n((()=>{v=[`roll`,`cone`,`leaf`,`flick`,`simple`],y=`cone`}));function x(e){let t=e<0?0:e>1?1:e,n=Math.sin(t*Math.PI);return{angle:t*Math.PI,curl:n,shadowAlpha:n}}var S=n((()=>{})),C=r({CssRenderer:()=>D});function w(e){return e.left===null==(e.right===null)?0:e.right===null?1:-1}function T(e){let t=e===`forward`?`to right`:`to left`;return[`linear-gradient(${t}, rgba(0,0,0,0.6), rgba(0,0,0,0.15) 40%, rgba(0,0,0,0) 60%)`,`linear-gradient(${t}, transparent 40%, rgba(255,255,255,0.32) 66%, transparent 90%)`,`linear-gradient(${t}, transparent 66%, rgba(0,0,0,0.35))`].join(`,`)}var E,D,ee=n((()=>{S(),E=180/Math.PI,D=class{#e=null;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=0;#d=0;#f=0;#p=0;#m=!1;#h=0;mount(e){let t=e.ownerDocument;return this.#e=e,this.#t=t.createElement(`div`),this.#t.className=`zine-clip`,this.#t.style.cssText=`position:relative;width:100%;height:100%;overflow:hidden;`,this.#n=t.createElement(`div`),this.#n.className=`zine-viewport`,this.#n.style.cssText=`position:absolute;inset:0;transform-origin:0 0;`,this.#r=t.createElement(`div`),this.#r.className=`zine-book`,this.#r.style.cssText=`position:absolute;inset:0;perspective:2000px;transform-style:preserve-3d;`,this.#i=this.#x(t,`zine-page-left`,`left:0;`),this.#a=this.#x(t,`zine-page-right`,`right:0;`),this.#o=t.createElement(`div`),this.#o.className=`zine-leaf`,this.#o.style.cssText=`position:absolute;top:0;width:50%;height:100%;transform-style:preserve-3d;display:none;`,this.#s=t.createElement(`canvas`),this.#s.className=`zine-leaf-front`,this.#s.style.cssText=`position:absolute;inset:0;width:100%;height:100%;backface-visibility:hidden;`,this.#c=t.createElement(`canvas`),this.#c.className=`zine-leaf-back`,this.#c.style.cssText=`position:absolute;inset:0;width:100%;height:100%;backface-visibility:hidden;transform:rotateY(180deg);`,this.#l=t.createElement(`div`),this.#l.className=`zine-leaf-shadow`,this.#l.style.cssText=`position:absolute;inset:0;opacity:0;pointer-events:none;`,this.#l.style.background=T(`forward`),this.#o.append(this.#s,this.#c,this.#l),this.#r.append(this.#i,this.#a,this.#o),this.#n.append(this.#r),this.#t.append(this.#n),e.append(this.#t),Promise.resolve()}destroy(){this.#t?.remove(),this.#e=null}renderSpread(e,t,n){n?.fill?(this.#i.style.width=`100%`,this.#a.style.display=`none`,this.#S(this.#i,t.right??t.left)):(this.#i.style.width=`50%`,this.#a.style.display=``,this.#S(this.#i,t.left),this.#S(this.#a,t.right)),this.#m=n?.fill??!1,this.#h=this.#m?0:w(t),this.#_(t),this.#v(),this.#g(this.#h),this.#o.style.display=`none`,this.#o.style.transform=``,this.#l.style.opacity=`0`}beginFlip(e,t,n,r){r?.fill?(this.#i.style.width=`100%`,this.#a.style.display=`none`,this.#o.style.width=`100%`,this.#o.style.left=`0`,this.#o.style.transformOrigin=n===`forward`?`left center`:`right center`,this.#S(this.#i,t.right??t.left),this.#S(this.#s,e.right??e.left),this.#S(this.#c,t.right??t.left)):(this.#i.style.width=`50%`,this.#a.style.display=``,this.#o.style.width=`50%`,n===`forward`?(this.#S(this.#i,e.left),this.#S(this.#a,t.right),this.#S(this.#s,e.right),this.#S(this.#c,t.left),this.#o.style.left=`50%`,this.#o.style.transformOrigin=`left center`):(this.#S(this.#a,e.right),this.#S(this.#i,t.left),this.#S(this.#s,e.left),this.#S(this.#c,t.right),this.#o.style.left=`0`,this.#o.style.transformOrigin=`right center`)),this.#u=r?.fill?0:w(e),this.#d=r?.fill?0:w(t),this.#m=r?.fill??!1,this.#_(t),this.#v(),this.#g(this.#u),this.#o.style.display=`block`,this.#o.style.transform=`rotateY(0deg)`,this.#l.style.background=T(n),this.#l.style.opacity=`0`}setFlipProgress(e,t){let n=x(e),r=n.angle*E;this.#g(this.#u+(this.#d-this.#u)*e),this.#o.style.display=`block`,this.#o.style.transform=`rotateY(${t===`forward`?-r:r}deg)`,this.#l.style.opacity=String(n.shadowAlpha)}#g(e){let t=e*(this.#p/4);this.#r.style.transform=t?`translateX(${t}px)`:``}#_(e){let t=e.left??e.right;t&&t.height&&(this.#f=t.width/t.height)}#v(){let e=this.#y();this.#p=e.width;let t=this.#r.style;t.inset=`auto`,t.left=`${e.x}px`,t.top=`${e.y}px`,t.width=`${e.width}px`,t.height=`${e.height}px`}#y(){let e=this.#e?.clientWidth??0,t=this.#e?.clientHeight??0;if(this.#f<=0||e<=0||t<=0)return{x:0,y:0,width:e,height:t};let n=(this.#m?1:2)*this.#f,r=e,i=t;return n>e/t?i=e/n:r=t*n,{x:(e-r)/2,y:(t-i)/2,width:r,height:i}}#b(){let e=this.#y();return this.#h===0?e:{x:e.x+e.width/4,y:e.y,width:e.width/2,height:e.height}}setViewTransform(e,t,n){this.#n.style.transform=`translate(${t}px, ${n}px) scale(${e})`}measure(){let e=this.#e,t=e?.clientWidth??0,n=e?.clientHeight??0,r=this.#f>0,i=r?this.#y():void 0,a=r?this.#b():void 0;return{containerWidth:t,containerHeight:n,pageWidth:t/2,pageHeight:n,book:i,content:a}}#x(e,t,n){let r=e.createElement(`canvas`);return r.className=t,r.style.cssText=`position:absolute;top:0;width:50%;height:100%;${n}`,r}#S(e,t){let n=e.getContext(`2d`);if(t===null){n?.clearRect(0,0,e.width,e.height);return}e.width=t.width,e.height=t.height,n?.drawImage(t,0,0)}}}));function te(e,t){let n=e+1,r=t+1,i=n*r,a=new Float32Array(i*2);for(let i=0;i<r;i++)for(let r=0;r<n;r++){let o=i*n+r;a[o*2]=r/e,a[o*2+1]=i/t}return{cols:e,rows:t,uvs:a,positions:new Float32Array(i*3),normals:new Float32Array(i*3)}}function O(e){let t=e.cols+1,n=e.rows+1,r=e.positions,i=e.normals;for(let e=0;e<n;e++)for(let a=0;a<t;a++){let o=a>0?a-1:a,s=a<t-1?a+1:a,c=e>0?e-1:e,l=e<n-1?e+1:e,u=(e*t+s)*3,d=(e*t+o)*3,f=(l*t+a)*3,p=(c*t+a)*3,m=r[u]-r[d],h=r[u+1]-r[d+1],g=r[u+2]-r[d+2],_=r[f]-r[p],v=r[f+1]-r[p+1],y=r[f+2]-r[p+2],b=h*y-g*v,x=g*_-m*y,S=m*v-h*_,C=Math.hypot(b,x,S)||1;b/=C,x/=C,S/=C;let w=(e*t+a)*3;i[w]=b,i[w+1]=x,i[w+2]=S}}var k=n((()=>{}));function ne(e,t,n,r){let i=e.cols+1,a=e.rows+1,o=e.positions,s=Math.max(1e-6,r<.5?r*2*Math.PI:(1-(r-.5)*2)*Math.PI),c=t/s,l=r<.5?0:-(r-.5)*2*Math.PI,u=Math.cos(l),d=Math.sin(l);for(let t=0;t<i;t++){let r=t/e.cols*s,l=Math.sin(r)*c,f=(1-Math.cos(r))*c,p=l*u+f*d,m=-l*d+f*u;for(let r=0;r<a;r++){let a=(r*i+t)*3;o[a]=p,o[a+1]=r/e.rows*n,o[a+2]=m}}O(e)}var re=n((()=>{k()}));function ie(e,t,n,r,i){let a=e.cols+1,o=e.rows+1,s=e.positions,c=!!i.fill,l=Math.sin(Math.PI*r)**.85,u=c?A:ae,d=Math.PI/2-l*(Math.PI/2-u),f=Math.sin(d),p=Math.cos(d),m=1/Math.max(f,1e-6),h=c?N:j,g=n*(h+((c?oe:M)-h)*l),_=(i.y-.5)*2,v=_>=0,y=Math.min(1,Math.abs(_)/se),b=1-y,x=v?n+g:-g,S=Math.hypot(t,.5*n-x),C=Math.max(S*f,t/Math.PI),w=c?r**+ce:r,T=-Math.PI*w,E=Math.cos(T),D=Math.sin(T);if(l<1e-4){for(let r=0;r<o;r++){let i=r/e.rows*n;for(let n=0;n<a;n++){let o=n/e.cols*t,c=(r*a+n)*3;s[c]=o*E,s[c+1]=i,s[c+2]=-o*D}}O(e);return}for(let r=0;r<o;r++){let i=r/e.rows*n;for(let o=0;o<a;o++){let c=o/e.cols*t,l=c,u=i,d=0;if(y>1e-5){let e=v?n-i:i,t=-g,r=Math.hypot(c,e-t);if(r>1e-8){let e=r*f,i=Math.asin(Math.min(1,Math.max(0,c/r)))*m,a=1-Math.cos(i),o=r+t-e*a*f;l=e*Math.sin(i),u=v?n-o:o,d=e*a*p}}let h=l,_=u,x=d;if(b>1e-5){let e=c/C,t=C*Math.sin(e),n=C*(1-Math.cos(e));h=y*l+b*t,_=y*u+b*i,x=y*d+b*n}let S=(r*a+o)*3;s[S]=h*E+x*D,s[S+1]=_,s[S+2]=-h*D+x*E}}O(e)}var ae,A,j,M,N,oe,se,ce,le=n((()=>{k(),ae=30*Math.PI/180,A=44*Math.PI/180,j=1.35,M=.7,N=1.85,oe=1.15,se=.42,ce=1.08}));function ue(){let e=new Float64Array(129),t=new Float64Array(129),n=1/P,r=e=>Math.PI*e-.5*Math.sin(2*Math.PI*e);for(let i=1;i<=P;i++){let a=r((i-1)*n),o=r(i*n);e[i]=e[i-1]+.5*(Math.cos(a)+Math.cos(o))*n,t[i]=t[i-1]+.5*(Math.sin(a)+Math.sin(o))*n}return e[P]=0,{x:e,z:t}}function de(e){let t=Math.max(0,Math.min(1,e))*P,n=Math.min(P-1,Math.floor(t)),r=t-n;return[F.x[n]+(F.x[n+1]-F.x[n])*r,F.z[n]+(F.z[n+1]-F.z[n])*r]}function fe(e,t,n,r,i){let a=e.cols+1,o=e.rows+1,s=e.positions;if(r<=1e-7||r>=.9999999){let i=r<.5?1:-1;for(let r=0;r<o;r++){let o=r/e.rows*n;for(let n=0;n<a;n++){let c=(r*a+n)*3;s[c]=i*(n/e.cols)*t,s[c+1]=o,s[c+2]=0}}O(e);return}let c=Math.sin(Math.PI*r)**.72,l=Math.max(1e-6,t*pe*c),u=Math.max(-1,Math.min(1,(i.y-.5)*2))*me*Math.sin(Math.PI*r)**1.15,d=Math.cos(u),f=Math.sin(u),p=-f,m=d,h=Math.abs(f)*n*.5,g=t+h/d,_=g+(-(l+h)/d-g)*r,v=n*.5;for(let r=0;r<o;r++){let i=r/e.rows*n;for(let n=0;n<a;n++){let o=n/e.cols*t,c=o-_,u=i-v,h=c*d+u*f,g=c*p+u*m,y=(r*a+n)*3;if(h<=0){s[y]=o,s[y+1]=i,s[y+2]=0;continue}let b,x;if(h<l){let[e,t]=de(h/l);b=l*e,x=l*t}else b=-(h-l),x=l*I;s[y]=_+p*g+d*b,s[y+1]=v+m*g+f*b,s[y+2]=x}}O(e)}var pe,me,P,F,I,he=n((()=>{k(),pe=.34,me=11*Math.PI/180,P=128,F=ue(),I=F.z[P]}));function ge(e,t,n,r,i){let a=e.cols+1,o=e.rows+1,s=e.cols,c=e.positions,l=t/s,u=Math.PI*r,d=-.52*Math.sin(2*Math.PI*r);for(let t=0;t<o;t++){let r=t/e.rows,o=d*(1+L*Math.abs(r-i.y)),f=r*n,p=0,m=0,h=Math.cos(u),g=Math.sin(u);c[t*a*3]=0,c[t*a*3+1]=f,c[t*a*3+2]=0;for(let e=1;e<a;e++){let n=e/s,r=u+o*n*n,i=Math.cos(r),d=Math.sin(r);p+=.5*(h+i)*l,m+=.5*(g+d)*l,h=i,g=d;let _=(t*a+e)*3;c[_]=p,c[_+1]=f,c[_+2]=m}}O(e)}var L,_e=n((()=>{k(),L=.45}));function ve(e,t,n,r){let i=e.cols+1,a=e.rows+1,o=e.positions,s=r*Math.PI,c=Math.cos(s),l=Math.sin(s);for(let r=0;r<i;r++){let s=r/e.cols*t,u=s*c,d=s*l;for(let t=0;t<a;t++){let a=(t*i+r)*3;o[a]=u,o[a+1]=t/e.rows*n,o[a+2]=d}}O(e)}var ye=n((()=>{k()})),R,be=n((()=>{re(),le(),he(),_e(),ye(),k(),b(),R={roll:{deform:ne,anchored:!1},cone:{deform:ie,anchored:!0},leaf:{deform:fe,anchored:!0},flick:{deform:ge,anchored:!0},simple:{deform:ve,anchored:!1}}}));function xe(e){let t=e.getContext(`webgl2`,{alpha:!0,premultipliedAlpha:!0,antialias:!0,depth:!1,stencil:!1,preserveDrawingBuffer:!0});if(t===null)throw Error(`WebglRenderer: could not create a WebGL2 context.`);return t}var Se=n((()=>{}));function z(e,t,n){let r=e.createProgram();if(r===null)throw Error(`WebglRenderer: could not create a program.`);let i=B(e,e.VERTEX_SHADER,t),a=B(e,e.FRAGMENT_SHADER,n);if(e.attachShader(r,i),e.attachShader(r,a),e.linkProgram(r),e.deleteShader(i),e.deleteShader(a),!e.getProgramParameter(r,e.LINK_STATUS)){let t=e.getProgramInfoLog(r);throw e.deleteProgram(r),Error(`WebglRenderer: program link failed: ${t??`unknown error`}`)}return r}function B(e,t,n){let r=e.createShader(t);if(r===null)throw Error(`WebglRenderer: could not create a shader.`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r);throw e.deleteShader(r),Error(`WebglRenderer: shader compile failed: ${t??`unknown error`}`)}return r}var Ce=n((()=>{}));function V(e){let t=e.createTexture();if(t===null)throw Error(`WebglRenderer: could not create a texture.`);return e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),t}function we(e,t,n){e.bindTexture(e.TEXTURE_2D,t),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!1),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n)}var Te=n((()=>{})),Ee=r({WebglRenderer:()=>je});function H(e){return e.left===null==(e.right===null)?0:e.right===null?1:-1}var U,W,G,K,q,J,De,Oe,ke,Ae,je,Me=n((()=>{be(),Se(),Ce(),Te(),U=`#version 300 es
2
2
  in vec2 aUnit;
3
3
  uniform vec2 uViewport;
4
4
  uniform vec4 uRect;
@@ -10,95 +10,82 @@ void main() {
10
10
  vec2 clip = px / uViewport * 2.0 - 1.0;
11
11
  gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);
12
12
  vUv = aUnit;
13
- }`,N=`#version 300 es
13
+ }`,W=`#version 300 es
14
14
  precision mediump float;
15
15
  in vec2 vUv;
16
16
  uniform sampler2D uTex;
17
- uniform float uGutterSide; // +1 = spine at the right edge, -1 = at the left edge, 0 = none
17
+ uniform float uGutterSide; // +1 = spine at right edge, -1 = at left edge, 0 = none
18
18
  out vec4 outColor;
19
19
  void main() {
20
20
  vec4 c = texture(uTex, vUv);
21
21
  if (uGutterSide != 0.0) {
22
- // Soft, permanent gutter shadow: darken toward the spine edge where the pages
23
- // meet, so the turning leaf's spine shadow lands into it instead of vanishing.
24
22
  float d = uGutterSide > 0.0 ? (1.0 - vUv.x) : vUv.x;
25
23
  c.rgb *= mix(0.72, 1.0, smoothstep(0.0, 0.10, d));
26
24
  }
27
25
  outColor = c;
28
- }`,P=`#version 300 es
29
- in vec2 aUnit;
26
+ }`,G=`#version 300 es
27
+ in vec3 aPos; // leaf-local device px: x = bent offset from spine, y 0..H, z depth
28
+ in vec3 aNormal;
29
+ in vec2 aUv;
30
30
  uniform vec2 uViewport;
31
- uniform vec4 uLeaf; // spineX, y, width, height (device px)
32
31
  uniform vec3 uView; // scale, tx, ty
33
- uniform float uAngle; // spine rotation 0..PI
34
- uniform float uCurl; // 0..1 bend amount
35
- uniform float uDir; // +1 leaf sweeps from +x side, -1 from -x side
32
+ uniform float uOriginX; // spine x in device px
33
+ uniform float uDir; // +1 leaf to the right of spine, -1 to the left
34
+ uniform float uLeafW; // leaf width in device px (perspective scale)
36
35
  out vec2 vUv;
36
+ out float vFacing;
37
37
  out float vU;
38
- out float vLight; // surface facing: +1 toward viewer, 0 edge-on, -1 away
39
- const float CAM = 3.0; // perspective camera distance, in page widths (bigger = subtler)
40
38
  void main() {
41
- float u = aUnit.x;
42
- float W = uLeaf.z;
43
- // Cylinder wrap of the turning sheet, rotated about the spine (vertical y axis).
44
- float bend = uCurl * 1.5;
45
- float phi, xw, zw;
46
- if (bend > 0.001) {
47
- float R = W / bend;
48
- phi = u * bend;
49
- xw = R * sin(phi);
50
- zw = R * (1.0 - cos(phi));
51
- } else {
52
- phi = 0.0;
53
- xw = u * W;
54
- zw = 0.0;
55
- }
56
- float X = xw * cos(uAngle) - zw * sin(uAngle); // in-plane
57
- float Z = xw * sin(uAngle) + zw * cos(uAngle); // depth (+ toward viewer)
58
- float px = uLeaf.x + uDir * X;
59
- float py = uLeaf.y + aUnit.y * uLeaf.w;
60
- // Perspective by depth. X may bulge toward the viewer for 3D pop; Y only ever
61
- // SHRINKS (persp clamped <= 1) about the page's own vertical center, so the top
62
- // is never pushed past the frame (that was the hidden-top bug).
63
- float D = W * CAM;
39
+ float bookX = uOriginX + uDir * aPos.x;
40
+ float bookY = aPos.y;
41
+ float Z = aPos.z;
42
+ // Eye distance, in leaf widths. Keeps the perspective resolution-independent. 5.3 puts the
43
+ // roll's deepest point ~14% larger than flat; stronger than that (a nearer eye) balloons the
44
+ // turning sheet and reads more like a fisheye than a page lifting.
45
+ float D = uLeafW * 5.3;
64
46
  float persp = D / max(D - Z, 1.0);
65
47
  float cx = uViewport.x * 0.5;
66
- float cy = uLeaf.y + 0.5 * uLeaf.w;
67
- px = cx + (px - cx) * persp;
68
- py = cy + (py - cy) * min(persp, 1.0);
48
+ float cy = uViewport.y * 0.5;
49
+ float px = cx + (bookX - cx) * persp;
50
+ float py = cy + (bookY - cy) * min(persp, 1.0); // Y only shrinks (top-safe)
69
51
  vec2 p = vec2(px, py) * uView.x + uView.yz;
70
52
  vec2 clip = p / uViewport * 2.0 - 1.0;
71
53
  gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);
72
- vUv = aUnit;
73
- vU = u;
74
- vLight = cos(phi + uAngle);
75
- }`,F=`#version 300 es
54
+ vUv = aUv;
55
+ vFacing = aNormal.z;
56
+ vU = aUv.x;
57
+ }`,K=`#version 300 es
76
58
  precision mediump float;
77
59
  in vec2 vUv;
60
+ in float vFacing;
78
61
  in float vU;
79
- in float vLight;
80
62
  uniform sampler2D uFront;
81
63
  uniform sampler2D uBack;
82
- uniform highp float uDir; // must match the vertex stage's default highp
64
+ uniform highp float uDir;
65
+ uniform float uGloss; // 0 disables the specular highlight (e.g. the flat 'simple' curl)
66
+ uniform float uAlpha; // leaf opacity; a lone page dissolves into the page landing beneath it
83
67
  out vec4 outColor;
84
68
  void main() {
85
- // A backward flip (uDir < 0) mirrors the mesh horizontally, which flips both the
86
- // projected winding (gl_FrontFacing) and the page's u->x mapping; undo both here.
69
+ // The turn mesh carries its own facing in the normal; the front points at the viewer
70
+ // (normal.z > 0) until the leaf passes vertical, for both flip directions. u->x still
71
+ // flips with uDir so a left-hand leaf reads spine-inward.
72
+ bool showFront = vFacing > 0.0;
87
73
  float fx = uDir > 0.0 ? vUv.x : 1.0 - vUv.x;
88
- // Front/back from the sheet's smooth facing (vLight), NOT gl_FrontFacing: the
89
- // winding-based test flickers per-pixel at grazing angles as the curl overlaps.
90
- bool showFront = vLight > 0.0;
91
74
  vec4 c = showFront ? texture(uFront, vec2(fx, vUv.y)) : texture(uBack, vec2(1.0 - fx, vUv.y));
92
75
 
93
- // Diffuse curl shading from the (smooth) facing magnitude: face-on bright, edge-on dark.
94
- float diff = clamp(abs(vLight), 0.0, 1.0);
95
- float lit = mix(0.72, 1.0, diff); // ambient floor, never crushed
96
- float sheen = smoothstep(0.6, 0.95, diff) * (1.0 - diff) * 0.5; // soft crest highlight
97
- // Spine crease uses the SAME curve as the static gutter shadow, so when the leaf
98
- // lands the shadow is continuous instead of popping away.
99
- lit *= mix(0.72, 1.0, smoothstep(0.0, 0.10, vU));
76
+ // Fold shading: the sheet darkens sharply where it curves away from the viewer, so the
77
+ // rolled edge reads as a deep crease with a soft highlight riding the ridge.
78
+ float diff = clamp(abs(vFacing), 0.0, 1.0);
79
+ float lit = mix(0.42, 1.0, diff);
80
+ lit *= mix(0.7, 1.0, smoothstep(0.0, 0.12, vU)); // spine crease matches the gutter shadow
100
81
 
101
- c.rgb = clamp(c.rgb * lit + sheen, 0.0, 1.0);
102
- outColor = c;
103
- }`,I=24,L=4e3,R=256*1024*1024,z=class{#e=null;#t=null;#n=null;#r=null;#i=null;#a=null;#o=null;#s=0;#c=new Map;#l=0;#u=null;#d={};#f={};#p={scale:1,tx:0,ty:0};#m=1;#h=null;#g=!1;#_=null;#v=0;#y=`forward`;#b=!1;#x=!1;#S=null;#C=null;mount(e){this.#e=e;let t=e.ownerDocument,n=t.createElement(`canvas`);return n.style.cssText=`display:block;width:100%;height:100%;`,e.append(n),this.#t=n,n.addEventListener(`webglcontextlost`,this.#w),n.addEventListener(`webglcontextrestored`,this.#T),t.addEventListener(`visibilitychange`,this.#E),this.#n=w(n),this.#k(),Promise.resolve()}destroy(){this.#O();let e=this.#t;e!==null&&(e.removeEventListener(`webglcontextlost`,this.#w),e.removeEventListener(`webglcontextrestored`,this.#T),e.ownerDocument.removeEventListener(`visibilitychange`,this.#E));let t=this.#n;if(t!==null){for(let e of this.#c.values())t.deleteTexture(e.tex);this.#u!==null&&t.deleteTexture(this.#u),this.#a!==null&&t.deleteVertexArray(this.#a),this.#o!==null&&t.deleteVertexArray(this.#o),this.#r!==null&&t.deleteProgram(this.#r),this.#i!==null&&t.deleteProgram(this.#i),t.getExtension(`WEBGL_lose_context`)?.loseContext()}e?.remove(),this.#c.clear(),this.#l=0,this.#u=null,this.#e=null,this.#t=null,this.#n=null,this.#h=null,this.#_=null}onFatal(e){this.#C=e}renderSpread(e,t,n){this.#h=t,this.#g=n?.fill??!1,this.#_=null,this.#A()}beginFlip(e,t,n,r){let i=r?.fill??!1;this.#y=n,this.#v=0,i?this.#_={underLeft:null,underRight:null,underFull:t.right??t.left,front:e.right??e.left,back:t.right??t.left,dir:n===`forward`?1:-1,spineAtStart:n===`forward`?0:1,fill:!0}:n===`forward`?this.#_={underLeft:e.left,underRight:t.right,underFull:null,front:e.right,back:t.left,dir:1,spineAtStart:.5,fill:!1}:this.#_={underLeft:t.left,underRight:e.right,underFull:null,front:e.left,back:t.right,dir:-1,spineAtStart:.5,fill:!1},this.#A()}setFlipProgress(e,t){this.#v=e,this.#y=t,this.#A()}setViewTransform(e,t,n){this.#p={scale:e,tx:t,ty:n},this.#A()}measure(){let e=this.#e,t=e?.clientWidth??0,n=e?.clientHeight??0;return{containerWidth:t,containerHeight:n,pageWidth:t/2,pageHeight:n}}#w=e=>{e.preventDefault(),this.#b=!0,this.#S===null&&(this.#S=setTimeout(()=>this.#D(),L))};#T=()=>{this.#O(),this.#b=!1,this.#k(),this.#A()};#E=()=>{this.#t?.ownerDocument.visibilityState===`visible`&&this.#A()};#D(){this.#x||(this.#x=!0,this.#C?.())}#O(){this.#S!==null&&(clearTimeout(this.#S),this.#S=null)}#k(){let e=this.#n;if(e===null)return;this.#r=E(e,M,N),this.#i=E(e,P,F);for(let t of[`uViewport`,`uRect`,`uView`,`uTex`,`uGutterSide`])this.#d[t]=e.getUniformLocation(this.#r,t);for(let t of[`uViewport`,`uLeaf`,`uView`,`uAngle`,`uCurl`,`uDir`,`uFront`,`uBack`])this.#f[t]=e.getUniformLocation(this.#i,t);this.#a=this.#z(e,this.#r,new Float32Array([0,0,1,0,0,1,1,1]));let t=[];for(let e=0;e<=I;e++){let n=e/I;t.push(n,0,n,1)}this.#s=50,this.#o=this.#z(e,this.#i,new Float32Array(t)),this.#c.clear(),this.#l=0,this.#u=this.#R(e),e.useProgram(this.#r),e.uniform1i(this.#d.uTex??null,0),e.useProgram(this.#i),e.uniform1i(this.#f.uFront??null,0),e.uniform1i(this.#f.uBack??null,1),e.clearColor(0,0,0,0),e.enable(e.BLEND),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA)}#A(){let e=this.#n,t=this.#t;e===null||t===null||this.#b||e.isContextLost()||(this.#B(),e.clear(e.COLOR_BUFFER_BIT),this.#_===null?this.#h!==null&&this.#j():this.#M())}#j(){let e=this.#t,t=e.width,n=e.height;this.#N();let r=this.#h;this.#g?this.#P({x:0,y:0,w:t,h:n},r.right??r.left):(this.#P({x:0,y:0,w:t/2,h:n},r.left,1),this.#P({x:t/2,y:0,w:t/2,h:n},r.right,-1))}#M(){let e=this.#n,t=this.#t,n=t.width,r=t.height,i=this.#_,a=_(this.#v);if(this.#N(),i.fill?this.#P({x:0,y:0,w:n,h:r},i.underFull):(this.#P({x:0,y:0,w:n/2,h:r},i.underLeft,1),this.#P({x:n/2,y:0,w:n/2,h:r},i.underRight,-1)),i.front===null&&i.back===null)return;this.#F(e.TEXTURE0,i.front),this.#F(e.TEXTURE1,i.back),e.activeTexture(e.TEXTURE0);let o=i.fill?n:n/2,s=i.spineAtStart*n;e.useProgram(this.#i),e.bindVertexArray(this.#o),e.uniform2f(this.#f.uViewport??null,n,r),e.uniform3f(this.#f.uView??null,this.#p.scale,this.#p.tx*this.#m,this.#p.ty*this.#m),e.uniform4f(this.#f.uLeaf??null,s,0,o,r),e.uniform1f(this.#f.uAngle??null,a.angle),e.uniform1f(this.#f.uCurl??null,a.curl),e.uniform1f(this.#f.uDir??null,i.dir),e.drawArrays(e.TRIANGLE_STRIP,0,this.#s)}#N(){let e=this.#n,t=this.#t;e.useProgram(this.#r),e.bindVertexArray(this.#a),e.activeTexture(e.TEXTURE0),e.uniform2f(this.#d.uViewport??null,t.width,t.height),e.uniform3f(this.#d.uView??null,this.#p.scale,this.#p.tx*this.#m,this.#p.ty*this.#m)}#P(e,t,n=0){let r=this.#n;t!==null&&(this.#F(r.TEXTURE0,t),r.uniform4f(this.#d.uRect??null,e.x,e.y,e.w,e.h),r.uniform1f(this.#d.uGutterSide??null,n),r.drawArrays(r.TRIANGLE_STRIP,0,4))}#F(e,t){let n=this.#n;n.activeTexture(e),n.bindTexture(n.TEXTURE_2D,t===null?this.#u:this.#I(t))}#I(e){let t=this.#n,n=this.#c.get(e);if(n!==void 0)return this.#c.delete(e),this.#c.set(e,n),n.tex;let r=k(t);A(t,r,e);let i=e,a=i.width*i.height*4;return this.#c.set(e,{tex:r,bytes:a}),this.#l+=a,this.#L(),r}#L(){let e=this.#n;for(let[t,n]of this.#c){if(this.#l<=R||this.#c.size<=4)break;this.#c.delete(t),this.#l-=n.bytes,e.deleteTexture(n.tex)}}#R(e){let t=k(e);return e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([0,0,0,0])),t}#z(e,t,n){let r=e.createVertexArray(),i=e.createBuffer();if(r===null||i===null)throw Error(`WebglRenderer: could not create buffers.`);e.bindVertexArray(r),e.bindBuffer(e.ARRAY_BUFFER,i),e.bufferData(e.ARRAY_BUFFER,n,e.STATIC_DRAW);let a=e.getAttribLocation(t,`aUnit`);return e.enableVertexAttribArray(a),e.vertexAttribPointer(a,2,e.FLOAT,!1,0,0),e.bindVertexArray(null),r}#B(){let e=this.#n,t=this.#t,n=this.#e;if(e===null||t===null||n===null)return;this.#m=typeof devicePixelRatio==`number`?devicePixelRatio:1;let r=Math.max(1,Math.round(n.clientWidth*this.#m)),i=Math.max(1,Math.round(n.clientHeight*this.#m));(t.width!==r||t.height!==i)&&(t.width=r,t.height=i,e.viewport(0,0,r,i))}}})),V={css:async()=>new(await(Promise.resolve().then(()=>(C(),y)))).CssRenderer,webgl2:async()=>new(await(Promise.resolve().then(()=>(B(),te)))).WebglRenderer},H=!0;function U(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&typeof e.mount==`function`}function W(e){return e.gpu&&H?[`webgl2`,`css`]:[`css`]}function G(){return{gpu:K()}}function K(){try{return!!document.createElement(`canvas`).getContext(`webgl2`)}catch{return!1}}async function q(e=`auto`,t=G()){if(U(e))return e;let n=Array.isArray(e)?e:e===`auto`?W(t):[e];for(let e of n){if(e===`webgl2`&&!t.gpu)continue;let n=V[e];if(n)return n()}throw n.length===1&&n[0]===`webgl2`&&!t.gpu?Error(`renderer: 'webgl2' was forced but this device has no WebGL2. Use 'css' or 'auto'.`):Error(`renderer: none of [${n.join(`, `)}] could be loaded — use 'css' or 'auto'.`)}var J=.25,Y=.0015,X=6,Z=250,ne=class{#e;#t;#n=new c;#r=new s(2);#i=new d;#a;#o;#s;#c;#l;#u;#d;#f=!1;#p;#m=[];#h=0;#g=0;#_={left:null,right:null};#v;#y;#b;#x;#S;#C=null;#w=!1;#T=1;#E=0;#D=0;#O=null;#k=!1;#A=!1;#j=null;#M=null;#N=null;#P=null;#F=null;#I=null;#L=!1;#R=1;#z=!1;#B=null;#V=null;#H=null;#U=null;#W=null;#G;debug={setFlipProgress:(e,t)=>{this.#O?.setFlipProgress(e,t)}};constructor(e,t){ae(e,t),this.#e=e,t.width!==void 0&&(e.style.width=`${t.width}px`),t.height!==void 0&&(e.style.height=`${t.height}px`),this.#t=t.source;let n=t.direction??`ltr`,r=t.cover??!1;this.#a=n,this.#o=r,this.#s=t.clickToFlip??`edge`,this.#c=t.clickZoneSize??64,this.#d=t.singlePageThreshold??640,this.#p=t.startPage,typeof this.#t.open!=`function`&&this.#ke(),this.#v=t.flipDuration??800,this.#y=t.zoom?.enabled??!0,this.#b=t.zoom?.wheel??!0;let i=t.zoom?.doubleClick,a=i===!1?[]:[...i??[1,2,4]].sort((e,t)=>e-t);this.#x=a.length>0?a:null,this.#S=t.zoom?.max??4;let o=this.#y&&this.#x!==null,s=t.zoom?.doubleClickInFlipZone??this.#s===`half`;this.#l=this.#s!==`off`&&o&&s&&t.clickFlipDelay!==0,this.#u=this.#l?t.clickFlipDelay??Z:0,this.#G=this.#fe(t.renderer??`auto`)}get ready(){return this.#G}getPageCount(){return this.#t.pageCount}getPage(){return this.#g}flipNext(){this.#q(this.#h+1)}flipPrev(){this.#q(this.#h-1)}flipTo(e){let t=Q(e,0,Math.max(0,this.#t.pageCount-1));this.#q(this.#Oe(t))}getZoom(){return this.#T}setZoom(e,t){if(!this.#O||!this.#y)return;let n=Q(e,1,this.#S),r=this.#O.measure(),i=t??{x:r.containerWidth/2,y:r.containerHeight/2},a=this.#T,o=n===1?0:i.x-n/a*(i.x-this.#E),s=n===1?0:i.y-n/a*(i.y-this.#D);[o,s]=this.#K(o,s,n,r.containerWidth,r.containerHeight),this.#T=n,this.#E=o,this.#D=s,this.#O.setViewTransform(n,o,s),this.#n.emit(`zoomChanged`,{scale:n})}resetZoom(){this.setZoom(1)}#K(e,t,n,r,i){return[Q(e,r*(1-n),0),Q(t,i*(1-n),0)]}on(e,t){return this.#n.on(e,t)}destroy(){this.#A=!0,this.#j!==null&&cancelAnimationFrame(this.#j),this.#ae(),this.#C?.disconnect(),this.#W?.(),this.#H?.(),this.#U?.(),this.#V?.(),this.#O?.destroy(),this.#O=null,this.#t.destroy(),this.#n.clear()}#q(e){if(e<0||e>=this.#m.length||e===this.#h||this.#i.send(`flip`)===null)return;let t=e>this.#h?`forward`:`backward`,n=this.#Z(e);this.#n.emit(`flipStart`,{from:this.#g,to:n}),this.#J(e,t,n)}async#J(e,t,n){let r=this.#m[e],i=r?await this.#Te(r):{left:null,right:null};this.#O?.beginFlip(this.#_,i,t,{fill:this.#f}),this.#Y(0,1,t,()=>this.#X(e,n,i))}#Y(e,t,n,r){let i=this.#ye()*Math.abs(t-e);if(i<=0){this.#O?.setFlipProgress(t,n),r();return}let a=performance.now(),o=s=>{let c=Math.min(1,(s-a)/i);this.#O?.setFlipProgress(e+(t-e)*re(c),n),c<1?this.#j=requestAnimationFrame(o):(this.#j=null,r())};this.#j=requestAnimationFrame(o)}#X(e,t,n){let r=this.#m[e];this.#h=e,this.#g=t,this.#_=n,r&&this.#Se(r,n),this.#De(),this.#i.send(`settle`),this.#ve(),this.#n.emit(`pageChanged`,{page:t}),this.#n.emit(`flipEnd`,{page:t})}#Z(e){let t=this.#m[e];if(!t)return this.#g;let n=[t.left,t.right].filter(e=>e!==null);return n.length>0?Math.min(...n):this.#g}#Q(e,t){if(this.#L||!this.#O||this.#i.state!==`idle`)return;if(this.#ae(),this.#T>1){if(this.#i.send(`panStart`)===null)return;this.#I={baseTx:this.#E,baseTy:this.#D};return}let n=this.#e.getBoundingClientRect(),r={x:e-n.left,y:t-n.top};this.#P=r;let{containerWidth:i,containerHeight:a}=this.#O.measure(),o=Math.min(i,a)*J;if(g(r,{width:i,height:a},o)!==`corner`)return;let s=r.x>i/2,c=this.#a===`rtl`?!s:s,l=this.#h+(c?1:-1);l<0||l>=this.#m.length||(this.#N={direction:c?`forward`:`backward`,targetIndex:l,toPage:this.#Z(l),width:i})}#$(){let e=this.#N;e&&(this.#N=null,this.#i.send(`grab`)!==null&&(this.#M={direction:e.direction,targetIndex:e.targetIndex,toPage:e.toPage,toContent:{left:null,right:null},width:e.width,t:0},this.#n.emit(`flipStart`,{from:this.#g,to:e.toPage}),this.#ee(e.targetIndex,e.direction)))}async#ee(e,t){let n=this.#m[e],r=n?await this.#Te(n):{left:null,right:null};this.#M?.targetIndex===e&&(this.#M.toContent=r,this.#O?.beginFlip(this.#_,r,t,{fill:this.#f}),this.#O?.setFlipProgress(this.#M.t,t))}#te(e,t){if(this.#L)return;if(this.#I){if(!this.#O)return;let n=this.#O.measure(),[r,i]=this.#K(this.#I.baseTx+e,this.#I.baseTy+t,this.#T,n.containerWidth,n.containerHeight);this.#E=r,this.#D=i,this.#O.setViewTransform(this.#T,r,i);return}this.#N&&Math.hypot(e,t)>X&&this.#$();let n=this.#M;n&&(n.t=Q((n.direction===`forward`?-e:e)/n.width,0,1),this.#O?.setFlipProgress(n.t,n.direction))}#ne(e){if(this.#L)return;if(this.#I){this.#I=null,this.#i.send(`panEnd`);return}let t=this.#M;if(!t){this.#N=null,this.#re(e);return}this.#M=null,this.#i.send(`release`);let n=e.swipe&&(t.direction===`forward`?e.dx<0:e.dx>0);t.t>=.5||n?this.#Y(t.t,1,t.direction,()=>this.#X(t.targetIndex,t.toPage,t.toContent)):this.#Y(t.t,0,t.direction,()=>this.#oe())}#re(e){if(this.#s===`off`||this.#T>1||!this.#P||Math.abs(e.dx)>X||Math.abs(e.dy)>X)return;let t=this.#ie(this.#P);if(!t)return;let n=this.#h+(t===`forward`?1:-1);if(!(n<0||n>=this.#m.length)){if(this.#ae(),this.#u<=0){this.#q(n);return}this.#F=setTimeout(()=>{this.#F=null,this.#q(n)},this.#u)}}#ie(e){if(!this.#O)return null;let{containerWidth:t}=this.#O.measure(),n;if(n=this.#s===`half`?e.x>t/2?`right`:`left`:e.x<=this.#c?`left`:e.x>=t-this.#c?`right`:null,!n)return null;let r=this.#a===`rtl`?`left`:`right`;return n===r?`forward`:`backward`}#ae(){this.#F!==null&&(clearTimeout(this.#F),this.#F=null)}#oe(){let e=this.#m[this.#h];e&&this.#Se(e,this.#_),this.#i.send(`settle`),this.#n.emit(`flipEnd`,{page:this.#g})}#se(){if(this.#N=null,this.#ae(),this.#M){this.#M=null,this.#i.send(`release`),this.#i.send(`settle`);let e=this.#m[this.#h];e&&this.#Se(e,this.#_)}else this.#I&&(this.#I=null,this.#i.send(`panEnd`));this.#L=!0,this.#R=this.#T}#ce(e,t,n){if(!this.#L)return;let r=this.#e.getBoundingClientRect();this.setZoom(this.#R*n,{x:e-r.left,y:t-r.top})}#le(){this.#L=!1}#ue(){let e=e=>{if(!this.#b||!this.#y||!(e.ctrlKey||e.metaKey))return;e.preventDefault();let t=this.#e.getBoundingClientRect(),n=Math.exp(-e.deltaY*Y);this.setZoom(this.#T*n,{x:e.clientX-t.left,y:e.clientY-t.top})};this.#e.addEventListener(`wheel`,e,{passive:!1}),this.#H=()=>this.#e.removeEventListener(`wheel`,e)}#de(){let e=e=>{let t=this.#x;if(!this.#y||t===null)return;if(this.#T<=1&&this.#s!==`off`&&!this.#l){let t=this.#e.getBoundingClientRect(),n={x:e.clientX-t.left,y:e.clientY-t.top};if(this.#ie(n)!==null)return}this.#ae(),e.preventDefault();let n=t.find(e=>e>this.#T+1e-6)??t[0]??this.#T,r=this.#e.getBoundingClientRect();this.setZoom(n,{x:e.clientX-r.left,y:e.clientY-r.top})};this.#e.addEventListener(`dblclick`,e),this.#U=()=>this.#e.removeEventListener(`dblclick`,e)}async#fe(e){let t=q(e);typeof this.#t.open==`function`&&(await this.#t.open(),this.#ke()),this.#t.prefetch([this.#g]);let n=await t,r=await this.#pe(n);this.#O=r,this.#be(r.measure().containerWidth);let i=new f({onStart:e=>this.#Q(e.x,e.y),onMove:e=>this.#te(e.dx,e.dy),onEnd:e=>this.#ne(e)}),a=new h({onPinchStart:()=>this.#se(),onPinchMove:e=>this.#ce(e.centerX,e.centerY,e.scale),onPinchEnd:()=>this.#le()});this.#V=p(this.#e,{pointer:i,pinch:a}),this.#ue(),this.#de(),this.#he(),this.#W=this.#ge(),await this.#xe(),this.#Ce(),this.#De(),this.#ve(),this.#n.emit(`ready`)}async#pe(e){try{return await e.mount(this.#e),e.onFatal?.(()=>{this.#me()}),e}catch{e.destroy();let t=await q(`css`);return await t.mount(this.#e),this.#k=!0,this.#n.emit(`rendererFallback`,{from:`webgl2`,to:`css`}),t}}async#me(){if(this.#k||this.#A)return;this.#k=!0,this.#O?.destroy(),this.#O=null;let e=await q(`css`);if(this.#A){e.destroy();return}await e.mount(this.#e),this.#O=e,this.#be(e.measure().containerWidth),await this.#xe(),this.#n.emit(`rendererFallback`,{from:`webgl2`,to:`css`})}#he(){if(typeof matchMedia!=`function`)return;let e=matchMedia(`(prefers-reduced-motion: reduce)`);this.#z=e.matches,e.addEventListener?.(`change`,e=>{this.#z=e.matches})}#ge(){let e=this.#e,t=e.ownerDocument;if(!t||typeof e.setAttribute!=`function`)return null;e.hasAttribute(`tabindex`)||(e.tabIndex=0),e.setAttribute(`aria-roledescription`,`flipbook`);let n=e=>this.#_e(e);e.addEventListener(`keydown`,n);let r=t.createElement(`div`);return r.setAttribute(`aria-live`,`polite`),r.setAttribute(`aria-atomic`,`true`),r.style.cssText=`position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;`,e.appendChild(r),this.#B=r,()=>{e.removeEventListener(`keydown`,n),r.remove(),this.#B=null}}#_e(e){let t=this.#a===`rtl`?`ArrowLeft`:`ArrowRight`;switch(e.key){case`ArrowRight`:case`ArrowLeft`:e.key===t?this.flipNext():this.flipPrev(),e.preventDefault();break;case`Home`:this.flipTo(0),e.preventDefault();break;case`End`:this.flipTo(this.#t.pageCount-1),e.preventDefault();break;default:break}}#ve(){this.#B&&(this.#B.textContent=`Page ${this.#g+1} of ${this.#t.pageCount}`)}#ye(){return this.#z?0:this.#v}update(){!this.#O||this.#i.state!==`idle`||(this.#be(this.#O.measure().containerWidth),this.#xe())}#be(e){let t=a(e,this.#d);t!==this.#f&&(this.#f=t,this.#m=i(this.#t.pageCount,{direction:this.#a,cover:this.#o,singlePage:t}),this.#h=this.#Oe(this.#g))}async#xe(){let e=this.#m[this.#h];!e||!this.#O||(this.#_=await this.#Te(e),this.#Se(e,this.#_))}#Se(e,t){this.#O?.renderSpread(e,t,{fill:this.#f})}#Ce(){typeof ResizeObserver>`u`||(this.#C=new ResizeObserver(()=>this.#we()),this.#C.observe(this.#e))}#we(){this.#w||(this.#w=!0,requestAnimationFrame(()=>{this.#w=!1,this.update()}))}async#Te(e){let[t,n]=await Promise.all([this.#Ee(e.left),this.#Ee(e.right)]);return{left:t,right:n}}async#Ee(e){if(e===null)return null;try{return await this.#t.get(e)}catch(t){return this.#n.emit(`sourceError`,{index:e,error:t}),null}}#De(){let{toMount:e}=this.#r.update(this.#h,this.#m.length),t=[];for(let n of e){let e=this.#m[n];e?.left!=null&&t.push(e.left),e?.right!=null&&t.push(e.right)}this.#t.prefetch(t)}#Oe(e){let t=this.#m.findIndex(t=>t.left===e||t.right===e);return t===-1?0:t}#ke(){let e=this.#t.pageCount;if(!Number.isInteger(e)||e<1)throw Error(`Zine: source has ${e} pages; a Source must have at least 1 page.`);let t=this.#p;if(t!==void 0&&(!Number.isInteger(t)||t<0||t>=e))throw Error(`Zine: startPage ${JSON.stringify(t)} is out of range for a ${e}-page book (valid 0..${e-1}).`);this.#m=i(e,{direction:this.#a,cover:this.#o}),this.#g=Q(t??0,0,e-1),this.#h=this.#Oe(this.#g)}};function Q(e,t,n){return e<t?t:e>n?n:e}function re(e){return e<.5?4*e*e*e:1-(-2*e+2)**3/2}function ie(e){return e===null?`null`:Array.isArray(e)?`array`:typeof e}function ae(e,t){if(typeof e!=`object`||!e||typeof e.appendChild!=`function`||typeof e.addEventListener!=`function`)throw Error(`Zine: container must be a DOM element; received ${ie(e)}.`);if(typeof t!=`object`||!t)throw Error("Zine: an options object with a `source` is required.");let n=t,r=n.source;if(typeof r!=`object`||!r||typeof r.get!=`function`||typeof r.pageCount!=`number`)throw Error("Zine: `source` is required and must be a Source, e.g. new ImageSource(urls).");let i=n.startPage;if(i!==void 0&&(typeof i!=`number`||!Number.isInteger(i)||i<0))throw Error(`Zine: startPage must be a non-negative integer; got ${JSON.stringify(i)}.`);let a=n.direction;if(a!==void 0&&a!==`ltr`&&a!==`rtl`)throw Error(`Zine: direction must be 'ltr' or 'rtl'; got ${JSON.stringify(a)}.`);let o=n.clickToFlip;if(o!==void 0&&![`edge`,`half`,`off`].includes(o))throw Error(`Zine: clickToFlip must be 'edge', 'half', or 'off'; got ${JSON.stringify(o)}.`);$(n.width,`width`,1),$(n.height,`height`,1),$(n.flipDuration,`flipDuration`,0),$(n.clickZoneSize,`clickZoneSize`,0),$(n.clickFlipDelay,`clickFlipDelay`,0),$(n.singlePageThreshold,`singlePageThreshold`,0),oe(n.zoom),se(n.renderer)}function $(e,t,n){if(e!==void 0&&(typeof e!=`number`||!Number.isFinite(e)||e<n))throw Error(`Zine: ${t} must be a number >= ${n}; got ${JSON.stringify(e)}.`)}function oe(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Zine: zoom must be an object, e.g. { max: 4 }.`);let t=e;if(t.enabled!==void 0&&typeof t.enabled!=`boolean`)throw Error(`Zine: zoom.enabled must be a boolean; got ${JSON.stringify(t.enabled)}.`);if(t.wheel!==void 0&&typeof t.wheel!=`boolean`)throw Error(`Zine: zoom.wheel must be a boolean; got ${JSON.stringify(t.wheel)}.`);if(t.doubleClickInFlipZone!==void 0&&typeof t.doubleClickInFlipZone!=`boolean`)throw Error(`Zine: zoom.doubleClickInFlipZone must be a boolean; got ${JSON.stringify(t.doubleClickInFlipZone)}.`);if(t.doubleClick!==void 0&&t.doubleClick!==!1){let e=t.doubleClick;if(!Array.isArray(e)||e.some(e=>typeof e!=`number`||!Number.isFinite(e)||e<1))throw Error(`Zine: zoom.doubleClick must be false or an array of zoom levels >= 1, e.g. [1, 2, 4].`)}$(t.max,`zoom.max`,1)}function se(e){if(e!==void 0){if(typeof e==`string`){if(e!==`auto`&&e!==`css`&&e!==`webgl2`)throw Error(`Zine: renderer '${e}' is not recognized; use 'auto', 'css', 'webgl2', an array of those, or a custom Renderer.`);return}if(Array.isArray(e)){for(let t of e)if(t!==`css`&&t!==`webgl2`)throw Error(`Zine: renderer order array may only contain 'css' or 'webgl2'; got ${JSON.stringify(t)}.`);return}if(!(typeof e==`object`&&e&&typeof e.mount==`function`))throw Error(`Zine: renderer must be 'auto', 'css', 'webgl2', an array of those, or a custom Renderer instance.`)}}e.ImageSource=class{pageCount;fit;#e;#t;#n=new Map;constructor(e,t={}){this.#e=e,this.pageCount=e.length,this.#t=t.preload??1,this.fit=t.fit??`contain`}get(e){let t=this.#r(e);for(let t=1;t<=this.#t;t++)this.prefetch([e-t,e+t]);return t}prefetch(e){for(let t of e)t>=0&&t<this.pageCount&&this.#r(t).catch(()=>{})}destroy(){for(let e of this.#n.values())e.then(e=>e.close()).catch(()=>{});this.#n.clear()}#r(e){let t=this.#n.get(e);if(t)return t;let n=this.#e[e];if(n===void 0)return Promise.reject(RangeError(`ImageSource: page ${e} is out of range (0..${this.pageCount-1}).`));let r=(async()=>{let t=await fetch(n);if(!t.ok)throw Error(`ImageSource: failed to fetch page ${e} (${n}) — HTTP ${t.status}.`);return createImageBitmap(await t.blob())})().catch(t=>{throw this.#n.delete(e),t});return this.#n.set(e,r),r}},e.Zine=ne});
82
+ // Glossy specular: brightest where the surface tilts ~30 deg from facing the viewer,
83
+ // so a thin glossy highlight rides across the sheet as it rolls.
84
+ float spec = pow(max(cos(acos(diff) - 0.52), 0.0), 220.0) * 0.22 * uGloss;
85
+
86
+ c.rgb = clamp(c.rgb * lit + spec, 0.0, 1.0);
87
+ // Premultiplied alpha (blendFunc ONE, ONE_MINUS_SRC_ALPHA): scale colour as well as alpha,
88
+ // or fading would brighten the sheet additively instead of dissolving it.
89
+ outColor = vec4(c.rgb * uAlpha, c.a * uAlpha);
90
+ }`,q=28,J=36,De=.7,Oe=.8,ke=4e3,Ae=256*1024*1024,je=class{#e=null;#t=null;#n=null;#r=null;#i=null;#a=null;#o=null;#s=null;#c=null;#l=0;#u=te(q,J);#d=new Map;#f=0;#p=null;#m={};#h={};#g={scale:1,tx:0,ty:0};#_=1;#v=null;#y=!1;#b=null;#x=0;#S=y;#C={y:.5};#w=0;#T=0;#E=0;#D=0;#O=0;#k=0;#A=!1;#j=!1;#M=null;#N=null;mount(e){this.#e=e;let t=e.ownerDocument,n=t.createElement(`canvas`);return n.style.cssText=`display:block;width:100%;height:100%;`,e.append(n),this.#t=n,n.addEventListener(`webglcontextlost`,this.#L),n.addEventListener(`webglcontextrestored`,this.#R),t.addEventListener(`visibilitychange`,this.#z),this.#n=xe(n),this.#H(),Promise.resolve()}destroy(){this.#V();let e=this.#t;e!==null&&(e.removeEventListener(`webglcontextlost`,this.#L),e.removeEventListener(`webglcontextrestored`,this.#R),e.ownerDocument.removeEventListener(`visibilitychange`,this.#z));let t=this.#n;if(t!==null){for(let e of this.#d.values())t.deleteTexture(e.tex);this.#p!==null&&t.deleteTexture(this.#p),this.#a!==null&&t.deleteVertexArray(this.#a),this.#o!==null&&t.deleteVertexArray(this.#o),this.#r!==null&&t.deleteProgram(this.#r),this.#i!==null&&t.deleteProgram(this.#i),t.getExtension(`WEBGL_lose_context`)?.loseContext()}e?.remove(),this.#d.clear(),this.#f=0,this.#p=null,this.#e=null,this.#t=null,this.#n=null,this.#v=null,this.#b=null}onFatal(e){this.#N=e}renderSpread(e,t,n){this.#v=t,this.#y=n?.fill??!1,this.#b=null,this.#P(t),this.#G()}#P(e){let t=e.left??e.right;t&&t.height&&(this.#D=t.width/t.height)}beginFlip(e,t,n,r){let i=r?.fill??!1;this.#x=0,r?.curl&&(this.#S=r.curl),r?.anchor&&(this.#C=r.anchor),this.#T=i?0:H(e),this.#E=i?0:H(t),this.#P(t),i?this.#b={underLeft:null,underRight:null,underFull:t.right??t.left,front:e.right??e.left,back:e.right??e.left,dir:n===`forward`?1:-1,fill:!0}:n===`forward`?this.#b={underLeft:e.left,underRight:t.right,underFull:null,front:e.right,back:t.left,dir:1,fill:!1}:this.#b={underLeft:t.left,underRight:e.right,underFull:null,front:e.left,back:t.right,dir:-1,fill:!1},this.#G()}setFlipProgress(e,t){this.#x=e,this.#G()}setViewTransform(e,t,n){this.#g={scale:e,tx:t,ty:n},this.#G()}measure(){let e=this.#e,t=e?.clientWidth??0,n=e?.clientHeight??0,r=this.#D>0,i=r?this.#F():void 0,a=r?this.#I():void 0;return{containerWidth:t,containerHeight:n,pageWidth:t/2,pageHeight:n,book:i,content:a}}#F(){let e=this.#e,t=e?.clientWidth??0,n=e?.clientHeight??0;if(this.#D<=0||t<=0||n<=0)return{x:0,y:0,width:t,height:n};let r=(this.#y?1:2)*this.#D,i=t,a=n;return r>t/n?a=t/r:i=n*r,{x:(t-i)/2,y:(n-a)/2,width:i,height:a}}#I(){let e=this.#F();return!this.#y&&this.#v!==null&&H(this.#v)!==0?{x:e.x+e.width/4,y:e.y,width:e.width/2,height:e.height}:e}#L=e=>{e.preventDefault(),this.#A=!0,this.#M===null&&(this.#M=setTimeout(()=>this.#B(),ke))};#R=()=>{this.#V(),this.#A=!1,this.#H(),this.#G()};#z=()=>{this.#t?.ownerDocument.visibilityState===`visible`&&this.#G()};#B(){this.#j||(this.#j=!0,this.#N?.())}#V(){this.#M!==null&&(clearTimeout(this.#M),this.#M=null)}#H(){let e=this.#n;if(e!==null){this.#r=z(e,U,W),this.#i=z(e,G,K);for(let t of[`uViewport`,`uRect`,`uView`,`uTex`,`uGutterSide`])this.#m[t]=e.getUniformLocation(this.#r,t);for(let t of[`uViewport`,`uView`,`uOriginX`,`uDir`,`uLeafW`,`uFront`,`uBack`,`uGloss`,`uAlpha`])this.#h[t]=e.getUniformLocation(this.#i,t);this.#a=this.#U(e,this.#r),this.#W(e,this.#i),this.#d.clear(),this.#f=0,this.#p=this.#te(e),e.useProgram(this.#r),e.uniform1i(this.#m.uTex??null,0),e.useProgram(this.#i),e.uniform1i(this.#h.uFront??null,0),e.uniform1i(this.#h.uBack??null,1),e.clearColor(0,0,0,0),e.enable(e.BLEND),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA)}}#U(e,t){let n=e.createVertexArray(),r=e.createBuffer();if(n===null||r===null)throw Error(`WebglRenderer: could not create buffers.`);e.bindVertexArray(n),e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,1,1]),e.STATIC_DRAW);let i=e.getAttribLocation(t,`aUnit`);return e.enableVertexAttribArray(i),e.vertexAttribPointer(i,2,e.FLOAT,!1,0,0),e.bindVertexArray(null),n}#W(e,t){let n=[];for(let e=0;e<J;e++)for(let t=0;t<q;t++){let r=e*29+t,i=r+1,a=r+29,o=a+1;n.push(r,a,i,i,a,o)}this.#l=n.length;let r=e.createVertexArray();this.#s=e.createBuffer(),this.#c=e.createBuffer();let i=e.createBuffer(),a=e.createBuffer();if(r===null||this.#s===null||this.#c===null||i===null||a===null)throw Error(`WebglRenderer: could not create mesh buffers.`);e.bindVertexArray(r),e.bindBuffer(e.ARRAY_BUFFER,this.#s),e.bufferData(e.ARRAY_BUFFER,this.#u.positions,e.DYNAMIC_DRAW);let o=e.getAttribLocation(t,`aPos`);e.enableVertexAttribArray(o),e.vertexAttribPointer(o,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.#c),e.bufferData(e.ARRAY_BUFFER,this.#u.normals,e.DYNAMIC_DRAW);let s=e.getAttribLocation(t,`aNormal`);e.enableVertexAttribArray(s),e.vertexAttribPointer(s,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,i),e.bufferData(e.ARRAY_BUFFER,this.#u.uvs,e.STATIC_DRAW);let c=e.getAttribLocation(t,`aUv`);e.enableVertexAttribArray(c),e.vertexAttribPointer(c,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,a),e.bufferData(e.ELEMENT_ARRAY_BUFFER,new Uint16Array(n),e.STATIC_DRAW),e.bindVertexArray(null),this.#o=r}#G(){let e=this.#n,t=this.#t;e===null||t===null||this.#A||e.isContextLost()||(this.#ne(),e.clear(e.COLOR_BUFFER_BIT),this.#K(),this.#b===null?this.#v!==null&&this.#q():this.#J())}#K(){let e=this.#n,t=this.#t,n=t.width,r=t.height;if(this.#D>0){let e=(this.#y?1:2)*this.#D;e>n/r?(this.#O=n,this.#k=Math.round(n/e)):(this.#k=r,this.#O=Math.round(r*e))}else this.#O=n,this.#k=r;let i=Math.round((n-this.#O)/2),a=Math.round((r-this.#k)/2);e.viewport(i,a,this.#O,this.#k)}#q(){let e=this.#O,t=this.#k,n=this.#v;this.#w=this.#y?0:H(n)*(e/4),this.#X(),this.#y?this.#Z({x:0,y:0,w:e,h:t},n.right??n.left):(this.#Z({x:0,y:0,w:e/2,h:t},n.left,+!!n.right),this.#Z({x:e/2,y:0,w:e/2,h:t},n.right,n.left?-1:0))}#J(){let e=this.#n,t=this.#O,n=this.#k,r=this.#b;if(this.#w=r.fill?0:(this.#T+(this.#E-this.#T)*this.#x)*(t/4),this.#X(),r.fill?this.#Z({x:0,y:0,w:t,h:n},r.underFull):(this.#Z({x:0,y:0,w:t/2,h:n},r.underLeft,1),this.#Z({x:t/2,y:0,w:t/2,h:n},r.underRight,-1)),r.front===null&&r.back===null)return;let i=r.fill?t:t/2,a=r.fill?r.dir>0?0:t:t/2;R[this.#S].deform(this.#u,i,n,this.#x,{y:this.#C.y,fill:r.fill}),e.bindBuffer(e.ARRAY_BUFFER,this.#s),e.bufferSubData(e.ARRAY_BUFFER,0,this.#u.positions),e.bindBuffer(e.ARRAY_BUFFER,this.#c),e.bufferSubData(e.ARRAY_BUFFER,0,this.#u.normals),this.#Q(e.TEXTURE0,r.front),this.#Q(e.TEXTURE1,r.back),e.activeTexture(e.TEXTURE0),e.useProgram(this.#i),e.bindVertexArray(this.#o),e.uniform2f(this.#h.uViewport??null,t,n),e.uniform3f(this.#h.uView??null,this.#g.scale,this.#g.tx*this.#_+this.#w,this.#g.ty*this.#_),e.uniform1f(this.#h.uOriginX??null,a),e.uniform1f(this.#h.uDir??null,r.dir),e.uniform1f(this.#h.uLeafW??null,i),e.uniform1f(this.#h.uGloss??null,this.#S===`simple`?0:1),e.uniform1f(this.#h.uAlpha??null,r.fill?this.#Y():1),e.drawElements(e.TRIANGLES,this.#l,e.UNSIGNED_SHORT,0)}#Y(){let e=this.#S===`roll`||this.#S===`simple`?De:Oe,t=(this.#x-e)/(1-e);return t<=0?1:t>=1?0:(1-t)**1.5}#X(){let e=this.#n;e.useProgram(this.#r),e.bindVertexArray(this.#a),e.activeTexture(e.TEXTURE0),e.uniform2f(this.#m.uViewport??null,this.#O,this.#k),e.uniform3f(this.#m.uView??null,this.#g.scale,this.#g.tx*this.#_+this.#w,this.#g.ty*this.#_)}#Z(e,t,n=0){let r=this.#n;t!==null&&(this.#Q(r.TEXTURE0,t),r.uniform4f(this.#m.uRect??null,e.x,e.y,e.w,e.h),r.uniform1f(this.#m.uGutterSide??null,n),r.drawArrays(r.TRIANGLE_STRIP,0,4))}#Q(e,t){let n=this.#n;n.activeTexture(e),n.bindTexture(n.TEXTURE_2D,t===null?this.#p:this.#$(t))}#$(e){let t=this.#n,n=this.#d.get(e);if(n!==void 0)return this.#d.delete(e),this.#d.set(e,n),n.tex;let r=V(t);we(t,r,e);let i=e,a=i.width*i.height*4;return this.#d.set(e,{tex:r,bytes:a}),this.#f+=a,this.#ee(),r}#ee(){let e=this.#n;for(let[t,n]of this.#d){if(this.#f<=Ae||this.#d.size<=4)break;this.#d.delete(t),this.#f-=n.bytes,e.deleteTexture(n.tex)}}#te(e){let t=V(e);return e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([0,0,0,0])),t}#ne(){let e=this.#n,t=this.#t,n=this.#e;if(e===null||t===null||n===null)return;this.#_=typeof devicePixelRatio==`number`?devicePixelRatio:1;let r=Math.max(1,Math.round(n.clientWidth*this.#_)),i=Math.max(1,Math.round(n.clientHeight*this.#_));(t.width!==r||t.height!==i)&&(t.width=r,t.height=i,e.viewport(0,0,r,i))}}})),Ne={css:async()=>new(await(Promise.resolve().then(()=>(ee(),C)))).CssRenderer,webgl2:async()=>new(await(Promise.resolve().then(()=>(Me(),Ee)))).WebglRenderer},Pe=!0;function Fe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&typeof e.mount==`function`}function Ie(e){return e.gpu&&Pe?[`webgl2`,`css`]:[`css`]}function Le(){return{gpu:Re()}}function Re(){try{return!!document.createElement(`canvas`).getContext(`webgl2`)}catch{return!1}}async function Y(e=`auto`,t=Le()){if(Fe(e))return e;let n=Array.isArray(e)?e:e===`auto`?Ie(t):[e];for(let e of n){if(e===`webgl2`&&!t.gpu)continue;let n=Ne[e];if(n)return n()}throw n.length===1&&n[0]===`webgl2`&&!t.gpu?Error(`renderer: 'webgl2' was forced but this device has no WebGL2. Use 'css' or 'auto'.`):Error(`renderer: none of [${n.join(`, `)}] could be loaded — use 'css' or 'auto'.`)}function ze(e,t){let n=typeof t.frontCover==`string`,r=typeof t.backCover==`string`,i=t.pages!=null&&Object.keys(t.pages).length>0;return!n&&!r&&!i?e:new Ve(e,t)}function Be(e){return fetch(e).then(t=>{if(!t.ok)throw Error(`zine: could not load image "${e}" (HTTP ${t.status}).`);return t.blob()}).then(e=>createImageBitmap(e))}var Ve=class{#e;#t;#n;#r;#i=new Map;#a=new Map;open;onPageUpdate;constructor(e,t){this.#e=e,this.#t=typeof t.frontCover==`string`?t.frontCover:null,this.#n=typeof t.backCover==`string`?t.backCover:null,this.#r=t.pages??{},typeof e.open==`function`?this.open=async()=>{await e.open(),this.#o()}:this.#o(),typeof e.onPageUpdate==`function`&&(this.onPageUpdate=t=>{e.onPageUpdate(e=>t(e+(this.#t===null?0:1)))})}get pageCount(){return this.#e.pageCount+(this.#t===null?0:1)+(this.#n===null?0:1)}get(e){let t=this.#t===null?0:1;if(this.#t!==null&&e===0)return this.#s(this.#t);if(this.#n!==null&&e===this.pageCount-1)return this.#s(this.#n);let n=e-t,r=this.#i.get(n);return r===void 0?this.#e.get(n):this.#s(r)}prefetch(e){let t=this.#t===null?0:1,n=[];for(let r of e)if(this.#t!==null&&r===0)this.#s(this.#t).catch(()=>{});else if(this.#n!==null&&r===this.pageCount-1)this.#s(this.#n).catch(()=>{});else{let e=r-t,i=this.#i.get(e);i===void 0?n.push(e):this.#s(i).catch(()=>{})}this.#e.prefetch(n)}destroy(){this.#e.destroy();for(let e of this.#a.values())e.then(e=>e.close()).catch(()=>{});this.#a.clear()}#o(){let e=this.#e.pageCount;this.#i.clear();for(let[t,n]of Object.entries(this.#r)){let r=Number(t),i=r<0?e+r:r;Number.isInteger(i)&&i>=0&&i<e&&this.#i.set(i,n)}}#s(e){let t=this.#a.get(e);return t===void 0&&(t=Be(e).catch(t=>{throw this.#a.delete(e),t}),this.#a.set(e,t)),t}};b();var He=.25,Ue=.0015,X=6,We=250,Ge=1.55,Ke=class{#e;#t;#n=new c;#r=new s(2);#i=new d;#a;#o;#s;#c=1;#l;#u;#d;#f;#p;#m=!1;#h=!1;#g=``;#_;#v=[];#y=0;#b=0;#x={left:null,right:null};#S;#C;#w;#T;#E;#D=null;#O=!1;#k=1;#A=0;#j=0;#M=null;#N=!1;#P=!1;#F=null;#I=null;#L=null;#R=null;#z=null;#B=null;#V=null;#H=null;#U=!1;#W=1;#G=!1;#K=null;#q=null;#J=null;#Y=null;#X=null;#Z;debug={setFlipProgress:(e,t)=>{this.#M?.setFlipProgress(e,t)}};constructor(e,t){Ye(e,t),this.#e=e,t.width!==void 0&&(e.style.width=`${t.width}px`),t.height!==void 0&&(e.style.height=`${t.height}px`),this.#t=ze(t.source,{frontCover:t.frontCover,backCover:t.backCover,pages:t.pages});let n=t.direction??`ltr`;this.#a=n,this.#o=t.spreadMode??`cover`,this.#s=t.curl??`cone`,this.#l=t.clickToFlip??`edge`,this.#u=t.clickZoneSize??64,this.#p=t.singlePageThreshold??640,this.#_=t.startPage,typeof this.#t.open!=`function`&&this.#He(),this.#S=t.flipDuration??800,this.#C=t.zoom?.enabled??!0,this.#w=t.zoom?.wheel??!0;let r=t.zoom?.doubleClick,i=r===!1?[]:[...r??[1,2,4]].sort((e,t)=>e-t);this.#T=i.length>0?i:null,this.#E=t.zoom?.max??4;let a=this.#C&&this.#T!==null,o=t.zoom?.doubleClickInFlipZone??this.#l===`half`;this.#d=this.#l!==`off`&&a&&o&&t.clickFlipDelay!==0,this.#f=this.#d?t.clickFlipDelay??We:0,this.#Z=this.#Se(t.renderer??`auto`)}get ready(){return this.#Z}getPageCount(){return this.#t.pageCount}getPage(){return this.#b}flipNext(){this.#Q(()=>this.#ne(this.#y+1))}flipPrev(){this.#Q(()=>this.#ne(this.#y-1))}flipTo(e){let t=Z(e,0,Math.max(0,this.#t.pageCount-1));this.#Q(()=>this.#ne(this.#Ve(t)))}#Q(e){this.#i.state===`idle`?e():this.#V?(this.#$(),e()):this.#B=e}#$(){let e=this.#V;e&&(this.#V=null,this.#F!==null&&(cancelAnimationFrame(this.#F),this.#F=null),this.#M?.setFlipProgress(e.toT,e.direction),e.onDone())}#ee(){let e=this.#B;e&&(this.#B=null,e())}getZoom(){return this.#k}setZoom(e,t){if(!this.#M||!this.#C)return;let n=Z(e,1,this.#E),r=this.#M.measure(),i=t??{x:r.containerWidth/2,y:r.containerHeight/2},a=this.#k,o=n===1?0:i.x-n/a*(i.x-this.#A),s=n===1?0:i.y-n/a*(i.y-this.#j);[o,s]=this.#te(o,s,n,r.containerWidth,r.containerHeight),this.#k=n,this.#A=o,this.#j=s,this.#M.setViewTransform(n,o,s),this.#n.emit(`zoomChanged`,{scale:n})}resetZoom(){this.setZoom(1)}#te(e,t,n,r,i){return[Z(e,r*(1-n),0),Z(t,i*(1-n),0)]}on(e,t){return this.#n.on(e,t)}destroy(){this.#P=!0,this.#F!==null&&cancelAnimationFrame(this.#F),this.#V=null,this.#B=null,this.#he(),this.#D?.disconnect(),this.#X?.(),this.#J?.(),this.#Y?.(),this.#q?.(),this.#M?.destroy(),this.#M=null,this.#t.destroy(),this.#n.clear()}#ne(e){if(e<0||e>=this.#v.length||e===this.#y||this.#i.send(`flip`)===null)return;let t=e>this.#y?`forward`:`backward`,n=this.#oe(e);this.#n.emit(`flipStart`,{from:this.#b,to:n}),this.#re(e,t,n)}async#re(e,t,n){let r=this.#v[e],i=r?await this.#Re(r):{left:null,right:null};this.#M?.beginFlip(this.#x,i,t,{fill:this.#m,curl:this.#s,anchor:{y:this.#c}}),this.#ie(0,1,t,()=>this.#ae(e,n,i))}#ie(e,t,n,r){let i=this.#ke()*Math.abs(t-e);if(i<=0){this.#M?.setFlipProgress(t,n),r();return}let a={toT:t,direction:n,onDone:r};this.#V=a;let o=performance.now(),s=c=>{if(this.#V!==a)return;let l=Math.min(1,(c-o)/i),u=this.#m?qe(l):Q(l);this.#M?.setFlipProgress(e+(t-e)*u,n),l<1?this.#F=requestAnimationFrame(s):(this.#F=null,this.#V=null,r())};this.#F=requestAnimationFrame(s)}#ae(e,t,n){let r=this.#v[e];this.#y=e,this.#b=t,this.#x=n,r&&this.#Ne(r,n),this.#Be(),this.#i.send(`settle`),this.#Oe(),this.#n.emit(`pageChanged`,{page:t}),this.#n.emit(`flipEnd`,{page:t}),this.#ee()}#oe(e){let t=this.#v[e];if(!t)return this.#b;let n=[t.left,t.right].filter(e=>e!==null);return n.length>0?Math.min(...n):this.#b}#se(e,t){if(this.#U||!this.#M||this.#i.state!==`idle`)return;if(this.#he(),this.#k>1){if(this.#i.send(`panStart`)===null)return;this.#H={baseTx:this.#A,baseTy:this.#j};return}let n=this.#e.getBoundingClientRect(),r=this.#pe(),i={x:e-n.left-r.x,y:t-n.top-r.y};this.#R=i;let a=Math.min(r.width,r.height)*He;if(_(i,{width:r.width,height:r.height},a)!==`corner`)return;this.#c=Z(i.y/r.height,0,1);let o=i.x>r.width/2,s=this.#a===`rtl`?!o:o,c=this.#y+(s?1:-1);c<0||c>=this.#v.length||(this.#L={direction:s?`forward`:`backward`,targetIndex:c,toPage:this.#oe(c),width:r.width})}#ce(){let e=this.#L;e&&(this.#L=null,this.#i.send(`grab`)!==null&&(this.#I={direction:e.direction,targetIndex:e.targetIndex,toPage:e.toPage,toContent:{left:null,right:null},width:e.width,t:0},this.#n.emit(`flipStart`,{from:this.#b,to:e.toPage}),this.#le(e.targetIndex,e.direction)))}async#le(e,t){let n=this.#v[e],r=n?await this.#Re(n):{left:null,right:null};this.#I?.targetIndex===e&&(this.#I.toContent=r,this.#M?.beginFlip(this.#x,r,t,{fill:this.#m,curl:this.#s,anchor:{y:this.#c}}),this.#M?.setFlipProgress(this.#I.t,t))}#ue(e,t){if(this.#U)return;if(this.#H){if(!this.#M)return;let n=this.#M.measure(),[r,i]=this.#te(this.#H.baseTx+e,this.#H.baseTy+t,this.#k,n.containerWidth,n.containerHeight);this.#A=r,this.#j=i,this.#M.setViewTransform(this.#k,r,i);return}this.#L&&Math.hypot(e,t)>X&&this.#ce();let n=this.#I;n&&(n.t=Z((n.direction===`forward`?-e:e)/n.width,0,1),this.#M?.setFlipProgress(n.t,n.direction))}#de(e){if(this.#U)return;if(this.#H){this.#H=null,this.#i.send(`panEnd`);return}let t=this.#I;if(!t){this.#L=null,this.#fe(e);return}this.#I=null,this.#i.send(`release`);let n=e.swipe&&(t.direction===`forward`?e.dx<0:e.dx>0);t.t>=.5||n?this.#ie(t.t,1,t.direction,()=>this.#ae(t.targetIndex,t.toPage,t.toContent)):this.#ie(t.t,0,t.direction,()=>this.#ge())}#fe(e){if(this.#l===`off`||this.#k>1||!this.#R||Math.abs(e.dx)>X||Math.abs(e.dy)>X)return;let t=this.#me(this.#R);if(!t)return;let n=t===`forward`?1:-1;if(this.#y+n<0||this.#y+n>=this.#v.length)return;this.#c=Z(this.#R.y/this.#pe().height,0,1);let r=()=>this.#ne(this.#y+n);if(this.#he(),this.#f<=0){this.#Q(r);return}this.#z=setTimeout(()=>{this.#z=null,this.#Q(r)},this.#f)}#pe(){let e=this.#M.measure();return e.content??e.book??{x:0,y:0,width:e.containerWidth,height:e.containerHeight}}#me(e){if(!this.#M)return null;let t=this.#pe().width,n;if(n=this.#l===`half`?e.x>t/2?`right`:`left`:e.x<=this.#u?`left`:e.x>=t-this.#u?`right`:null,!n)return null;let r=this.#a===`rtl`?`left`:`right`;return n===r?`forward`:`backward`}#he(){this.#z!==null&&(clearTimeout(this.#z),this.#z=null)}#ge(){let e=this.#v[this.#y];e&&this.#Ne(e,this.#x),this.#i.send(`settle`),this.#n.emit(`flipEnd`,{page:this.#b}),this.#ee()}#_e(){if(this.#L=null,this.#he(),this.#I){this.#I=null,this.#i.send(`release`),this.#i.send(`settle`);let e=this.#v[this.#y];e&&this.#Ne(e,this.#x)}else this.#H&&(this.#H=null,this.#i.send(`panEnd`));this.#U=!0,this.#W=this.#k}#ve(e,t,n){if(!this.#U)return;let r=this.#e.getBoundingClientRect();this.setZoom(this.#W*n,{x:e-r.left,y:t-r.top})}#ye(){this.#U=!1}#be(){let e=e=>{if(!this.#w||!this.#C||!(e.ctrlKey||e.metaKey))return;e.preventDefault();let t=this.#e.getBoundingClientRect(),n=Math.exp(-e.deltaY*Ue);this.setZoom(this.#k*n,{x:e.clientX-t.left,y:e.clientY-t.top})};this.#e.addEventListener(`wheel`,e,{passive:!1}),this.#J=()=>this.#e.removeEventListener(`wheel`,e)}#xe(){let e=e=>{let t=this.#T;if(!this.#C||t===null)return;if(this.#k<=1&&this.#l!==`off`&&!this.#d){let t=this.#e.getBoundingClientRect(),n={x:e.clientX-t.left,y:e.clientY-t.top};if(this.#me(n)!==null)return}this.#he(),e.preventDefault();let n=t.find(e=>e>this.#k+1e-6)??t[0]??this.#k,r=this.#e.getBoundingClientRect();this.setZoom(n,{x:e.clientX-r.left,y:e.clientY-r.top})};this.#e.addEventListener(`dblclick`,e),this.#Y=()=>this.#e.removeEventListener(`dblclick`,e)}async#Se(e){let t=Y(e);typeof this.#t.open==`function`&&(await this.#t.open(),this.#He()),this.#t.prefetch([this.#b]);let n=await t,r=await this.#Ce(n);this.#M=r,this.#t.onPageUpdate?.(e=>this.#Fe(e)),this.#je(r.measure().containerWidth);let i=new p({onStart:e=>this.#se(e.x,e.y),onMove:e=>this.#ue(e.dx,e.dy),onEnd:e=>this.#de(e)}),a=new g({onPinchStart:()=>this.#_e(),onPinchMove:e=>this.#ve(e.centerX,e.centerY,e.scale),onPinchEnd:()=>this.#ye()});this.#q=m(this.#e,{pointer:i,pinch:a}),this.#be(),this.#xe(),this.#Te(),this.#X=this.#Ee(),await this.#Me(),this.#Ie(),this.#Be(),this.#Oe(),this.#n.emit(`ready`)}async#Ce(e){try{return await e.mount(this.#e),e.onFatal?.(()=>{this.#we()}),e}catch{e.destroy();let t=await Y(`css`);return await t.mount(this.#e),this.#N=!0,this.#n.emit(`rendererFallback`,{from:`webgl2`,to:`css`}),t}}async#we(){if(this.#N||this.#P)return;this.#N=!0,this.#M?.destroy(),this.#M=null;let e=await Y(`css`);if(this.#P){e.destroy();return}await e.mount(this.#e),this.#M=e,this.#je(e.measure().containerWidth),await this.#Me(),this.#n.emit(`rendererFallback`,{from:`webgl2`,to:`css`})}#Te(){if(typeof matchMedia!=`function`)return;let e=matchMedia(`(prefers-reduced-motion: reduce)`);this.#G=e.matches,e.addEventListener?.(`change`,e=>{this.#G=e.matches})}#Ee(){let e=this.#e,t=e.ownerDocument;if(!t||typeof e.setAttribute!=`function`)return null;e.hasAttribute(`tabindex`)||(e.tabIndex=0),e.setAttribute(`aria-roledescription`,`flipbook`);let n=e=>this.#De(e);e.addEventListener(`keydown`,n);let r=t.createElement(`div`);return r.setAttribute(`aria-live`,`polite`),r.setAttribute(`aria-atomic`,`true`),r.style.cssText=`position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;`,e.appendChild(r),this.#K=r,()=>{e.removeEventListener(`keydown`,n),r.remove(),this.#K=null}}#De(e){let t=this.#a===`rtl`?`ArrowLeft`:`ArrowRight`;switch(e.key){case`ArrowRight`:case`ArrowLeft`:e.key===t?this.flipNext():this.flipPrev(),e.preventDefault();break;case`Home`:this.flipTo(0),e.preventDefault();break;case`End`:this.flipTo(this.#t.pageCount-1),e.preventDefault();break;default:break}}#Oe(){this.#K&&(this.#K.textContent=`Page ${this.#b+1} of ${this.#t.pageCount}`)}#ke(){return this.#G?0:this.#S*(this.#m?Ge:1)}update(){!this.#M||this.#i.state!==`idle`||(this.#je(this.#M.measure().containerWidth),this.#Me())}#Ae(){return this.#h||this.#o===`single`?`single`:this.#o}#je(e){let t=a(e,this.#p);if(t===this.#h)return;this.#h=t;let n=this.#Ae();this.#m=n===`single`,this.#v=i(this.#t.pageCount,{direction:this.#a,mode:n}),this.#y=this.#Ve(this.#b)}async#Me(){let e=this.#v[this.#y];!e||!this.#M||(this.#x=await this.#Re(e),this.#Ne(e,this.#x))}#Ne(e,t){this.#M?.renderSpread(e,t,{fill:this.#m}),this.#Pe()}#Pe(){let e=this.#M?.measure().book;if(!e||e.width<=0||e.height<=0)return;let t=(e.width/e.height).toFixed(4);t!==this.#g&&(this.#g=t,this.#e.style.aspectRatio=t)}#Fe(e){if(this.#i.state!==`idle`)return;let t=this.#v[this.#y];t&&(t.left===e||t.right===e)&&this.#Me()}#Ie(){typeof ResizeObserver>`u`||(this.#D=new ResizeObserver(()=>this.#Le()),this.#D.observe(this.#e))}#Le(){this.#O||(this.#O=!0,requestAnimationFrame(()=>{this.#O=!1,this.update()}))}async#Re(e){let[t,n]=await Promise.all([this.#ze(e.left),this.#ze(e.right)]);return{left:t,right:n}}async#ze(e){if(e===null)return null;try{return await this.#t.get(e)}catch(t){return this.#n.emit(`sourceError`,{index:e,error:t}),null}}#Be(){let{toMount:e}=this.#r.update(this.#y,this.#v.length),t=[];for(let n of e){let e=this.#v[n];e?.left!=null&&t.push(e.left),e?.right!=null&&t.push(e.right)}this.#t.prefetch(t)}#Ve(e){let t=this.#v.findIndex(t=>t.left===e||t.right===e);return t===-1?0:t}#He(){let e=this.#t.pageCount;if(!Number.isInteger(e)||e<1)throw Error(`Zine: source has ${e} pages; a Source must have at least 1 page.`);let t=this.#_;if(t!==void 0&&(!Number.isInteger(t)||t<0||t>=e))throw Error(`Zine: startPage ${JSON.stringify(t)} is out of range for a ${e}-page book (valid 0..${e-1}).`);let n=this.#Ae();this.#m=n===`single`,this.#v=i(e,{direction:this.#a,mode:n}),this.#b=Z(t??0,0,e-1),this.#y=this.#Ve(this.#b)}};function Z(e,t,n){return e<t?t:e>n?n:e}function Q(e){return e<.5?2*e*e:1-(-2*e+2)**2/2}function qe(e){return 1-(1-Q(e))**1.3}function Je(e){return e===null?`null`:Array.isArray(e)?`array`:typeof e}function Ye(e,t){if(typeof e!=`object`||!e||typeof e.appendChild!=`function`||typeof e.addEventListener!=`function`)throw Error(`Zine: container must be a DOM element; received ${Je(e)}.`);if(typeof t!=`object`||!t)throw Error("Zine: an options object with a `source` is required.");let n=t,r=n.source;if(typeof r!=`object`||!r||typeof r.get!=`function`||typeof r.pageCount!=`number`)throw Error("Zine: `source` is required and must be a Source, e.g. new ImageSource(urls).");let i=n.startPage;if(i!==void 0&&(typeof i!=`number`||!Number.isInteger(i)||i<0))throw Error(`Zine: startPage must be a non-negative integer; got ${JSON.stringify(i)}.`);let a=n.direction;if(a!==void 0&&a!==`ltr`&&a!==`rtl`)throw Error(`Zine: direction must be 'ltr' or 'rtl'; got ${JSON.stringify(a)}.`);let o=n.clickToFlip;if(o!==void 0&&![`edge`,`half`,`off`].includes(o))throw Error(`Zine: clickToFlip must be 'edge', 'half', or 'off'; got ${JSON.stringify(o)}.`);let s=n.curl;if(s!==void 0&&!v.includes(s))throw Error(`Zine: curl must be one of ${v.join(`, `)}; got ${JSON.stringify(s)}.`);let c=n.spreadMode;if(c!==void 0&&![`double`,`single`,`cover`,`book`].includes(c))throw Error(`Zine: spreadMode must be 'double', 'single', 'cover', or 'book'; got ${JSON.stringify(c)}.`);for(let e of[`frontCover`,`backCover`]){let t=n[e];if(t!==void 0&&typeof t!=`string`)throw Error(`Zine: ${e} must be an image URL string; got ${JSON.stringify(t)}.`)}let l=n.pages;if(l!==void 0&&(typeof l!=`object`||!l||Array.isArray(l)))throw Error(`Zine: pages must be an object mapping page indices to image URLs.`);$(n.width,`width`,1),$(n.height,`height`,1),$(n.flipDuration,`flipDuration`,0),$(n.clickZoneSize,`clickZoneSize`,0),$(n.clickFlipDelay,`clickFlipDelay`,0),$(n.singlePageThreshold,`singlePageThreshold`,0),Xe(n.zoom),Ze(n.renderer)}function $(e,t,n){if(e!==void 0&&(typeof e!=`number`||!Number.isFinite(e)||e<n))throw Error(`Zine: ${t} must be a number >= ${n}; got ${JSON.stringify(e)}.`)}function Xe(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Zine: zoom must be an object, e.g. { max: 4 }.`);let t=e;if(t.enabled!==void 0&&typeof t.enabled!=`boolean`)throw Error(`Zine: zoom.enabled must be a boolean; got ${JSON.stringify(t.enabled)}.`);if(t.wheel!==void 0&&typeof t.wheel!=`boolean`)throw Error(`Zine: zoom.wheel must be a boolean; got ${JSON.stringify(t.wheel)}.`);if(t.doubleClickInFlipZone!==void 0&&typeof t.doubleClickInFlipZone!=`boolean`)throw Error(`Zine: zoom.doubleClickInFlipZone must be a boolean; got ${JSON.stringify(t.doubleClickInFlipZone)}.`);if(t.doubleClick!==void 0&&t.doubleClick!==!1){let e=t.doubleClick;if(!Array.isArray(e)||e.some(e=>typeof e!=`number`||!Number.isFinite(e)||e<1))throw Error(`Zine: zoom.doubleClick must be false or an array of zoom levels >= 1, e.g. [1, 2, 4].`)}$(t.max,`zoom.max`,1)}function Ze(e){if(e!==void 0){if(typeof e==`string`){if(e!==`auto`&&e!==`css`&&e!==`webgl2`)throw Error(`Zine: renderer '${e}' is not recognized; use 'auto', 'css', 'webgl2', an array of those, or a custom Renderer.`);return}if(Array.isArray(e)){for(let t of e)if(t!==`css`&&t!==`webgl2`)throw Error(`Zine: renderer order array may only contain 'css' or 'webgl2'; got ${JSON.stringify(t)}.`);return}if(!(typeof e==`object`&&e&&typeof e.mount==`function`))throw Error(`Zine: renderer must be 'auto', 'css', 'webgl2', an array of those, or a custom Renderer instance.`)}}var Qe=class{pageCount;fit;#e;#t;#n=new Map;constructor(e,t={}){this.#e=e,this.pageCount=e.length,this.#t=t.preload??1,this.fit=t.fit??`contain`}get(e){let t=this.#r(e);for(let t=1;t<=this.#t;t++)this.prefetch([e-t,e+t]);return t}prefetch(e){for(let t of e)t>=0&&t<this.pageCount&&this.#r(t).catch(()=>{})}destroy(){for(let e of this.#n.values())e.then(e=>e.close()).catch(()=>{});this.#n.clear()}#r(e){let t=this.#n.get(e);if(t)return t;let n=this.#e[e];if(n===void 0)return Promise.reject(RangeError(`ImageSource: page ${e} is out of range (0..${this.pageCount-1}).`));let r=(async()=>{let t=await fetch(n);if(!t.ok)throw Error(`ImageSource: failed to fetch page ${e} (${n}) — HTTP ${t.status}.`);return createImageBitmap(await t.blob())})().catch(t=>{throw this.#n.delete(e),t});return this.#n.set(e,r),r}};b(),e.CURL_TYPES=v,e.ImageSource=Qe,e.Zine=Ke});
104
91
  //# sourceMappingURL=index.umd.cjs.map