AWSTemplateFormatVersion: 2010-09-09 Description: Serve Z/X/Y tiles through CloudFront + Lambda from an existing S3 bucket. Parameters: BucketName: Description: >- Name of an existing S3 bucket with .pmtiles tilesets. Should be in the same region as your CloudFormation stack. Can be a RequesterPays bucket in another account. Type: String MinLength: 1 DefaultTTL: Description: Default time-to-live for cached tiles in the CloudFront distribution. Type: Number Default: 86400 AllowedOrigins: Description: >- Comma-separated list of domains (e.g. example.com) allowed by browser CORS policy, or * for all origins. Type: List Default: '*' PublicHostname: Description: >- Optional. Replace *.cloudfront.net in TileJSON with a custom hostname (e.g. example.com). See docs on how this value is cached. Type: String Outputs: CloudFrontDistributionUrl: Description: URL of the CloudFront distribution for cached tiles. Value: !Sub https://${CloudFrontDistribution.DomainName} Export: Name: !Sub ${AWS::StackName}-CloudFrontDistributionURL Conditions: IsPublicHostnameProvided: !Not - !Equals - !Ref PublicHostname - '' Resources: LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/lambda/${AWS::StackName} RetentionInDays: 7 LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: !Sub ${AWS::StackName}-LambdaLoggingPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub >- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}:log-stream:* - PolicyName: !Sub ${AWS::StackName}-LambdaS3AccessPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: s3:GetObject Resource: !Sub arn:aws:s3:::${BucketName}/* LambdaFunctionUrl: Type: AWS::Lambda::Url Properties: AuthType: NONE TargetFunctionArn: !GetAtt LambdaFunction.Arn InvokeMode: BUFFERED LambdaFunctionUrlPermissionInvokeUrl: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunctionUrl FunctionName: !Ref LambdaFunction Principal: '*' FunctionUrlAuthType: NONE LambdaFunctionUrlPermissionInvokeFunction: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref LambdaFunction Principal: '*' ViewerRequestCloudFrontFunction: Type: AWS::CloudFront::Function Properties: Name: !Sub ${AWS::StackName}-ViewerRequestCloudFrontFunction AutoPublish: true FunctionCode: | function handler(event) { const request = event.request; request.headers['x-distribution-domain-name'] = { value: event.context.distributionDomainName }; return request; } FunctionConfig: Comment: Add x-distribution-domain header. Runtime: cloudfront-js-2.0 CloudFrontDistribution: Type: AWS::CloudFront::Distribution DeletionPolicy: Delete Properties: DistributionConfig: Origins: - Id: LambdaOrigin DomainName: !Select - 2 - !Split - / - !GetAtt LambdaFunctionUrl.FunctionUrl CustomOriginConfig: OriginProtocolPolicy: https-only DefaultCacheBehavior: TargetOriginId: LambdaOrigin ViewerProtocolPolicy: redirect-to-https CachePolicyId: !Ref CachePolicyId ResponseHeadersPolicyId: !Ref ResponseHeadersPolicyId OriginRequestPolicyId: b689b0a8-53d0-40ab-baf2-68738e2966ac FunctionAssociations: !If - IsPublicHostnameProvided - !Ref AWS::NoValue - - EventType: viewer-request FunctionARN: !GetAtt ViewerRequestCloudFrontFunction.FunctionARN Enabled: true HttpVersion: http2and3 Comment: CloudFront Distribution PriceClass: PriceClass_All CachePolicyId: Type: AWS::CloudFront::CachePolicy Properties: CachePolicyConfig: Name: !Sub ${AWS::StackName}-CachePolicyConfig DefaultTTL: !Ref DefaultTTL MaxTTL: 31536000 MinTTL: 0 ParametersInCacheKeyAndForwardedToOrigin: EnableAcceptEncodingBrotli: true EnableAcceptEncodingGzip: true HeadersConfig: HeaderBehavior: none CookiesConfig: CookieBehavior: none QueryStringsConfig: QueryStringBehavior: none ResponseHeadersPolicyId: Type: AWS::CloudFront::ResponseHeadersPolicy Properties: ResponseHeadersPolicyConfig: Name: !Sub ${AWS::StackName}-ResponseHeadersPolicyConfig CorsConfig: AccessControlAllowOrigins: Items: !Ref AllowedOrigins AccessControlAllowHeaders: Items: - '*' AccessControlAllowMethods: Items: - GET - HEAD - OPTIONS AccessControlExposeHeaders: Items: - ETag AccessControlAllowCredentials: false OriginOverride: true Comment: CORS policy for Protomaps LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${AWS::StackName}-LambdaFunction Runtime: nodejs22.x Architectures: - arm64 Role: !GetAtt LambdaExecutionRole.Arn Handler: index.handler MemorySize: 512 LoggingConfig: LogGroup: !Ref LogGroup Environment: Variables: BUCKET: !Ref BucketName PUBLIC_HOSTNAME: !Ref PublicHostname Code: ZipFile: > //sha:26424aa "use strict";var fr=Object.create;var re=Object.defineProperty;var vr=Object.getOwnPropertyDescriptor;var pr=Object.getOwnPropertyNames;var gr=Object.getPrototypeOf,dr=Object.prototype.hasOwnProperty;var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),mr=(t,e)=>{for(var r in e)re(t,r,{get:e[r],enumerable:!0})},je=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of pr(e))!dr.call(t,i)&&i!==r&&re(t,i,{get:()=>e[i],enumerable:!(n=vr(e,i))||n.enumerable});return t};var Be=(t,e,r)=>(r=t!=null?fr(gr(t)):{},je(e||!t||!t.__esModule?re(r,"default",{value:t,enumerable:!0}):r,t)),yr=t=>je(re({},"__esModule",{value:!0}),t);var xt=K((xi,wt)=>{var oe=Object.defineProperty,Jr=Object.getOwnPropertyDescriptor,Qr=Object.getOwnPropertyNames,Yr=Object.prototype.hasOwnProperty,se=(t,e)=>oe(t,"name",{value:e,configurable:!0}),Xr=(t,e)=>{for(var r in e)oe(t,r,{get:e[r],enumerable:!0})},en=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qr(e))!Yr.call(t,i)&&i!==r&&oe(t,i,{get:()=>e[i],enumerable:!(n=Jr(e,i))||n.enumerable});return t},tn=t=>en(oe({},"__esModule",{value:!0}),t),ht={};Xr(ht,{AlgorithmId:()=>gt,EndpointURLScheme:()=>pt,FieldPosition:()=>dt,HttpApiKeyAuthLocation:()=>vt,HttpAuthLocation:()=>ft,IniSectionType:()=>mt,RequestHandlerProtocol:()=>yt,SMITHY_CONTEXT_KEY:()=>an,getDefaultClientConfiguration:()=>on,resolveDefaultRuntimeConfig:()=>sn});wt.exports=tn(ht);var ft=(t=>(t.HEADER="header",t.QUERY="query",t))(ft||{}),vt=(t=>(t.HEADER="header",t.QUERY="query",t))(vt||{}),pt=(t=>(t.HTTP="http",t.HTTPS="https",t))(pt||{}),gt=(t=>(t.MD5="md5",t.CRC32="crc32",t.CRC32C="crc32c",t.SHA1="sha1",t.SHA256="sha256",t))(gt||{}),rn=se(t=>{let e=[];return t.sha256!==void 0&&e.push({algorithmId:()=>"sha256",checksumConstructor:()=>t.sha256}),t.md5!=null&&e.push({algorithmId:()=>"md5",checksumConstructor:()=>t.md5}),{_checksumAlgorithms:e,addChecksumAlgorithm(r){this._checksumAlgorithms.push(r)},checksumAlgorithms(){return this._checksumAlgorithms}}},"getChecksumConfiguration"),nn=se(t=>{let e={};return t.checksumAlgorithms().forEach(r=>{e[r.algorithmId()]=r.checksumConstructor()}),e},"resolveChecksumRuntimeConfig"),on=se(t=>({...rn(t)}),"getDefaultClientConfiguration"),sn=se(t=>({...nn(t)}),"resolveDefaultRuntimeConfig"),dt=(t=>(t[t.HEADER=0]="HEADER",t[t.TRAILER=1]="TRAILER",t))(dt||{}),an="__smithy_context",mt=(t=>(t.PROFILE="profile",t.SSO_SESSION="sso-session",t.SERVICES="services",t))(mt||{}),yt=(t=>(t.HTTP_0_9="http/0.9",t.HTTP_1_0="http/1.0",t.TDS_8_0="tds/8.0",t))(yt||{})});var zt=K((Ei,St)=>{var ae=Object.defineProperty,ln=Object.getOwnPropertyDescriptor,un=Object.getOwnPropertyNames,cn=Object.prototype.hasOwnProperty,N=(t,e)=>ae(t,"name",{value:e,configurable:!0}),hn=(t,e)=>{for(var r in e)ae(t,r,{get:e[r],enumerable:!0})},fn=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of un(e))!cn.call(t,i)&&i!==r&&ae(t,i,{get:()=>e[i],enumerable:!(n=ln(e,i))||n.enumerable});return t},vn=t=>fn(ae({},"__esModule",{value:!0}),t),Ct={};hn(Ct,{Field:()=>dn,Fields:()=>mn,HttpRequest:()=>yn,HttpResponse:()=>wn,IHttpRequest:()=>Tt.HttpRequest,getHttpHandlerExtensionConfiguration:()=>pn,isValidHostname:()=>_t,resolveHttpHandlerRuntimeConfig:()=>gn});St.exports=vn(Ct);var pn=N(t=>{let e=t.httpHandler;return{setHttpHandler(r){e=r},httpHandler(){return e},updateHttpClientConfig(r,n){e.updateHttpClientConfig(r,n)},httpHandlerConfigs(){return e.httpHandlerConfigs()}}},"getHttpHandlerExtensionConfiguration"),gn=N(t=>({httpHandler:t.httpHandler()}),"resolveHttpHandlerRuntimeConfig"),Tt=xt(),bt=class{constructor({name:e,kind:r=Tt.FieldPosition.HEADER,values:n=[]}){this.name=e,this.kind=r,this.values=n}add(e){this.values.push(e)}set(e){this.values=e}remove(e){this.values=this.values.filter(r=>r!==e)}toString(){return this.values.map(e=>e.includes(",")||e.includes(" ")?`"${e}"`:e).join(", ")}get(){return this.values}};N(bt,"Field");var dn=bt,Et=class{constructor({fields:e=[],encoding:r="utf-8"}){this.entries={},e.forEach(this.setField.bind(this)),this.encoding=r}setField(e){this.entries[e.name.toLowerCase()]=e}getField(e){return this.entries[e.toLowerCase()]}removeField(e){delete this.entries[e.toLowerCase()]}getByType(e){return Object.values(this.entries).filter(r=>r.kind===e)}};N(Et,"Fields");var mn=Et,At=class Te{constructor(e){this.method=e.method||"GET",this.hostname=e.hostname||"localhost",this.port=e.port,this.query=e.query||{},this.headers=e.headers||{},this.body=e.body,this.protocol=e.protocol?e.protocol.slice(-1)!==":"?`${e.protocol}:`:e.protocol:"https:",this.path=e.path?e.path.charAt(0)!=="/"?`/${e.path}`:e.path:"/",this.username=e.username,this.password=e.password,this.fragment=e.fragment}static clone(e){let r=new Te({...e,headers:{...e.headers}});return r.query&&(r.query=Pt(r.query)),r}static isInstance(e){if(!e)return!1;let r=e;return"method"in r&&"protocol"in r&&"hostname"in r&&"path"in r&&typeof r.query=="object"&&typeof r.headers=="object"}clone(){return Te.clone(this)}};N(At,"HttpRequest");var yn=At;function Pt(t){return Object.keys(t).reduce((e,r)=>{let n=t[r];return{...e,[r]:Array.isArray(n)?[...n]:n}},{})}N(Pt,"cloneQuery");var Ht=class{constructor(e){this.statusCode=e.statusCode,this.reason=e.reason,this.headers=e.headers||{},this.body=e.body}static isInstance(e){if(!e)return!1;let r=e;return typeof r.statusCode=="number"&&typeof r.headers=="object"}};N(Ht,"HttpResponse");var wn=Ht;function _t(t){return/^[a-z0-9][a-z0-9\.\-]*[a-z0-9]$/.test(t)}N(_t,"isValidHostname")});var Ut=K((Ai,Rt)=>{var le=Object.defineProperty,xn=Object.getOwnPropertyDescriptor,Cn=Object.getOwnPropertyNames,Tn=Object.prototype.hasOwnProperty,be=(t,e)=>le(t,"name",{value:e,configurable:!0}),bn=(t,e)=>{for(var r in e)le(t,r,{get:e[r],enumerable:!0})},En=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Cn(e))!Tn.call(t,i)&&i!==r&&le(t,i,{get:()=>e[i],enumerable:!(n=xn(e,i))||n.enumerable});return t},An=t=>En(le({},"__esModule",{value:!0}),t),Ot={};bn(Ot,{escapeUri:()=>Mt,escapeUriPath:()=>Hn});Rt.exports=An(Ot);var Mt=be(t=>encodeURIComponent(t).replace(/[!'()*]/g,Pn),"escapeUri"),Pn=be(t=>`%${t.charCodeAt(0).toString(16).toUpperCase()}`,"hexEncode"),Hn=be(t=>t.split("/").map(Mt).join("/"),"escapeUriPath")});var It=K((Pi,kt)=>{var ue=Object.defineProperty,_n=Object.getOwnPropertyDescriptor,Sn=Object.getOwnPropertyNames,zn=Object.prototype.hasOwnProperty,On=(t,e)=>ue(t,"name",{value:e,configurable:!0}),Mn=(t,e)=>{for(var r in e)ue(t,r,{get:e[r],enumerable:!0})},Rn=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Sn(e))!zn.call(t,i)&&i!==r&&ue(t,i,{get:()=>e[i],enumerable:!(n=_n(e,i))||n.enumerable});return t},Un=t=>Rn(ue({},"__esModule",{value:!0}),t),Dt={};Mn(Dt,{buildQueryString:()=>Lt});kt.exports=Un(Dt);var Ee=Ut();function Lt(t){let e=[];for(let r of Object.keys(t).sort()){let n=t[r];if(r=(0,Ee.escapeUri)(r),Array.isArray(n))for(let i=0,o=n.length;i{var Dn=Object.create,ee=Object.defineProperty,Ln=Object.getOwnPropertyDescriptor,kn=Object.getOwnPropertyNames,In=Object.getPrototypeOf,Nn=Object.prototype.hasOwnProperty,C=(t,e)=>ee(t,"name",{value:e,configurable:!0}),jn=(t,e)=>{for(var r in e)ee(t,r,{get:e[r],enumerable:!0})},Bt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of kn(e))!Nn.call(t,i)&&i!==r&&ee(t,i,{get:()=>e[i],enumerable:!(n=Ln(e,i))||n.enumerable});return t},Bn=(t,e,r)=>(r=t!=null?Dn(In(t)):{},Bt(e||!t||!t.__esModule?ee(r,"default",{value:t,enumerable:!0}):r,t)),$n=t=>Bt(ee({},"__esModule",{value:!0}),t),$t={};jn($t,{DEFAULT_REQUEST_TIMEOUT:()=>Kn,NodeHttp2Handler:()=>Yn,NodeHttpHandler:()=>Wn,streamCollector:()=>ei});tr.exports=$n($t);var Ft=zt(),qt=It(),Ae=require("http"),Pe=require("https"),Fn=["ECONNRESET","EPIPE","ETIMEDOUT"],Zt=C(t=>{let e={};for(let r of Object.keys(t)){let n=t[r];e[r]=Array.isArray(n)?n.join(","):n}return e},"getTransformedHeaders"),qn=C((t,e,r=0)=>{if(!r)return;let n=setTimeout(()=>{t.destroy(),e(Object.assign(new Error(`Socket timed out without establishing a connection within ${r} ms`),{name:"TimeoutError"}))},r);t.on("socket",i=>{i.connecting?i.on("connect",()=>{clearTimeout(n)}):clearTimeout(n)})},"setConnectionTimeout"),Zn=C((t,{keepAlive:e,keepAliveMsecs:r})=>{e===!0&&t.on("socket",n=>{n.setKeepAlive(e,r||0)})},"setSocketKeepAlive"),Gn=C((t,e,r=0)=>{t.setTimeout(r,()=>{t.destroy(),e(Object.assign(new Error(`Connection timed out after ${r} ms`),{name:"TimeoutError"}))})},"setSocketTimeout"),Gt=require("stream"),Nt=1e3;async function _e(t,e,r=Nt){let n=e.headers??{},i=n.Expect||n.expect,o=-1,s=!1;i==="100-continue"&&await Promise.race([new Promise(a=>{o=Number(setTimeout(a,Math.max(Nt,r)))}),new Promise(a=>{t.on("continue",()=>{clearTimeout(o),a()}),t.on("error",()=>{s=!0,clearTimeout(o),a()})})]),s||Kt(t,e.body)}C(_e,"writeRequestBody");function Kt(t,e){if(e instanceof Gt.Readable){e.pipe(t);return}if(e){if(Buffer.isBuffer(e)||typeof e=="string"){t.end(e);return}let r=e;if(typeof r=="object"&&r.buffer&&typeof r.byteOffset=="number"&&typeof r.byteLength=="number"){t.end(Buffer.from(r.buffer,r.byteOffset,r.byteLength));return}t.end(Buffer.from(e));return}t.end()}C(Kt,"writeBody");var Kn=0,Wt=class He{constructor(e){this.socketWarningTimestamp=0,this.metadata={handlerProtocol:"http/1.1"},this.configProvider=new Promise((r,n)=>{typeof e=="function"?e().then(i=>{r(this.resolveDefaultConfig(i))}).catch(n):r(this.resolveDefaultConfig(e))})}static create(e){return typeof e?.handle=="function"?e:new He(e)}static checkSocketUsage(e,r,n=console){var i,o,s;let{sockets:a,requests:l,maxSockets:h}=e;if(typeof h!="number"||h===1/0||Date.now()-15e3=h&&y>=2*h)return(s=n?.warn)==null||s.call(n,`@smithy/node-http-handler:WARN - socket usage at capacity=${c} and ${y} additional requests are enqueued. See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler config.`),Date.now()}return r}resolveDefaultConfig(e){let{requestTimeout:r,connectionTimeout:n,socketTimeout:i,httpAgent:o,httpsAgent:s}=e||{},a=!0,l=50;return{connectionTimeout:n,requestTimeout:r??i,httpAgent:o instanceof Ae.Agent||typeof o?.destroy=="function"?o:new Ae.Agent({keepAlive:a,maxSockets:l,...o}),httpsAgent:s instanceof Pe.Agent||typeof s?.destroy=="function"?s:new Pe.Agent({keepAlive:a,maxSockets:l,...s}),logger:console}}destroy(){var e,r,n,i;(r=(e=this.config)==null?void 0:e.httpAgent)==null||r.destroy(),(i=(n=this.config)==null?void 0:n.httpsAgent)==null||i.destroy()}async handle(e,{abortSignal:r}={}){this.config||(this.config=await this.configProvider);let n;return new Promise((i,o)=>{let s,a=C(async p=>{await s,clearTimeout(n),i(p)},"resolve"),l=C(async p=>{await s,clearTimeout(n),o(p)},"reject");if(!this.config)throw new Error("Node HTTP request handler config is not resolved");if(r?.aborted){let p=new Error("Request aborted");p.name="AbortError",l(p);return}let h=e.protocol==="https:",f=h?this.config.httpsAgent:this.config.httpAgent;n=setTimeout(()=>{this.socketWarningTimestamp=He.checkSocketUsage(f,this.socketWarningTimestamp,this.config.logger)},this.config.socketAcquisitionWarningTimeout??(this.config.requestTimeout??2e3)+(this.config.connectionTimeout??1e3));let u=(0,qt.buildQueryString)(e.query||{}),c;if(e.username!=null||e.password!=null){let p=e.username??"",x=e.password??"";c=`${p}:${x}`}let y=e.path;u&&(y+=`?${u}`),e.fragment&&(y+=`#${e.fragment}`);let T={headers:e.headers,host:e.hostname,method:e.method,path:y,port:e.port,agent:f,auth:c},w=(h?Pe.request:Ae.request)(T,p=>{let x=new Ft.HttpResponse({statusCode:p.statusCode||-1,reason:p.statusMessage,headers:Zt(p.headers),body:p});a({response:x})});if(w.on("error",p=>{Fn.includes(p.code)?l(Object.assign(p,{name:"TimeoutError"})):l(p)}),qn(w,l,this.config.connectionTimeout),Gn(w,l,this.config.requestTimeout),r){let p=C(()=>{w.destroy();let x=new Error("Request aborted");x.name="AbortError",l(x)},"onAbort");if(typeof r.addEventListener=="function"){let x=r;x.addEventListener("abort",p,{once:!0}),w.once("close",()=>x.removeEventListener("abort",p))}else r.onabort=p}let H=T.agent;typeof H=="object"&&"keepAlive"in H&&Zn(w,{keepAlive:H.keepAlive,keepAliveMsecs:H.keepAliveMsecs}),s=_e(w,e,this.config.requestTimeout).catch(p=>(clearTimeout(n),o(p)))})}updateHttpClientConfig(e,r){this.config=void 0,this.configProvider=this.configProvider.then(n=>({...n,[e]:r}))}httpHandlerConfigs(){return this.config??{}}};C(Wt,"NodeHttpHandler");var Wn=Wt,jt=require("http2"),Vn=Bn(require("http2")),Vt=class{constructor(e){this.sessions=[],this.sessions=e??[]}poll(){if(this.sessions.length>0)return this.sessions.shift()}offerLast(e){this.sessions.push(e)}contains(e){return this.sessions.includes(e)}remove(e){this.sessions=this.sessions.filter(r=>r!==e)}[Symbol.iterator](){return this.sessions[Symbol.iterator]()}destroy(e){for(let r of this.sessions)r===e&&(r.destroyed||r.destroy())}};C(Vt,"NodeHttp2ConnectionPool");var Jn=Vt,Jt=class{constructor(e){if(this.sessionCache=new Map,this.config=e,this.config.maxConcurrency&&this.config.maxConcurrency<=0)throw new RangeError("maxConcurrency must be greater than zero.")}lease(e,r){let n=this.getUrlString(e),i=this.sessionCache.get(n);if(i){let l=i.poll();if(l&&!this.config.disableConcurrency)return l}let o=Vn.default.connect(n);this.config.maxConcurrency&&o.settings({maxConcurrentStreams:this.config.maxConcurrency},l=>{if(l)throw new Error("Fail to set maxConcurrentStreams to "+this.config.maxConcurrency+"when creating new session for "+e.destination.toString())}),o.unref();let s=C(()=>{o.destroy(),this.deleteSession(n,o)},"destroySessionCb");o.on("goaway",s),o.on("error",s),o.on("frameError",s),o.on("close",()=>this.deleteSession(n,o)),r.requestTimeout&&o.setTimeout(r.requestTimeout,s);let a=this.sessionCache.get(n)||new Jn;return a.offerLast(o),this.sessionCache.set(n,a),o}deleteSession(e,r){let n=this.sessionCache.get(e);n&&n.contains(r)&&(n.remove(r),this.sessionCache.set(e,n))}release(e,r){var n;let i=this.getUrlString(e);(n=this.sessionCache.get(i))==null||n.offerLast(r)}destroy(){for(let[e,r]of this.sessionCache){for(let n of r)n.destroyed||n.destroy(),r.remove(n);this.sessionCache.delete(e)}}setMaxConcurrentStreams(e){if(this.config.maxConcurrency&&this.config.maxConcurrency<=0)throw new RangeError("maxConcurrentStreams must be greater than zero.");this.config.maxConcurrency=e}setDisableConcurrentStreams(e){this.config.disableConcurrency=e}getUrlString(e){return e.destination.toString()}};C(Jt,"NodeHttp2ConnectionManager");var Qn=Jt,Qt=class Yt{constructor(e){this.metadata={handlerProtocol:"h2"},this.connectionManager=new Qn({}),this.configProvider=new Promise((r,n)=>{typeof e=="function"?e().then(i=>{r(i||{})}).catch(n):r(e||{})})}static create(e){return typeof e?.handle=="function"?e:new Yt(e)}destroy(){this.connectionManager.destroy()}async handle(e,{abortSignal:r}={}){this.config||(this.config=await this.configProvider,this.connectionManager.setDisableConcurrentStreams(this.config.disableConcurrentStreams||!1),this.config.maxConcurrentStreams&&this.connectionManager.setMaxConcurrentStreams(this.config.maxConcurrentStreams));let{requestTimeout:n,disableConcurrentStreams:i}=this.config;return new Promise((o,s)=>{var a;let l=!1,h,f=C(async g=>{await h,o(g)},"resolve"),u=C(async g=>{await h,s(g)},"reject");if(r?.aborted){l=!0;let g=new Error("Request aborted");g.name="AbortError",u(g);return}let{hostname:c,method:y,port:T,protocol:m,query:w}=e,H="";if(e.username!=null||e.password!=null){let g=e.username??"",A=e.password??"";H=`${g}:${A}@`}let p=`${m}//${H}${c}${T?`:${T}`:""}`,x={destination:new URL(p)},M=this.connectionManager.lease(x,{requestTimeout:(a=this.config)==null?void 0:a.sessionTimeout,disableConcurrentStreams:i||!1}),D=C(g=>{i&&this.destroySession(M),l=!0,u(g)},"rejectWithDestroy"),j=(0,qt.buildQueryString)(w||{}),B=e.path;j&&(B+=`?${j}`),e.fragment&&(B+=`#${e.fragment}`);let E=M.request({...e.headers,[jt.constants.HTTP2_HEADER_PATH]:B,[jt.constants.HTTP2_HEADER_METHOD]:y});if(M.ref(),E.on("response",g=>{let A=new Ft.HttpResponse({statusCode:g[":status"]||-1,headers:Zt(g),body:E});l=!0,f({response:A}),i&&(M.close(),this.connectionManager.deleteSession(p,M))}),n&&E.setTimeout(n,()=>{E.close();let g=new Error(`Stream timed out because of no activity for ${n} ms`);g.name="TimeoutError",D(g)}),r){let g=C(()=>{E.close();let A=new Error("Request aborted");A.name="AbortError",D(A)},"onAbort");if(typeof r.addEventListener=="function"){let A=r;A.addEventListener("abort",g,{once:!0}),E.once("close",()=>A.removeEventListener("abort",g))}else r.onabort=g}E.on("frameError",(g,A,P)=>{D(new Error(`Frame type id ${g} in stream id ${P} has failed with code ${A}.`))}),E.on("error",D),E.on("aborted",()=>{D(new Error(`HTTP/2 stream is abnormally aborted in mid-communication with result code ${E.rstCode}.`))}),E.on("close",()=>{M.unref(),i&&M.destroy(),l||D(new Error("Unexpected error: http2 request did not get a response"))}),h=_e(E,e,n)})}updateHttpClientConfig(e,r){this.config=void 0,this.configProvider=this.configProvider.then(n=>({...n,[e]:r}))}httpHandlerConfigs(){return this.config??{}}destroySession(e){e.destroyed||e.destroy()}};C(Qt,"NodeHttp2Handler");var Yn=Qt,Xt=class extends Gt.Writable{constructor(){super(...arguments),this.bufferedBytes=[]}_write(e,r,n){this.bufferedBytes.push(e),n()}};C(Xt,"Collector");var Xn=Xt,ei=C(t=>ti(t)?er(t):new Promise((e,r)=>{let n=new Xn;t.pipe(n),t.on("error",i=>{n.end(),r(i)}),n.on("error",r),n.on("finish",function(){let i=new Uint8Array(Buffer.concat(this.bufferedBytes));e(i)})}),"streamCollector"),ti=C(t=>typeof ReadableStream=="function"&&t instanceof ReadableStream,"isReadableStreamInstance");async function er(t){let e=[],r=t.getReader(),n=!1,i=0;for(;!n;){let{done:a,value:l}=await r.read();l&&(e.push(l),i+=l.length),n=a}let o=new Uint8Array(i),s=0;for(let a of e)o.set(a,s),s+=a.length;return o}C(er,"collectReadableStream")});var oi={};mr(oi,{handler:()=>ii,handlerRaw:()=>sr});module.exports=yr(oi);var $e=require("module"),wr=(0,$e.createRequire)("/"),xr;try{xr=wr("worker_threads").Worker}catch{}var S=Uint8Array,q=Uint16Array,Cr=Int32Array,Fe=new S([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),qe=new S([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Tr=new S([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Ze=function(t,e){for(var r=new q(31),n=0;n<31;++n)r[n]=e+=1<>1|(v&21845)<<1,k=(k&52428)>>2|(k&13107)<<2,k=(k&61680)>>4|(k&3855)<<4,de[v]=((k&65280)>>8|(k&255)<<8)>>1;var k,v,W=function(t,e,r){for(var n=t.length,i=0,o=new q(e);i>l]=h}else for(a=new q(n),i=0;i>15-t[i]);return a},V=new S(288);for(v=0;v<144;++v)V[v]=8;var v;for(v=144;v<256;++v)V[v]=9;var v;for(v=256;v<280;++v)V[v]=7;var v;for(v=280;v<288;++v)V[v]=8;var v,Ve=new S(32);for(v=0;v<32;++v)Ve[v]=5;var v;var Ar=W(V,9,1);var Pr=W(Ve,5,1),pe=function(t){for(var e=t[0],r=1;re&&(e=t[r]);return e},R=function(t,e,r){var n=e/8|0;return(t[n]|t[n+1]<<8)>>(e&7)&r},ge=function(t,e){var r=e/8|0;return(t[r]|t[r+1]<<8|t[r+2]<<16)>>(e&7)},Hr=function(t){return(t+7)/8|0},_r=function(t,e,r){return(e==null||e<0)&&(e=0),(r==null||r>t.length)&&(r=t.length),new S(t.subarray(e,r))};var Sr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],_=function(t,e,r){var n=new Error(e||Sr[t]);if(n.code=t,Error.captureStackTrace&&Error.captureStackTrace(n,_),!r)throw n;return n},me=function(t,e,r,n){var i=t.length,o=n?n.length:0;if(!i||e.f&&!e.l)return r||new S(0);var s=!r,a=s||e.i!=2,l=e.i;s&&(r=new S(i*3));var h=function(ke){var Ie=r.length;if(ke>Ie){var Ne=new S(Math.max(Ie*2,ke));Ne.set(r),r=Ne}},f=e.f||0,u=e.p||0,c=e.b||0,y=e.l,T=e.d,m=e.m,w=e.n,H=i*8;do{if(!y){f=R(t,u,1);var p=R(t,u+1,3);if(u+=3,p)if(p==1)y=Ar,T=Pr,m=9,w=5;else if(p==2){var j=R(t,u,31)+257,B=R(t,u+10,15)+4,E=j+R(t,u+5,31)+1;u+=14;for(var g=new S(E),A=new S(19),P=0;P>4;if(x<16)g[P++]=x;else{var $=0,te=0;for(x==16?(te=3+R(t,u,3),u+=2,$=g[P-1]):x==17?(te=3+R(t,u,7),u+=3):x==18&&(te=11+R(t,u,127),u+=7);te--;)g[P++]=$}}var Re=g.subarray(0,j),I=g.subarray(j);m=pe(Re),w=pe(I),y=W(Re,m,1),T=W(I,w,1)}else _(1);else{var x=Hr(u)+4,M=t[x-4]|t[x-3]<<8,D=x+M;if(D>i){l&&_(0);break}a&&h(c+M),r.set(t.subarray(x,D),c),e.b=c+=M,e.p=u=D*8,e.f=f;continue}if(u>H){l&&_(0);break}}a&&h(c+131072);for(var ur=(1<>4;if(u+=$&15,u>H){l&&_(0);break}if($||_(2),F<256)r[c++]=F;else if(F==256){he=u,y=null;break}else{var Ue=F-254;if(F>264){var P=F-257,G=Fe[P];Ue=R(t,u,(1<>4;fe||_(3),u+=fe&15;var I=Er[ve];if(ve>3){var G=qe[ve];I+=ge(t,u)&(1<H){l&&_(0);break}a&&h(c+131072);var De=c+Ue;if(c>3&1)+(e>>4&1);n>0;n-=!t[r++]);return r+(e&2)},Mr=function(t){var e=t.length;return(t[e-4]|t[e-3]<<8|t[e-2]<<16|t[e-1]<<24)>>>0};var Rr=function(t,e){return((t[0]&15)!=8||t[0]>>4>7||(t[0]<<8|t[1])%31)&&_(6,"invalid zlib data"),(t[1]>>5&1)==+!e&&_(6,"invalid zlib data: "+(t[1]&32?"need":"unexpected")+" dictionary"),(t[1]>>3&4)+2};function Ur(t,e){return me(t,{i:2},e&&e.out,e&&e.dictionary)}function Dr(t,e){var r=Or(t);return r+8>t.length&&_(6,"invalid gzip data"),me(t.subarray(r,-8),{i:2},e&&e.out||new S(Mr(t)),e&&e.dictionary)}function Lr(t,e){return me(t.subarray(Rr(t,e&&e.dictionary),-4),{i:2},e&&e.out,e&&e.dictionary)}function Je(t,e){return t[0]==31&&t[1]==139&&t[2]==8?Dr(t,e):(t[0]&15)!=8||t[0]>>4>7||(t[0]<<8|t[1])%31?Ur(t,e):Lr(t,e)}var kr=typeof TextDecoder<"u"&&new TextDecoder,Ir=0;try{kr.decode(zr,{stream:!0}),Ir=1}catch{}var Nr=Object.defineProperty,J=Math.pow,d=(t,e)=>Nr(t,"name",{value:e,configurable:!0}),b=(t,e,r)=>new Promise((n,i)=>{var o=l=>{try{a(r.next(l))}catch(h){i(h)}},s=l=>{try{a(r.throw(l))}catch(h){i(h)}},a=l=>l.done?n(l.value):Promise.resolve(l.value).then(o,s);a((r=r.apply(t,e)).next())}),ci=d((t,e)=>{let r=!1,n="",i=L.GridLayer.extend({createTile:d((o,s)=>{let a=document.createElement("img"),l=new AbortController,h=l.signal;return a.cancel=()=>{l.abort()},r||(t.getHeader().then(f=>{f.tileType===1?console.error("Error: archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles. See https://github.com/protomaps/PMTiles/tree/main/js for details."):f.tileType===2?n="image/png":f.tileType===3?n="image/jpeg":f.tileType===4?n="image/webp":f.tileType===5&&(n="image/avif")}),r=!0),t.getZxy(o.z,o.x,o.y,h).then(f=>{if(f){let u=new Blob([f.data],{type:n}),c=window.URL.createObjectURL(u);a.src=c,a.cancel=void 0,s(void 0,a)}}).catch(f=>{if(f.name!=="AbortError")throw f}),a},"createTile"),_removeTile:d(function(o){let s=this._tiles[o];s&&(s.el.cancel&&s.el.cancel(),s.el.width=0,s.el.height=0,s.el.deleted=!0,L.DomUtil.remove(s.el),delete this._tiles[o],this.fire("tileunload",{tile:s.el,coords:this._keyToTileCoords(o)}))},"_removeTile")});return new i(e)},"leafletRasterLayer"),jr=d(t=>(e,r)=>{if(r instanceof AbortController)return t(e,r);let n=new AbortController;return t(e,n).then(i=>r(void 0,i.data,i.cacheControl||"",i.expires||""),i=>r(i)).catch(i=>r(i)),{cancel:d(()=>n.abort(),"cancel")}},"v3compat"),Br=class{constructor(e){this.tilev4=d((r,n)=>b(this,null,function*(){if(r.type==="json"){let y=r.url.substr(10),T=this.tiles.get(y);if(T||(T=new ne(y),this.tiles.set(y,T)),this.metadata)return{data:yield T.getTileJson(r.url)};let m=yield T.getHeader();return(m.minLon>=m.maxLon||m.minLat>=m.maxLat)&&console.error(`Bounds of PMTiles archive ${m.minLon},${m.minLat},${m.maxLon},${m.maxLat} are not valid.`),{data:{tiles:[`${r.url}/{z}/{x}/{y}`],minzoom:m.minZoom,maxzoom:m.maxZoom,bounds:[m.minLon,m.minLat,m.maxLon,m.maxLat]}}}let i=new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/),o=r.url.match(i);if(!o)throw new Error("Invalid PMTiles protocol URL");let s=o[1],a=this.tiles.get(s);a||(a=new ne(s),this.tiles.set(s,a));let l=o[2],h=o[3],f=o[4],u=yield a.getHeader(),c=yield a?.getZxy(+l,+h,+f,n.signal);if(c)return{data:new Uint8Array(c.data),cacheControl:c.cacheControl,expires:c.expires};if(u.tileType===1){if(this.errorOnMissingTile)throw new Error("Tile not found.");return{data:new Uint8Array}}return{data:null}}),"tilev4"),this.tile=jr(this.tilev4),this.tiles=new Map,this.metadata=e?.metadata||!1,this.errorOnMissingTile=e?.errorOnMissingTile||!1}add(e){this.tiles.set(e.source.getKey(),e)}get(e){return this.tiles.get(e)}};d(Br,"Protocol");function Qe(t,e){return(e>>>0)*4294967296+(t>>>0)}d(Qe,"toNum");function Ye(t,e){let r=e.buf,n=r[e.pos++],i=(n&112)>>4;if(n<128||(n=r[e.pos++],i|=(n&127)<<3,n<128)||(n=r[e.pos++],i|=(n&127)<<10,n<128)||(n=r[e.pos++],i|=(n&127)<<17,n<128)||(n=r[e.pos++],i|=(n&127)<<24,n<128)||(n=r[e.pos++],i|=(n&1)<<31,n<128))return Qe(t,i);throw new Error("Expected varint not more than 10 bytes")}d(Ye,"readVarintRemainder");function Z(t){let e=t.buf,r=e[t.pos++],n=r&127;return r<128||(r=e[t.pos++],n|=(r&127)<<7,r<128)||(r=e[t.pos++],n|=(r&127)<<14,r<128)||(r=e[t.pos++],n|=(r&127)<<21,r<128)?n:(r=e[t.pos],n|=(r&15)<<28,Ye(n,t))}d(Z,"readVarint");function ye(t,e,r,n){if(n===0){r===1&&(e[0]=t-1-e[0],e[1]=t-1-e[1]);let i=e[0];e[0]=e[1],e[1]=i}}d(ye,"rotate");function Xe(t,e){let r=J(2,t),n=e,i=e,o=e,s=[0,0],a=1;for(;a26)throw new Error("Tile zoom level exceeds max safe number limit (26)");if(e>J(2,t)-1||r>J(2,t)-1)throw new Error("tile x/y outside zoom level bounds");let n=$r[t],i=J(2,t),o=0,s=0,a=0,l=[e,r],h=i/2;for(;h>0;)o=(l[0]&h)>0?1:0,s=(l[1]&h)>0?1:0,a+=h*h*(3*o^s),ye(h,l,o,s),h=h/2;return n+a}d(et,"zxyToTileId");function Fr(t){let e=0,r=0;for(let n=0;n<27;n++){let i=(1<t)return Xe(n,t-e);e+=i}throw new Error("Tile zoom level exceeds max safe number limit (26)")}d(Fr,"tileIdToZxy");var Y=(t=>(t[t.Unknown=0]="Unknown",t[t.None=1]="None",t[t.Gzip=2]="Gzip",t[t.Brotli=3]="Brotli",t[t.Zstd=4]="Zstd",t))(Y||{});function ie(t,e){return b(this,null,function*(){if(e===1||e===0)return t;if(e===2){if(typeof globalThis.DecompressionStream>"u")return Je(new Uint8Array(t));let r=new Response(t).body;if(!r)throw new Error("Failed to read response stream");let n=r.pipeThrough(new globalThis.DecompressionStream("gzip"));return new Response(n).arrayBuffer()}throw new Error("Compression method not supported")})}d(ie,"defaultDecompress");var z=(t=>(t[t.Unknown=0]="Unknown",t[t.Mvt=1]="Mvt",t[t.Png=2]="Png",t[t.Jpeg=3]="Jpeg",t[t.Webp=4]="Webp",t[t.Avif=5]="Avif",t))(z||{});function X(t){return t===1?".mvt":t===2?".png":t===3?".jpg":t===4?".webp":t===5?".avif":""}d(X,"tileTypeExt");var qr=127;function tt(t,e){let r=0,n=t.length-1;for(;r<=n;){let i=n+r>>1,o=e-t[i].tileId;if(o>0)r=i+1;else if(o<0)n=i-1;else return t[i]}return n>=0&&(t[n].runLength===0||e-t[n].tileId-1,o=/Chrome|Chromium|Edg|OPR|Brave/.test(n);this.chromeWindowsNoCache=!1,i&&o&&(this.chromeWindowsNoCache=!0)}getKey(){return this.url}setHeaders(e){this.customHeaders=e}getBytes(e,r,n,i){return b(this,null,function*(){let o,s;n?s=n:(o=new AbortController,s=o.signal);let a=new Headers(this.customHeaders);a.set("range",`bytes=${e}-${e+r-1}`);let l;this.mustReload?l="reload":this.chromeWindowsNoCache&&(l="no-store");let h=yield fetch(this.url,{signal:s,cache:l,headers:a});if(e===0&&h.status===416){let c=h.headers.get("Content-Range");if(!c||!c.startsWith("bytes */"))throw new Error("Missing content-length on 416 response");let y=+c.substr(8);h=yield fetch(this.url,{signal:s,cache:"reload",headers:{range:`bytes=0-${y-1}`}})}let f=h.headers.get("Etag");if(f!=null&&f.startsWith("W/")&&(f=null),h.status===416||i&&f&&f!==i)throw this.mustReload=!0,new Q(`Server returned non-matching ETag ${i} after one retry. Check browser extensions and servers for issues that may affect correct ETag headers.`);if(h.status>=300)throw new Error(`Bad response code: ${h.status}`);let u=h.headers.get("Content-Length");if(h.status===200&&(!u||+u>r))throw o&&o.abort(),new Error("Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving.");return{data:yield h.arrayBuffer(),etag:f||void 0,cacheControl:h.headers.get("Cache-Control")||void 0,expires:h.headers.get("Expires")||void 0}})}};d(rt,"FetchSource");var Gr=rt;function O(t,e){let r=t.getUint32(e+4,!0),n=t.getUint32(e+0,!0);return r*J(2,32)+n}d(O,"getUint64");function nt(t,e){let r=new DataView(t),n=r.getUint8(7);if(n>3)throw new Error(`Archive is spec version ${n} but this library supports up to spec version 3`);return{specVersion:n,rootDirectoryOffset:O(r,8),rootDirectoryLength:O(r,16),jsonMetadataOffset:O(r,24),jsonMetadataLength:O(r,32),leafDirectoryOffset:O(r,40),leafDirectoryLength:O(r,48),tileDataOffset:O(r,56),tileDataLength:O(r,64),numAddressedTiles:O(r,72),numTileEntries:O(r,80),numTileContents:O(r,88),clustered:r.getUint8(96)===1,internalCompression:r.getUint8(97),tileCompression:r.getUint8(98),tileType:r.getUint8(99),minZoom:r.getUint8(100),maxZoom:r.getUint8(101),minLon:r.getInt32(102,!0)/1e7,minLat:r.getInt32(106,!0)/1e7,maxLon:r.getInt32(110,!0)/1e7,maxLat:r.getInt32(114,!0)/1e7,centerZoom:r.getUint8(118),centerLon:r.getInt32(119,!0)/1e7,centerLat:r.getInt32(123,!0)/1e7,etag:e}}d(nt,"bytesToHeader");function we(t){let e={buf:new Uint8Array(t),pos:0},r=Z(e),n=[],i=0;for(let o=0;o0?n[o].offset=n[o-1].offset+n[o-1].length:n[o].offset=s-1}return n}d(we,"deserializeIndex");var it=class extends Error{};d(it,"EtagMismatch");var Q=it;function xe(t,e){return b(this,null,function*(){let r=yield t.getBytes(0,16384);if(new DataView(r.data).getUint16(0,!0)!==19792)throw new Error("Wrong magic number for PMTiles archive");let n=r.data.slice(0,qr),i=nt(n,r.etag),o=r.data.slice(i.rootDirectoryOffset,i.rootDirectoryOffset+i.rootDirectoryLength),s=`${t.getKey()}|${i.etag||""}|${i.rootDirectoryOffset}|${i.rootDirectoryLength}`,a=we(yield e(o,i.internalCompression));return[i,[s,a.length,a]]})}d(xe,"getHeaderAndRoot");function Ce(t,e,r,n,i){return b(this,null,function*(){let o=yield t.getBytes(r,n,void 0,i.etag),s=yield e(o.data,i.internalCompression),a=we(s);if(a.length===0)throw new Error("Empty directory is invalid");return a})}d(Ce,"getDirectory");var ot=class{constructor(e=100,r=!0,n=ie){this.cache=new Map,this.maxCacheEntries=e,this.counter=1,this.decompress=n}getHeader(e){return b(this,null,function*(){let r=e.getKey(),n=this.cache.get(r);if(n)return n.lastUsed=this.counter++,n.data;let i=yield xe(e,this.decompress);return i[1]&&this.cache.set(i[1][0],{lastUsed:this.counter++,data:i[1][2]}),this.cache.set(r,{lastUsed:this.counter++,data:i[0]}),this.prune(),i[0]})}getDirectory(e,r,n,i){return b(this,null,function*(){let o=`${e.getKey()}|${i.etag||""}|${r}|${n}`,s=this.cache.get(o);if(s)return s.lastUsed=this.counter++,s.data;let a=yield Ce(e,this.decompress,r,n,i);return this.cache.set(o,{lastUsed:this.counter++,data:a}),this.prune(),a})}prune(){if(this.cache.size>this.maxCacheEntries){let e=1/0,r;this.cache.forEach((n,i)=>{n.lastUsed{xe(e,this.decompress).then(a=>{a[1]&&this.cache.set(a[1][0],{lastUsed:this.counter++,data:Promise.resolve(a[1][2])}),o(a[0]),this.prune()}).catch(a=>{s(a)})});return this.cache.set(r,{lastUsed:this.counter++,data:i}),i})}getDirectory(e,r,n,i){return b(this,null,function*(){let o=`${e.getKey()}|${i.etag||""}|${r}|${n}`,s=this.cache.get(o);if(s)return s.lastUsed=this.counter++,yield s.data;let a=new Promise((l,h)=>{Ce(e,this.decompress,r,n,i).then(f=>{l(f),this.prune()}).catch(f=>{h(f)})});return this.cache.set(o,{lastUsed:this.counter++,data:a}),a})}prune(){if(this.cache.size>=this.maxCacheEntries){let e=1/0,r;this.cache.forEach((n,i)=>{n.lastUsed{this.getHeader(e).then(s=>{i(),this.invalidations.delete(r)}).catch(s=>{o(s)})});this.invalidations.set(r,n)})}};d(at,"SharedPromiseCache");var Kr=at,lt=class{constructor(e,r,n){typeof e=="string"?this.source=new Gr(e):this.source=e,n?this.decompress=n:this.decompress=ie,r?this.cache=r:this.cache=new Kr}getHeader(){return b(this,null,function*(){return yield this.cache.getHeader(this.source)})}getZxyAttempt(e,r,n,i){return b(this,null,function*(){let o=et(e,r,n),s=yield this.cache.getHeader(this.source);if(es.maxZoom)return;let a=s.rootDirectoryOffset,l=s.rootDirectoryLength;for(let h=0;h<=3;h++){let f=yield this.cache.getDirectory(this.source,a,l,s),u=tt(f,o);if(u){if(u.runLength>0){let c=yield this.source.getBytes(s.tileDataOffset+u.offset,u.length,i,s.etag);return{data:yield this.decompress(c.data,s.tileCompression),cacheControl:c.cacheControl,expires:c.expires}}a=s.leafDirectoryOffset+u.offset,l=u.length}else return}throw new Error("Maximum directory depth exceeded")})}getZxy(e,r,n,i){return b(this,null,function*(){try{return yield this.getZxyAttempt(e,r,n,i)}catch(o){if(o instanceof Q)return this.cache.invalidate(this.source),yield this.getZxyAttempt(e,r,n,i);throw o}})}getMetadataAttempt(){return b(this,null,function*(){let e=yield this.cache.getHeader(this.source),r=yield this.source.getBytes(e.jsonMetadataOffset,e.jsonMetadataLength,void 0,e.etag),n=yield this.decompress(r.data,e.internalCompression),i=new TextDecoder("utf-8");return JSON.parse(i.decode(n))})}getMetadata(){return b(this,null,function*(){try{return yield this.getMetadataAttempt()}catch(e){if(e instanceof Q)return this.cache.invalidate(this.source),yield this.getMetadataAttempt();throw e}})}getTileJson(e){return b(this,null,function*(){let r=yield this.getHeader(),n=yield this.getMetadata(),i=X(r.tileType);return{tilejson:"3.0.0",scheme:"xyz",tiles:[`${e}/{z}/{x}/{y}${i}`],vector_layers:n.vector_layers,attribution:n.attribution,description:n.description,name:n.name,version:n.version,bounds:[r.minLon,r.minLat,r.maxLon,r.maxLat],center:[r.centerLon,r.centerLat,r.centerZoom],minzoom:r.minZoom,maxzoom:r.maxZoom}})}};d(lt,"PMTiles");var ne=lt;var ut=(t,e)=>e?e.replaceAll("{name}",t):t+".pmtiles",Wr=/^\/(?[0-9a-zA-Z\/!\-_\.\*\'\(\)]+)\/(?\d+)\/(?\d+)\/(?\d+).(?[a-z]+)$/,Vr=/^\/(?[0-9a-zA-Z\/!\-_\.\*\'\(\)]+).json$/,ct=t=>{let e=t.match(Wr);if(e){let n=e.groups;return{ok:!0,name:n.NAME,tile:[+n.Z,+n.X,+n.Y],ext:n.EXT}}let r=t.match(Vr);return r?{ok:!0,name:r.groups.NAME,ext:"json"}:{ok:!1,name:"",tile:[0,0,0],ext:""}};var nr=require("crypto"),ze=Be(require("zlib")),ce=require("@aws-sdk/client-s3"),ir=Be(rr()),ri=new ce.S3Client({requestHandler:new ir.NodeHttpHandler({connectionTimeout:500,socketTimeout:500})});async function or(t,e){if(e===Y.None||e===Y.Unknown)return t;if(e===Y.Gzip)return ze.default.gunzipSync(t);throw new Error("Compression method not supported")}var ni=new st(void 0,void 0,or),Se=class{constructor(e){this.archiveName=e}getKey(){return this.archiveName}async getBytes(e,r,n,i){let o;try{o=await ri.send(new ce.GetObjectCommand({Bucket:process.env.BUCKET,Key:ut(this.archiveName,process.env.PMTILES_PATH),Range:"bytes="+e+"-"+(e+r-1),IfMatch:i,RequestPayer:"requester"}))}catch(a){throw a instanceof Error&&a.name==="PreconditionFailed"?new Q:a}let s=await o.Body?.transformToByteArray();if(!s)throw new Error("Failed to read S3 response body");return{data:s.buffer,etag:o.ETag,expires:o.Expires?.toISOString(),cacheControl:o.CacheControl}}},U=(t,e,r=!1,n={})=>({statusCode:t,body:e,headers:n,isBase64Encoded:r}),sr=async(t,e,r)=>{let n,i=!1;if(t.pathParameters)if(i=!0,t.pathParameters.proxy)n=`/${t.pathParameters.proxy}`;else return U(500,"Proxy integration missing tile_path parameter");else n=t.rawPath;if(!n)return U(500,"Invalid event configuration");let o={};process.env.CORS&&(o["Access-Control-Allow-Origin"]=process.env.CORS);let{ok:s,name:a,tile:l,ext:h}=ct(n);if(!s)return U(400,"Invalid tile URL",!1,o);let f=new Se(a),u=new ne(f,ni,or);try{let c=await u.getHeader();if(!l){if(!(process.env.PUBLIC_HOSTNAME||t.headers["x-distribution-domain-name"]))return U(501,"PUBLIC_HOSTNAME must be set for TileJSON",!1,o);o["Content-Type"]="application/json";let w=await u.getTileJson(`https://${process.env.PUBLIC_HOSTNAME||t.headers["x-distribution-domain-name"]||""}/${a}`);return U(200,JSON.stringify(w),!1,o)}if(l[0]c.maxZoom)return U(404,"",!1,o);let T={mvt:z.Mvt,pbf:z.Mvt,png:z.Png,jpg:z.Jpeg,webp:z.Webp,avif:z.Avif}[h];if(c.tileType!==T&&X(c.tileType)!=="")return U(400,`Bad request: requested .${h} but archive has type ${X(c.tileType)}`,!1,o);let m=await u.getZxy(l[0],l[1],l[2]);if(m){switch(c.tileType){case z.Mvt:o["Content-Type"]="application/vnd.mapbox-vector-tile";break;case z.Png:o["Content-Type"]="image/png";break;case z.Jpeg:o["Content-Type"]="image/jpeg";break;case z.Webp:o["Content-Type"]="image/webp";break;case z.Avif:o["Content-Type"]="image/avif";break}let w=m.data;if(r&&(w=r(w,c.tileType)),o["Cache-Control"]=process.env.CACHE_CONTROL||"public, max-age=86400",o.ETag=`"${(0,nr.createHash)("sha256").update(Buffer.from(w)).digest("hex")}"`,i){let H=ze.default.gzipSync(w);return o["Content-Encoding"]="gzip",U(200,Buffer.from(H).toString("base64"),!0,o)}return U(200,Buffer.from(w).toString("base64"),!0,o)}return U(204,"",!1,o)}catch(c){if(c.name==="AccessDenied")return U(403,"Bucket access unauthorized",!1,o);throw c}},ii=async(t,e)=>await sr(t,e);0&&(module.exports={handler,handlerRaw});