/*!
 * Nutrient Web SDK 1.9.1 (https://www.nutrient.io/sdk/web)
 *
 * Copyright (c) 2016-2025 PSPDFKit GmbH. All rights reserved.
 *
 * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
 * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.
 * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
 * This notice may not be removed from this file.
 *
 * PSPDFKit uses several open source third-party components: https://www.nutrient.io/legal/acknowledgements/web-acknowledgements/
 */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.NutrientViewer=t():e.NutrientViewer=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function s(e){var t=function(e,t){if("object"!=i(e)||!e)return e;var s=e[Symbol.toPrimitive];if(void 0!==s){var r=s.call(e,t||"default");if("object"!=i(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==i(t)?t:t+""}function r(e,t,i){return(t=s(t))in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}e.r(t),e.d(t,{default:()=>L});const n=Symbol("Comlink.proxy"),o=Symbol("Comlink.endpoint"),a=Symbol("Comlink.releaseProxy"),h=Symbol("Comlink.finalizer"),l=Symbol("Comlink.thrown"),c=e=>"object"==typeof e&&null!==e||"function"==typeof e,d=new Map([["proxy",{canHandle:e=>c(e)&&e[n],serialize(e){const{port1:t,port2:i}=new MessageChannel;return u(e,t),[i,[i]]},deserialize:e=>(e.start(),f(e))}],["throw",{canHandle:e=>c(e)&&l in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function u(e,t=globalThis,i=["*"]){t.addEventListener("message",(function s(r){if(!r||!r.data)return;if(!function(e,t){for(const i of e){if(t===i||"*"===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}return!1}(i,r.origin))return void console.warn(`Invalid origin '${r.origin}' for comlink proxy`);const{id:o,type:a,path:c}=Object.assign({path:[]},r.data),d=(r.data.argumentList||[]).map(M);let f;try{const t=c.slice(0,-1).reduce(((e,t)=>e[t]),e),i=c.reduce(((e,t)=>e[t]),e);switch(a){case"GET":f=i;break;case"SET":t[c.slice(-1)[0]]=M(r.data.value),f=!0;break;case"APPLY":f=i.apply(t,d);break;case"CONSTRUCT":f=function(e){return Object.assign(e,{[n]:!0})}(new i(...d));break;case"ENDPOINT":{const{port1:t,port2:i}=new MessageChannel;u(e,i),f=function(e,t){return T.set(e,t),e}(t,[t])}break;case"RELEASE":f=void 0;break;default:return}}catch(e){f={value:e,[l]:0}}Promise.resolve(f).catch((e=>({value:e,[l]:0}))).then((i=>{const[r,n]=x(i);t.postMessage(Object.assign(Object.assign({},r),{id:o}),n),"RELEASE"===a&&(t.removeEventListener("message",s),p(t),h in e&&"function"==typeof e[h]&&e[h]())})).catch((e=>{const[i,s]=x({value:new TypeError("Unserializable return value"),[l]:0});t.postMessage(Object.assign(Object.assign({},i),{id:o}),s)}))})),t.start&&t.start()}function p(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function f(e,t){const i=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=i.get(t.id);if(s)try{s(t)}finally{i.delete(t.id)}})),y(e,i,[],t)}function g(e){if(e)throw new Error("Proxy has been released and is not useable")}function m(e){return $(e,new Map,{type:"RELEASE"}).then((()=>{p(e)}))}const w=new WeakMap,v="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=(w.get(e)||0)-1;w.set(e,t),0===t&&m(e)}));function y(e,t,i=[],s=function(){}){let r=!1;const n=new Proxy(s,{get(s,o){if(g(r),o===a)return()=>{!function(e){v&&v.unregister(e)}(n),m(e),t.clear(),r=!0};if("then"===o){if(0===i.length)return{then:()=>n};const s=$(e,t,{type:"GET",path:i.map((e=>e.toString()))}).then(M);return s.then.bind(s)}return y(e,t,[...i,o])},set(s,n,o){g(r);const[a,h]=x(o);return $(e,t,{type:"SET",path:[...i,n].map((e=>e.toString())),value:a},h).then(M)},apply(s,n,a){g(r);const h=i[i.length-1];if(h===o)return $(e,t,{type:"ENDPOINT"}).then(M);if("bind"===h)return y(e,t,i.slice(0,-1));const[l,c]=b(a);return $(e,t,{type:"APPLY",path:i.map((e=>e.toString())),argumentList:l},c).then(M)},construct(s,n){g(r);const[o,a]=b(n);return $(e,t,{type:"CONSTRUCT",path:i.map((e=>e.toString())),argumentList:o},a).then(M)}});return function(e,t){const i=(w.get(t)||0)+1;w.set(t,i),v&&v.register(e,t,e)}(n,e),n}function b(e){const t=e.map(x);return[t.map((e=>e[0])),(i=t.map((e=>e[1])),Array.prototype.concat.apply([],i))];var i}const T=new WeakMap;function x(e){for(const[t,i]of d)if(i.canHandle(e)){const[s,r]=i.serialize(e);return[{type:"HANDLER",name:t,value:s},r]}return[{type:"RAW",value:e},T.get(e)||[]]}function M(e){switch(e.type){case"HANDLER":return d.get(e.name).deserialize(e.value);case"RAW":return e.value}}function $(e,t,i,s){return new Promise((r=>{const n=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(n,r),e.start&&e.start(),e.postMessage(Object.assign({id:n},i),s)}))}class C{constructor(e){r(this,"queue",[]),r(this,"activeRequests",new Map),r(this,"isProcessing",!1),r(this,"renderCallbacks",new Map),r(this,"errorCallbacks",new Map),r(this,"maxConcurrentRequests",1),r(this,"activeRequestCount",0),this.renderChannel=e}setCallbacks(e,t,i){this.renderCallbacks.set(e,t),this.errorCallbacks.set(e,i)}enqueue(e,t){const i=Date.now();for(const s of t){if(this.activeRequests.has(s.id))continue;const t=this.queue.findIndex((e=>e.request.id===s.id));-1===t?this.queue.push({request:s,sessionId:e,priority:this.calculatePriority(s),timestamp:i,cancelled:!1}):this.queue[t].priority=this.calculatePriority(s)}this.sortQueue(),this.isProcessing||this.startProcessing()}cancel(e,t){const i=new Set(t);for(const t of this.queue)t.sessionId===e&&i.has(t.request.id)&&(t.cancelled=!0);for(const[t,s]of this.activeRequests)s.sessionId===e&&i.has(t)&&(s.cancelled=!0)}cancelSession(e){for(const t of this.queue)t.sessionId===e&&(t.cancelled=!0);for(const t of this.activeRequests.values())t.sessionId===e&&(t.cancelled=!0)}async startProcessing(){if(!this.isProcessing){for(this.isProcessing=!0;this.queue.length>0||this.activeRequestCount>0;){for(;this.activeRequestCount<this.maxConcurrentRequests&&this.queue.length>0;){const e=this.getNextRequest();if(!e)break;this.activeRequestCount++,this.processRequest(e).finally((()=>{this.activeRequestCount--}))}await new Promise((e=>setTimeout(e,0)))}this.isProcessing=!1}}getNextRequest(){for(;this.queue.length>0;){const e=this.queue.shift();if(!e)break;if(!e.cancelled)return this.activeRequests.set(e.request.id,e),e}return null}async processRequest(e){const{request:t,sessionId:i}=e;try{if(e.cancelled)return;"undefined"!=typeof performance&&performance.mark&&performance.mark(`tile-render-start-${t.id}`);const s=await this.renderTile(t);if("undefined"!=typeof performance&&performance.mark&&(performance.mark(`tile-render-ready-${t.id}`),performance.measure))try{performance.measure(`tile-wasm-render-${t.id}`,`tile-render-start-${t.id}`,`tile-render-ready-${t.id}`)}catch(e){}if(e.cancelled)return;const r=this.renderCallbacks.get(i);r&&r(i,t.id,s)}catch(s){if(console.error("[SharedRenderQueue] Error processing request:",s),!e.cancelled){const e=this.errorCallbacks.get(i);e&&e(i,t.id,s)}}finally{this.activeRequests.delete(t.id)}}async renderTile(e){const{sourceInfo:t,options:i}=e,s=await this.renderChannel.render(t.pageIndex,t.pageSize,t.tileRect,{renderForPrinting:i.renderForPrinting,renderText:i.renderText,priority:i.priority||"high"});return{buffer:s,format:i.format||"bitmap",width:s.width,height:s.height}}calculatePriority(e){let t=0;"high"===e.options.priority&&(t-=1e3),e.targetInfo.isVisible&&(t-=500),t-=10*e.viewportRenderUpdateId;return t+=100*Math.abs(e.targetInfo.scale-e.targetInfo.targetScale),t}sortQueue(){this.queue.sort(((e,t)=>e.priority-t.priority))}}const R=function e(t){let i;return i=t instanceof Error?t:new Error(t),Object.setPrototypeOf(i,e.prototype),i};R.prototype=Object.create(Error.prototype,{name:{value:"PSPDFKitError",enumerable:!1}});const S=R;["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","iframe","object","embed","[contenteditable]",'[tabindex]:not([tabindex^="-"])'].join(",");new WeakMap;const I=!1;function E(){I}function P(e,t){if(null===t)return!0;const i=e===t;return i||E("skipping render of outdated viewportUpdateId",e,"latest is",t),i}function z(e,t){return e.left<t.width&&e.left+e.width>0&&e.top<t.height&&e.top+e.height>0}class k{constructor(e,t,i,s,n,o,a){r(this,"viewport",null),r(this,"mipLevels",[]),r(this,"pendingTiles",new Map),r(this,"totalTilesForCurrentRender",0),r(this,"completedTilesForCurrentRender",0),r(this,"latestViewportUpdateId",0),r(this,"showTileBorders",I),r(this,"drawCallCounter",0),r(this,"scrollEventCounter",0),this.canvas=e,this.sessionId=t,this.sharedQueue=i,this.TILE_SIZE=n;const h=e.getContext("2d");!function(e,t){if(!e)throw new S(`Assertion failed: ${t||"Condition not met"}\n\nFor further assistance, please go to: https://www.nutrient.io/support/request`)}(h,"OffscreenCanvasRenderingContext2D not available"),this.ctx=h,this.pageIndex=o,this.pageSize=a,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.tileCache=s,i.setCallbacks(t,this.handleTileReady.bind(this),this.handleTileError.bind(this))}updateViewport(e){const t=this.viewport;if(this.viewport=e,this.latestViewportUpdateId++,this.cancelStaleRequests(this.latestViewportUpdateId),t?.devicePixelRatio!==e.devicePixelRatio&&(this.mipLevels=function(e,t){const i=e*t,s=[];s.push(.5),s.push(1);let r=2;for(;r<=i;)s.push(r),r*=2;return!s.includes(i)&&i>s[s.length-1]&&s.push(i),s}(e.maxZoomLevel,e.devicePixelRatio)),t){const i=t.zoomLevel!==e.zoomLevel,s=t.viewportWidth!==e.viewportWidth||t.viewportHeight!==e.viewportHeight,r=t.scrollX!==e.scrollX||t.scrollY!==e.scrollY;this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),i||s?this.handleResize(this.latestViewportUpdateId):r&&this.handleScroll(e.scrollX-t.scrollX,e.scrollY-t.scrollY,this.latestViewportUpdateId)}else this.handleResize(this.latestViewportUpdateId)}cancelStaleRequests(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2;if(0===this.pendingTiles.size)return;const i=[];for(const[s,r]of this.pendingTiles){e-r.latestNeededViewportId>t&&i.push(s)}if(i.length>0){this.sharedQueue.cancel(this.sessionId,i);for(const e of i)this.pendingTiles.delete(e);E(`Cancelled ${i.length} stale requests (age > ${t})`)}}handleScroll(e,t,i){this.viewport&&(this.scrollEventCounter++,E(`SCROLL #${this.scrollEventCounter}: delta(${e.toFixed(1)}, ${t.toFixed(1)}) scroll:(${this.viewport.scrollX.toFixed(1)}, ${this.viewport.scrollY.toFixed(1)}) canvas:${this.canvas.width}x${this.canvas.height}`),this.drawOptimized(i))}handleResize(e){if(!this.viewport)return;const t=(e,t)=>Math.round(e*Math.pow(10,t))/Math.pow(10,t),{viewportWidth:i,viewportHeight:s,zoomLevel:r,devicePixelRatio:n}=this.viewport,o=Math.ceil(i*r*n),a=Math.ceil(s*r*n);this.canvas.width===o&&this.canvas.height===a||(this.canvas.width=t(o,4),this.canvas.height=t(a,4)),this.drawOptimized(e)}drawOptimized(e){const t=this.calculateVisibleTiles(),i=new Set;this.drawCallCounter=0,E("-- drawOptimized --"),E("--- paintCachedTiles() ---"),this.paintCachedTiles(t,i,e),E("--- renderExposedAreas() ---"),this.renderExposedAreas(t,i,e),E(`--- draw complete: ${this.drawCallCounter} tiles drawn ---`)}paintCachedTiles(e,t,i){if(this.viewport)for(const s of e){const e=`${s.col},${s.row},${s.mip}`;if(t.has(e))continue;if(!z(this.getTileCanvasRect(s),this.canvas))continue;let r=this.tileCache.get(this.pageIndex,s.mip,s.col,s.row,0,s.tileSize);if(r)this.drawCachedTile(r,s,i),t.add(e);else{const e=s.rect;let n=!1;for(const o of this.mipLevels){if(o===s.mip)continue;const a=this.TILE_SIZE/o,h=Math.floor(e.left/a),l=Math.ceil((e.left+e.width)/a),c=Math.floor(e.top/a),d=Math.ceil((e.top+e.height)/a);for(let e=c;e<d;e++)for(let c=h;c<l;c++)if(r=this.tileCache.get(this.pageIndex,o,c,e,0,Math.round(a)),r){const h=`${c},${e},${o}`;if(!t.has(h)){z(this.getFallbackTileCanvasRect(c,e,a),this.canvas)&&(this.drawCachedTileWithClipping(r,c,e,o,a,s,i),t.add(h),n=!0)}}if(n)break}}}}renderExposedAreas(e,t,i){if(!this.viewport)return;const s=e.filter((e=>{const i=`${e.col},${e.row},${e.mip}`;if(t.has(i))return!1;return z(this.getTileCanvasRect(e),this.canvas)}));s.length>0&&this.requestTiles(s,i)}calculateVisibleTiles(){if(!this.viewport)return[];const{scrollX:e,scrollY:t,zoomLevel:i,viewportWidth:s,viewportHeight:r,devicePixelRatio:n}=this.viewport,o=function(e,t){for(const i of t)if(i>=e)return i;return t[t.length-1]||e}(i*n,this.mipLevels),a=this.TILE_SIZE/o,h=Math.min(.25*Math.min(s,r),a),l=Math.max(0,e-h),c=Math.max(0,t-h),d=Math.min(e+s+h,this.pageSize.width),u=Math.min(t+r+h,this.pageSize.height),p=Math.floor(l/a),f=Math.ceil(d/a),g=Math.floor(c/a),m=Math.ceil(u/a);E(`Tile grid: ${f-p}x${m-g} = ${(f-p)*(m-g)} tiles (gutter: ${h.toFixed(1)} page units)`);const w=[];for(let e=g;e<m;e++)for(let t=p;t<f;t++){const i=t*a,s=e*a;w.push({col:t,row:e,rect:{left:i,top:s,width:Math.min(a,this.pageSize.width-i),height:Math.min(a,this.pageSize.height-s)},mip:o,tileSize:Math.round(a)})}return w}drawImageBitmap(e,t,i,s,r,n){P(n,this.latestViewportUpdateId)&&(this.drawCallCounter++,this.ctx.drawImage(e,t,i,s,r))}getTileCanvasRect(e){if(!this.viewport)return{left:0,top:0,width:0,height:0};const{scrollX:t,scrollY:i,zoomLevel:s,devicePixelRatio:r}=this.viewport;return{left:(e.rect.left-t)*s*r,top:(e.rect.top-i)*s*r,width:e.rect.width*s*r,height:e.rect.height*s*r}}getFallbackTileCanvasRect(e,t,i){if(!this.viewport)return{left:0,top:0,width:0,height:0};const{scrollX:s,scrollY:r,zoomLevel:n,devicePixelRatio:o}=this.viewport;return{left:(e*i-s)*n*o,top:(t*i-r)*n*o,width:i*n*o,height:i*n*o}}requestTiles(e,t){if(!this.viewport)return;const i=[];for(const s of e){const e=this.generateTileCacheKey(this.pageIndex,s.mip,s.col,s.row,0,s.tileSize);if(this.pendingTiles.has(e)){const i=this.pendingTiles.get(e);i&&(i.latestNeededViewportId=Math.max(i.latestNeededViewportId,t));continue}const r=this.getTileCanvasRect(s),n=r.left<this.canvas.width&&r.left+r.width>0&&r.top<this.canvas.height&&r.top+r.height>0;this.pendingTiles.set(e,{tile:s,latestNeededViewportId:t}),i.push({id:e,viewportRenderUpdateId:t,sourceInfo:{pageIndex:this.pageIndex,pageSize:{width:Math.ceil(this.pageSize.width*s.mip),height:Math.ceil(this.pageSize.height*s.mip)},tileRect:{left:Math.floor(s.rect.left*s.mip),top:Math.floor(s.rect.top*s.mip),width:Math.ceil(s.rect.width*s.mip),height:Math.ceil(s.rect.height*s.mip)}},targetInfo:{scale:s.mip,targetScale:this.viewport.zoomLevel*this.viewport.devicePixelRatio,isVisible:!0,canvasRect:r},options:{renderAnnotations:!0,renderText:!0,format:"bitmap",priority:n?"high":"normal"}})}i.length>0?(this.totalTilesForCurrentRender=this.pendingTiles.size,this.completedTilesForCurrentRender=0,E(`REQUESTING ${i.length} new tiles from backend`),this.sharedQueue.enqueue(this.sessionId,i)):E("No new tiles to request - all visible tiles are cached")}generateTileCacheKey(e,t,i,s,r,n){return`${e}_${t}_${i}_${s}_${r}_${n}`}drawCachedTileWithClipping(e,t,i,s,r,n,o){if(!this.viewport)return;const{scrollX:a,scrollY:h,zoomLevel:l,devicePixelRatio:c}=this.viewport,d=(t*r-a)*l*c,u=(i*r-h)*l*c,p=l*c/s,f=e.width*p,g=e.height*p,m={left:d,top:u,width:f,height:g};z(m,this.canvas)?(E(`DRAW: clipped cached tile[${t},${i}] size:(${Math.round(e.width||-1)}x${Math.round(e.height||-1)}) at canvasPos:(${Math.round(d)},${Math.round(u)}) canvasRect:${JSON.stringify(m)} mip:${s}`),this.drawImageBitmap(e.imageData,d,u,f,g,o),this.showTileBorders&&this.drawTileBorder(n,m,o,"#00f")):E(`SKIP DRAW: cached tile[${t},${i}] at canvasPos:(${Math.round(d)},${Math.round(u)})`)}drawCachedTile(e,t,i){if(!this.viewport)return;const s=this.getTileCanvasRect(t),r=z(s,this.canvas);r?(E(`Draw #${this.drawCallCounter}: tile[${t.col},${t.row}] mip:${t.mip.toFixed(1)} visible:${r} canvasPos:(${Math.round(s.left)},${Math.round(s.top)}) size:${Math.round(s.width)}x${Math.round(s.height)}`),this.drawImageBitmap(e.imageData,s.left,s.top,s.width,s.height,i),this.showTileBorders&&this.drawTileBorder(t,s,i)):E(`SKIP DRAW: invisible tile[${t.col},${t.row}] at canvasPos:(${Math.round(s.left)},${Math.round(s.top)})`)}handleTileReady(e,t,i){if(e!==this.sessionId)return;const s=this.pendingTiles.get(t);if(!s||!this.viewport)return;const{tile:r,latestNeededViewportId:n}=s;this.pendingTiles.delete(t),this.tileCache.put(this.pageIndex,r.mip,r.col,r.row,i.buffer,i.format,0,r.tileSize,i.width,i.height),this.drawTile(i,r,n),this.completedTilesForCurrentRender++}drawTile(e,t,i){if(!this.viewport)return;if(!P(i,this.latestViewportUpdateId))return;const s=this.getTileCanvasRect(t),r=z(s,this.canvas);this.drawCallCounter++,E(`NEW TILE: tile[${t.col},${t.row}] mip:${t.mip.toFixed(1)} visible:${r} canvasPos:(${Math.round(s.left)},${Math.round(s.top)}) size:${Math.round(s.width)}x${Math.round(s.height)}`),"bitmap"===e.format&&(this.ctx.drawImage(e.buffer,s.left,s.top,s.width,s.height),this.showTileBorders&&this.drawTileBorder(t,s,i))}drawTileBorder(e,t,i){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"#0f0";this.ctx.save(),this.ctx.strokeStyle=s,this.ctx.lineWidth=2,this.ctx.setLineDash([5,5]),this.ctx.strokeRect(t.left,t.top,t.width,t.height),this.ctx.fillStyle="rgba(0, 0, 0, 0.8)",this.ctx.fillRect(t.left,t.top,280,75),this.ctx.fillStyle=s,this.ctx.font="bold 15px monospace",this.ctx.fillText(`Tile ${i}: ${e.col},${e.row}`,t.left+5,t.top+15),this.ctx.fillText(`MIP: ${e.mip.toFixed(1)}`,t.left+5,t.top+30),this.ctx.fillText(`Canvas: ${Math.round(t.width)}×${Math.round(t.height)}px`,t.left+5,t.top+45);const r=Math.ceil(e.rect.width*e.mip),n=Math.ceil(e.rect.height*e.mip);this.ctx.fillText(`Bitmap: ${r}×${n}px`,t.left+5,t.top+60),this.ctx.restore()}handleTileError(e,t,i){e===this.sessionId&&(this.pendingTiles.delete(t),console.warn("Tile render failed:",t,i))}dispose(){this.sharedQueue.cancelSession(this.sessionId),this.pendingTiles.clear(),this.tileCache.clear()}}class q{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:256;r(this,"cache",new Map),r(this,"hotQueue",new Set),r(this,"coldQueue",new Set),r(this,"pinnedTiles",new Set),r(this,"currentBytes",0),r(this,"hits",0),r(this,"misses",0),this.maxBytes=1024*e*1024}generateKey(e,t,i,s){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,n=arguments.length>5?arguments[5]:void 0;const o=Math.floor(i),a=Math.floor(s),h=Math.round(1e3*t)/1e3,l=Math.round(n);return 0!==r?`${e}/mip${h}/x${o}y${a}/rot${r}/ts${l}`:`${e}/mip${h}/x${o}y${a}/ts${l}`}get(e,t,i,s){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,n=arguments.length>5?arguments[5]:void 0;const o=this.generateKey(e,t,i,s,r,n),a=this.cache.get(o);return a?(this.hits++,a.lastAccessTime=Date.now(),a.accessCount++,this.coldQueue.has(o)&&a.accessCount>2&&(this.coldQueue.delete(o),this.hotQueue.add(o)),a):(this.misses++,null)}getCachedMipsForTile(e,t,i){let s=arguments.length>4?arguments[4]:void 0;const r=[];return this.cache.forEach((n=>{n.pageIndex===e&&n.tileX===t&&n.tileY===i&&Math.abs(n.tileSize-s)<1&&r.push(n.mip)})),r.sort(((e,t)=>e-t))}put(e,t,i,s,r){let n=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"bitmap",o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:0,a=arguments.length>7?arguments[7]:void 0,h=arguments.length>8?arguments[8]:void 0,l=arguments.length>9?arguments[9]:void 0;const c=this.generateKey(e,t,i,s,o,a),d=this.calculateTileMemorySize(h,l,n);this.ensureMemoryBudget(d);const u={key:c,pageIndex:e,mip:t,tileX:i,tileY:s,tileSize:a,imageData:r,format:n,width:h,height:l,byteSize:d,lastAccessTime:Date.now(),createdTime:Date.now(),accessCount:1,isPinned:!1},p=this.cache.get(c);p&&(this.currentBytes-=p.byteSize,this.hotQueue.delete(c),this.coldQueue.delete(c)),this.cache.set(c,u),this.hotQueue.add(c),this.currentBytes+=d}pin(e,t,i,s){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,n=arguments.length>5?arguments[5]:void 0;const o=this.generateKey(e,t,i,s,r,n),a=this.cache.get(o);a&&(this.pinnedTiles.add(o),a.isPinned=!0)}clearPage(e){const t=[];this.cache.forEach(((i,s)=>{i.pageIndex!==e||i.isPinned||t.push(s)})),t.forEach((e=>{this.removeTile(e)}))}clear(){const e=[];this.cache.forEach(((t,i)=>{t.isPinned||e.push(i)})),e.forEach((e=>{this.removeTile(e)}))}getStats(){const e=this.hits+this.misses>0?this.hits/(this.hits+this.misses):0;return{totalTiles:this.cache.size,totalBytes:this.currentBytes,hotTiles:this.hotQueue.size,coldTiles:this.coldQueue.size,pinnedTiles:this.pinnedTiles.size,hitRate:e}}ensureMemoryBudget(e){if(this.currentBytes+e<=this.maxBytes)return;const t=this.currentBytes+e-this.maxBytes;let i=0;const s=Date.now(),r=Array.from(this.hotQueue);for(const e of r){const t=this.cache.get(e);t&&!t.isPinned&&s-t.lastAccessTime>5e3&&(this.hotQueue.delete(e),this.coldQueue.add(e))}const n=Array.from(this.coldQueue).map((e=>({key:e,tile:this.cache.get(e)}))).filter((e=>e.tile&&!e.tile.isPinned)).sort(((e,t)=>(e.tile?.lastAccessTime??0)-(t.tile?.lastAccessTime??0)));for(const{key:e,tile:s}of n){if(i>=t||!s)break;i+=s.byteSize,this.removeTile(e)}if(i<t){const e=Array.from(this.hotQueue).map((e=>({key:e,tile:this.cache.get(e)}))).filter((e=>e.tile&&!e.tile.isPinned)).sort(((e,t)=>(e.tile?.lastAccessTime??0)-(t.tile?.lastAccessTime??0)));for(const{key:s,tile:r}of e){if(i>=t||!r)break;i+=r.byteSize,this.removeTile(s)}}}removeTile(e){const t=this.cache.get(e);t&&(t.imageData.close(),this.cache.delete(e),this.hotQueue.delete(e),this.coldQueue.delete(e),this.pinnedTiles.delete(e),this.currentBytes-=t.byteSize)}calculateTileMemorySize(e,t){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"bitmap";if("bitmap"===i)return e*t*4;const s=e*t;return"jpeg"===i?Math.ceil(4*s*.15):Math.ceil(4*s*.4)}}class L{constructor(){r(this,"offscreenRendererMap",new Map),r(this,"canvasSessionIdCounter",0),r(this,"sharedRenderQueue",null),r(this,"tileCache",new q(256)),r(this,"renderChannel",null)}async setupRenderMessageChannel(e){this.renderChannel=f(e)}async releaseRenderer(e){const t=this.offscreenRendererMap.get(e);t&&(t.dispose(),this.offscreenRendererMap.delete(e))}async beginRenderer(e,t,i,s){!function(e,t){if(!e)throw new S(`Assertion failed: ${t||"Condition not met"}\n\nFor further assistance, please go to: https://www.nutrient.io/support/request`)}(this.renderChannel,"Setup render channel first"),this.sharedRenderQueue||(this.sharedRenderQueue=new C(this.renderChannel));const r=`page-${t}-${this.canvasSessionIdCounter++}`,n=new k(e,r,this.sharedRenderQueue,this.tileCache,i,t,s);return this.offscreenRendererMap.set(r,n),r}async updateViewport(e,t){const i=this.offscreenRendererMap.get(e);i?i.updateViewport(t):console.warn(`No renderer found for session ${e}`)}async endRenderer(e){const t=this.offscreenRendererMap.get(e);t?(t.dispose(),this.offscreenRendererMap.delete(e)):console.warn(`No renderer found for session ${e}`)}}return u(new L),t})()));