diff --git a/notebook/chla.html b/notebook/chla.html
new file mode 100644
index 0000000..a26d1d8
--- /dev/null
+++ b/notebook/chla.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="UTF-8">
+<title>PACE Chlorophyll-a</title>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
+<link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css"/>
+<style>.layer-switcher-ctrl{background-color:#fff}.layer-switcher-ctrl a{background-color:#fff;_color:#404040;color:#a9a9a9;display:block;margin:0;padding:5px 10px;text-decoration:none;border-bottom:1px solid black;text-align:center}.layer-switcher-ctrl a:hover{background-color:#f8f8f8;color:#404040}.layer-switcher-ctrl a.active{background-color:#3887be;color:#fff}.layer-switcher-ctrl a.active:hover{background:#3074a4}.layer-switcher-ctrl-simple{background-color:#fff}.layer-switcher-ctrl-simple a{background-color:#fff;color:#a9a9a9;display:block;margin:0;padding:5px 10px;text-decoration:none;border-bottom:1px solid black;text-align:center}.layer-switcher-ctrl-simple a:hover{background-color:#f8f8f8;color:#404040}.layer-switcher-ctrl-simple a.active{color:#404040}.layer-switcher-ctrl-simple a.active:hover{_background:#3074a4;color:#a9a9a9}
+html, body {height: 100%; margin: 0; padding: 0;} #pymaplibregl {width: 100%; height: 100%;}
+</style>
+<body>
+<div id="pymaplibregl"></div>
+<script>
+(()=>{var H=Math.pow,w=(t,e,r)=>new Promise((n,i)=>{var o=c=>{try{s(r.next(c))}catch(u){i(u)}},a=c=>{try{s(r.throw(c))}catch(u){i(u)}},s=c=>c.done?n(c.value):Promise.resolve(c.value).then(o,a);s((r=r.apply(t,e)).next())}),k=Uint8Array,I=Uint16Array,Xe=Int32Array,Ee=new k([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]),Me=new k([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]),Ye=new k([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Te=function(t,e){for(var r=new I(31),n=0;n<31;++n)r[n]=e+=1<<t[n-1];for(var i=new Xe(r[30]),n=1;n<30;++n)for(var o=r[n];o<r[n+1];++o)i[o]=o-r[n]<<5|n;return{b:r,r:i}},Se=Te(Ee,2),Oe=Se.b,Qe=Se.r;Oe[28]=258,Qe[258]=28;var Pe=Te(Me,0),et=Pe.b,rr=Pe.r,le=new I(32768);for(p=0;p<32768;++p)P=(p&43690)>>1|(p&21845)<<1,P=(P&52428)>>2|(P&13107)<<2,P=(P&61680)>>4|(P&3855)<<4,le[p]=((P&65280)>>8|(P&255)<<8)>>1;var P,p,F=function(t,e,r){for(var n=t.length,i=0,o=new I(e);i<n;++i)t[i]&&++o[t[i]-1];var a=new I(e);for(i=1;i<e;++i)a[i]=a[i-1]+o[i-1]<<1;var s;if(r){s=new I(1<<e);var c=15-e;for(i=0;i<n;++i)if(t[i])for(var u=i<<4|t[i],l=e-t[i],f=a[t[i]-1]++<<l,h=f|(1<<l)-1;f<=h;++f)s[le[f]>>c]=u}else for(s=new I(n),i=0;i<n;++i)t[i]&&(s[i]=le[a[t[i]-1]++]>>15-t[i]);return s},J=new k(288);for(p=0;p<144;++p)J[p]=8;var p;for(p=144;p<256;++p)J[p]=9;var p;for(p=256;p<280;++p)J[p]=7;var p;for(p=280;p<288;++p)J[p]=8;var p,Ae=new k(32);for(p=0;p<32;++p)Ae[p]=5;var p,tt=F(J,9,1),rt=F(Ae,5,1),se=function(t){for(var e=t[0],r=1;r<t.length;++r)t[r]>e&&(e=t[r]);return e},T=function(t,e,r){var n=e/8|0;return(t[n]|t[n+1]<<8)>>(e&7)&r},ce=function(t,e){var r=e/8|0;return(t[r]|t[r+1]<<8|t[r+2]<<16)>>(e&7)},nt=function(t){return(t+7)/8|0},it=function(t,e,r){(e==null||e<0)&&(e=0),(r==null||r>t.length)&&(r=t.length);var n=new k(r-e);return n.set(t.subarray(e,r)),n},ot=["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||ot[t]);if(n.code=t,Error.captureStackTrace&&Error.captureStackTrace(n,_),!r)throw n;return n},he=function(t,e,r,n){var i=t.length,o=n?n.length:0;if(!i||e.f&&!e.l)return r||new k(0);var a=!r||e.i!=2,s=e.i;r||(r=new k(i*3));var c=function(De){var _e=r.length;if(De>_e){var Le=new k(Math.max(_e*2,De));Le.set(r),r=Le}},u=e.f||0,l=e.p||0,f=e.b||0,h=e.l,v=e.d,m=e.m,g=e.n,b=i*8;do{if(!h){u=T(t,l,1);var y=T(t,l+1,3);if(l+=3,y)if(y==1)h=tt,v=rt,m=9,g=5;else if(y==2){var E=T(t,l,31)+257,R=T(t,l+10,15)+4,Q=E+T(t,l+5,31)+1;l+=14;for(var x=new k(Q),re=new k(19),U=0;U<R;++U)re[Ye[U]]=T(t,l+U*3,7);l+=R*3;for(var ye=se(re),We=(1<<ye)-1,Fe=F(re,ye,1),U=0;U<Q;){var me=Fe[T(t,l,We)];l+=me&15;var d=me>>4;if(d<16)x[U++]=d;else{var $=0,ee=0;for(d==16?(ee=3+T(t,l,3),l+=2,$=x[U-1]):d==17?(ee=3+T(t,l,7),l+=3):d==18&&(ee=11+T(t,l,127),l+=7);ee--;)x[U++]=$}}var we=x.subarray(0,E),M=x.subarray(E);m=se(we),g=se(M),h=F(we,m,1),v=F(M,g,1)}else _(1);else{var d=nt(l)+4,O=t[d-4]|t[d-3]<<8,A=d+O;if(A>i){s&&_(0);break}a&&c(f+O),r.set(t.subarray(d,A),f),e.b=f+=O,e.p=l=A*8,e.f=u;continue}if(l>b){s&&_(0);break}}a&&c(f+131072);for(var Je=(1<<m)-1,qe=(1<<g)-1,ne=l;;ne=l){var $=h[ce(t,l)&Je],z=$>>4;if(l+=$&15,l>b){s&&_(0);break}if($||_(2),z<256)r[f++]=z;else if(z==256){ne=l,h=null;break}else{var be=z-254;if(z>264){var U=z-257,Z=Ee[U];be=T(t,l,(1<<Z)-1)+Oe[U],l+=Z}var ie=v[ce(t,l)&qe],oe=ie>>4;ie||_(3),l+=ie&15;var M=et[oe];if(oe>3){var Z=Me[oe];M+=ce(t,l)&(1<<Z)-1,l+=Z}if(l>b){s&&_(0);break}a&&c(f+131072);var ae=f+be;if(f<M){var xe=o-M,Ge=Math.min(M,ae);for(xe+f<0&&_(3);f<Ge;++f)r[f]=n[xe+f]}for(;f<ae;f+=4)r[f]=r[f-M],r[f+1]=r[f+1-M],r[f+2]=r[f+2-M],r[f+3]=r[f+3-M];f=ae}}e.l=h,e.p=ne,e.b=f,e.f=u,h&&(u=1,e.m=m,e.d=v,e.n=g)}while(!u);return f==r.length?r:it(r,0,f)},at=new k(0),st=function(t){(t[0]!=31||t[1]!=139||t[2]!=8)&&_(6,"invalid gzip data");var e=t[3],r=10;e&4&&(r+=(t[10]|t[11]<<8)+2);for(var n=(e>>3&1)+(e>>4&1);n>0;n-=!t[r++]);return r+(e&2)},ct=function(t){var e=t.length;return(t[e-4]|t[e-3]<<8|t[e-2]<<16|t[e-1]<<24)>>>0},lt=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 ut(t,e){return he(t,{i:2},e&&e.out,e&&e.dictionary)}function ft(t,e){var r=st(t);return r+8>t.length&&_(6,"invalid gzip data"),he(t.subarray(r,-8),{i:2},e&&e.out||new k(ct(t)),e&&e.dictionary)}function ht(t,e){return he(t.subarray(lt(t,e&&e.dictionary),-4),{i:2},e&&e.out,e&&e.dictionary)}function ue(t,e){return t[0]==31&&t[1]==139&&t[2]==8?ft(t,e):(t[0]&15)!=8||t[0]>>4>7||(t[0]<<8|t[1])%31?ut(t,e):ht(t,e)}var dt=typeof TextDecoder<"u"&&new TextDecoder,pt=0;try{dt.decode(at,{stream:!0}),pt=1}catch{}var Re=(t,e)=>t*H(2,e),j=(t,e)=>Math.floor(t/H(2,e)),te=(t,e)=>Re(t.getUint16(e+1,!0),8)+t.getUint8(e),$e=(t,e)=>Re(t.getUint32(e+2,!0),16)+t.getUint16(e,!0),gt=(t,e,r,n,i)=>{if(t!==n.getUint8(i))return t-n.getUint8(i);let o=te(n,i+1);if(e!==o)return e-o;let a=te(n,i+4);return r!==a?r-a:0},vt=(t,e,r,n)=>{let i=ze(t,e|128,r,n);return i?{z:e,x:r,y:n,offset:i[0],length:i[1],isDir:!0}:null},ke=(t,e,r,n)=>{let i=ze(t,e,r,n);return i?{z:e,x:r,y:n,offset:i[0],length:i[1],isDir:!1}:null},ze=(t,e,r,n)=>{let i=0,o=t.byteLength/17-1;for(;i<=o;){let a=o+i>>1,s=gt(e,r,n,t,a*17);if(s>0)i=a+1;else if(s<0)o=a-1;else return[$e(t,a*17+7),t.getUint32(a*17+13,!0)]}return null},yt=(t,e)=>t.isDir&&!e.isDir?1:!t.isDir&&e.isDir?-1:t.z!==e.z?t.z-e.z:t.x!==e.x?t.x-e.x:t.y-e.y,Be=(t,e)=>{let r=t.getUint8(e*17);return{z:r&127,x:te(t,e*17+1),y:te(t,e*17+4),offset:$e(t,e*17+7),length:t.getUint32(e*17+13,!0),isDir:r>>7===1}},Ue=t=>{let e=[],r=new DataView(t);for(let n=0;n<r.byteLength/17;n++)e.push(Be(r,n));return mt(e)},mt=t=>{t.sort(yt);let e=new ArrayBuffer(17*t.length),r=new Uint8Array(e);for(let n=0;n<t.length;n++){let i=t[n],o=i.z;i.isDir&&(o=o|128),r[n*17]=o,r[n*17+1]=i.x&255,r[n*17+2]=i.x>>8&255,r[n*17+3]=i.x>>16&255,r[n*17+4]=i.y&255,r[n*17+5]=i.y>>8&255,r[n*17+6]=i.y>>16&255,r[n*17+7]=i.offset&255,r[n*17+8]=j(i.offset,8)&255,r[n*17+9]=j(i.offset,16)&255,r[n*17+10]=j(i.offset,24)&255,r[n*17+11]=j(i.offset,32)&255,r[n*17+12]=j(i.offset,48)&255,r[n*17+13]=i.length&255,r[n*17+14]=i.length>>8&255,r[n*17+15]=i.length>>16&255,r[n*17+16]=i.length>>24&255}return e},wt=(t,e)=>{if(t.byteLength<17)return null;let r=t.byteLength/17,n=Be(t,r-1);if(n.isDir){let i=n.z,o=e.z-i,a=Math.trunc(e.x/(1<<o)),s=Math.trunc(e.y/(1<<o));return{z:i,x:a,y:s}}return null};function bt(t){return w(this,null,function*(){let e=yield t.getBytes(0,512e3),r=new DataView(e.data),n=r.getUint32(4,!0),i=r.getUint16(8,!0),o=new TextDecoder("utf-8"),a=JSON.parse(o.decode(new DataView(e.data,10,n))),s=0;a.compression==="gzip"&&(s=2);let c=0;"minzoom"in a&&(c=+a.minzoom);let u=0;"maxzoom"in a&&(u=+a.maxzoom);let l=0,f=0,h=0,v=-180,m=-85,g=180,b=85;if(a.bounds){let d=a.bounds.split(",");v=+d[0],m=+d[1],g=+d[2],b=+d[3]}if(a.center){let d=a.center.split(",");l=+d[0],f=+d[1],h=+d[2]}return{specVersion:r.getUint16(2,!0),rootDirectoryOffset:10+n,rootDirectoryLength:i*17,jsonMetadataOffset:10,jsonMetadataLength:n,leafDirectoryOffset:0,leafDirectoryLength:void 0,tileDataOffset:0,tileDataLength:void 0,numAddressedTiles:0,numTileEntries:0,numTileContents:0,clustered:!1,internalCompression:1,tileCompression:s,tileType:1,minZoom:c,maxZoom:u,minLon:v,minLat:m,maxLon:g,maxLat:b,centerZoom:h,centerLon:l,centerLat:f,etag:e.etag}})}function xt(t,e,r,n,i,o,a){return w(this,null,function*(){let s=yield r.getArrayBuffer(e,t.rootDirectoryOffset,t.rootDirectoryLength,t);t.specVersion===1&&(s=Ue(s));let c=ke(new DataView(s),n,i,o);if(c){let f=(yield e.getBytes(c.offset,c.length,a)).data,h=new DataView(f);return h.getUint8(0)===31&&h.getUint8(1)===139&&(f=ue(new Uint8Array(f))),{data:f}}let u=wt(new DataView(s),{z:n,x:i,y:o});if(u){let l=vt(new DataView(s),u.z,u.x,u.y);if(l){let f=yield r.getArrayBuffer(e,l.offset,l.length,t);t.specVersion===1&&(f=Ue(f));let h=ke(new DataView(f),n,i,o);if(h){let m=(yield e.getBytes(h.offset,h.length,a)).data,g=new DataView(m);return g.getUint8(0)===31&&g.getUint8(1)===139&&(m=ue(new Uint8Array(m))),{data:m}}}}})}var Ie={getHeader:bt,getZxy:xt};var Dt=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:()=>n.abort()}},He=class{constructor(){this.tilev4=(t,e)=>w(this,null,function*(){if(t.type==="json"){let f=t.url.substr(10),h=this.tiles.get(f);h||(h=new Ce(f),this.tiles.set(f,h));let v=yield h.getHeader();return{data:{tiles:[`${t.url}/{z}/{x}/{y}`],minzoom:v.minZoom,maxzoom:v.maxZoom,bounds:[v.minLon,v.minLat,v.maxLon,v.maxLat]}}}let r=new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/),n=t.url.match(r);if(!n)throw new Error("Invalid PMTiles protocol URL");let i=n[1],o=this.tiles.get(i);o||(o=new Ce(i),this.tiles.set(i,o));let a=n[2],s=n[3],c=n[4],u=yield o.getHeader(),l=yield o?.getZxy(+a,+s,+c,e.signal);return l?{data:new Uint8Array(l.data),cacheControl:l.cacheControl,expires:l.expires}:u.tileType===1?{data:new Uint8Array}:{data:null}}),this.tile=Dt(this.tilev4),this.tiles=new Map}add(t){this.tiles.set(t.source.getKey(),t)}get(t){return this.tiles.get(t)}};function B(t,e){return(e>>>0)*4294967296+(t>>>0)}function _t(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 B(t,i);throw new Error("Expected varint not more than 10 bytes")}function W(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,_t(n,t))}function Lt(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}}var kt=[0,1,5,21,85,341,1365,5461,21845,87381,349525,1398101,5592405,22369621,89478485,357913941,1431655765,5726623061,22906492245,91625968981,366503875925,1466015503701,5864062014805,23456248059221,93824992236885,375299968947541,0x5555555555555];function Ut(t,e,r){if(t>26)throw Error("Tile zoom level exceeds max safe number limit (26)");if(e>H(2,t)-1||r>H(2,t)-1)throw Error("tile x/y outside zoom level bounds");let n=kt[t],i=H(2,t),o=0,a=0,s=0,c=[e,r],u=i/2;for(;u>0;)o=(c[0]&u)>0?1:0,a=(c[1]&u)>0?1:0,s+=u*u*(3*o^a),Lt(u,c,o,a),u=u/2;return n+s}function Ve(t,e){return w(this,null,function*(){if(e===1||e===0)return t;if(e===2){if(typeof globalThis.DecompressionStream>"u")return ue(new Uint8Array(t));let r=new Response(t).body;if(!r)throw Error("Failed to read response stream");let n=r.pipeThrough(new globalThis.DecompressionStream("gzip"));return new Response(n).arrayBuffer()}throw Error("Compression method not supported")})}var Ct=127;function Et(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<t[n].runLength)?t[n]:null}var Mt=class{constructor(t,e=new Headers){this.url=t,this.customHeaders=e,this.mustReload=!1}getKey(){return this.url}setHeaders(t){this.customHeaders=t}getBytes(t,e,r,n){return w(this,null,function*(){let i,o;r?o=r:(i=new AbortController,o=i.signal);let a=new Headers(this.customHeaders);a.set("range",`bytes=${t}-${t+e-1}`);let s;this.mustReload&&(s="reload");let c=yield fetch(this.url,{signal:o,cache:s,headers:a});if(t===0&&c.status===416){let h=c.headers.get("Content-Range");if(!h||!h.startsWith("bytes */"))throw Error("Missing content-length on 416 response");let v=+h.substr(8);c=yield fetch(this.url,{signal:o,cache:"reload",headers:{range:`bytes=0-${v-1}`}})}let u=c.headers.get("Etag");if(u?.startsWith("W/")&&(u=null),c.status===416||n&&u&&u!==n)throw this.mustReload=!0,new fe(n);if(c.status>=300)throw Error(`Bad response code: ${c.status}`);let l=c.headers.get("Content-Length");if(c.status===200&&(!l||+l>e))throw i&&i.abort(),Error("Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving.");return{data:yield c.arrayBuffer(),etag:u||void 0,cacheControl:c.headers.get("Cache-Control")||void 0,expires:c.headers.get("Expires")||void 0}})}};function S(t,e){let r=t.getUint32(e+4,!0),n=t.getUint32(e+0,!0);return r*H(2,32)+n}function Tt(t,e){let r=new DataView(t),n=r.getUint8(7);if(n>3)throw Error(`Archive is spec version ${n} but this library supports up to spec version 3`);return{specVersion:n,rootDirectoryOffset:S(r,8),rootDirectoryLength:S(r,16),jsonMetadataOffset:S(r,24),jsonMetadataLength:S(r,32),leafDirectoryOffset:S(r,40),leafDirectoryLength:S(r,48),tileDataOffset:S(r,56),tileDataLength:S(r,64),numAddressedTiles:S(r,72),numTileEntries:S(r,80),numTileContents:S(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}}function Ne(t){let e={buf:new Uint8Array(t),pos:0},r=W(e),n=[],i=0;for(let o=0;o<r;o++){let a=W(e);n.push({tileId:i+a,offset:0,length:0,runLength:1}),i+=a}for(let o=0;o<r;o++)n[o].runLength=W(e);for(let o=0;o<r;o++)n[o].length=W(e);for(let o=0;o<r;o++){let a=W(e);a===0&&o>0?n[o].offset=n[o-1].offset+n[o-1].length:n[o].offset=a-1}return n}function St(t){let e=new DataView(t);return e.getUint16(2,!0)===2?(console.warn("PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"),2):e.getUint16(2,!0)===1?(console.warn("PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"),1):3}var fe=class extends Error{};function Ot(t,e){return w(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");if(St(r.data)<3)return[yield Ie.getHeader(t)];let i=r.data.slice(0,Ct),o=Tt(i,r.etag),a=r.data.slice(o.rootDirectoryOffset,o.rootDirectoryOffset+o.rootDirectoryLength),s=`${t.getKey()}|${o.etag||""}|${o.rootDirectoryOffset}|${o.rootDirectoryLength}`,c=Ne(yield e(a,o.internalCompression));return[o,[s,c.length,c]]})}function Pt(t,e,r,n,i){return w(this,null,function*(){let o=yield t.getBytes(r,n,void 0,i.etag),a=yield e(o.data,i.internalCompression),s=Ne(a);if(s.length===0)throw new Error("Empty directory is invalid");return s})}var At=class{constructor(t=100,e=!0,r=Ve){this.cache=new Map,this.invalidations=new Map,this.maxCacheEntries=t,this.counter=1,this.decompress=r}getHeader(t){return w(this,null,function*(){let e=t.getKey(),r=this.cache.get(e);if(r)return r.lastUsed=this.counter++,yield r.data;let n=new Promise((i,o)=>{Ot(t,this.decompress).then(a=>{a[1]&&this.cache.set(a[1][0],{lastUsed:this.counter++,data:Promise.resolve(a[1][2])}),i(a[0]),this.prune()}).catch(a=>{o(a)})});return this.cache.set(e,{lastUsed:this.counter++,data:n}),n})}getDirectory(t,e,r,n){return w(this,null,function*(){let i=`${t.getKey()}|${n.etag||""}|${e}|${r}`,o=this.cache.get(i);if(o)return o.lastUsed=this.counter++,yield o.data;let a=new Promise((s,c)=>{Pt(t,this.decompress,e,r,n).then(u=>{s(u),this.prune()}).catch(u=>{c(u)})});return this.cache.set(i,{lastUsed:this.counter++,data:a}),a})}getArrayBuffer(t,e,r,n){return w(this,null,function*(){let i=`${t.getKey()}|${n.etag||""}|${e}|${r}`,o=this.cache.get(i);if(o)return o.lastUsed=this.counter++,yield o.data;let a=new Promise((s,c)=>{t.getBytes(e,r,void 0,n.etag).then(u=>{s(u.data),this.cache.has(i),this.prune()}).catch(u=>{c(u)})});return this.cache.set(i,{lastUsed:this.counter++,data:a}),a})}prune(){if(this.cache.size>=this.maxCacheEntries){let t=1/0,e;this.cache.forEach((r,n)=>{r.lastUsed<t&&(t=r.lastUsed,e=n)}),e&&this.cache.delete(e)}}invalidate(t){return w(this,null,function*(){let e=t.getKey();if(this.invalidations.get(e))return yield this.invalidations.get(e);this.cache.delete(t.getKey());let r=new Promise((n,i)=>{this.getHeader(t).then(o=>{n(),this.invalidations.delete(e)}).catch(o=>{i(o)})});this.invalidations.set(e,r)})}},Ce=class{constructor(t,e,r){typeof t=="string"?this.source=new Mt(t):this.source=t,r?this.decompress=r:this.decompress=Ve,e?this.cache=e:this.cache=new At}getHeader(){return w(this,null,function*(){return yield this.cache.getHeader(this.source)})}getZxyAttempt(t,e,r,n){return w(this,null,function*(){let i=Ut(t,e,r),o=yield this.cache.getHeader(this.source);if(o.specVersion<3)return Ie.getZxy(o,this.source,this.cache,t,e,r,n);if(t<o.minZoom||t>o.maxZoom)return;let a=o.rootDirectoryOffset,s=o.rootDirectoryLength;for(let c=0;c<=3;c++){let u=yield this.cache.getDirectory(this.source,a,s,o),l=Et(u,i);if(l){if(l.runLength>0){let f=yield this.source.getBytes(o.tileDataOffset+l.offset,l.length,n,o.etag);return{data:yield this.decompress(f.data,o.tileCompression),cacheControl:f.cacheControl,expires:f.expires}}a=o.leafDirectoryOffset+l.offset,s=l.length}else return}throw Error("Maximum directory depth exceeded")})}getZxy(t,e,r,n){return w(this,null,function*(){try{return yield this.getZxyAttempt(t,e,r,n)}catch(i){if(i instanceof fe)return this.cache.invalidate(this.source),yield this.getZxyAttempt(t,e,r,n);throw i}})}getMetadataAttempt(){return w(this,null,function*(){let t=yield this.cache.getHeader(this.source),e=yield this.source.getBytes(t.jsonMetadataOffset,t.jsonMetadataLength,void 0,t.etag),r=yield this.decompress(e.data,t.internalCompression),n=new TextDecoder("utf-8");return JSON.parse(n.decode(r))})}getMetadata(){return w(this,null,function*(){try{return yield this.getMetadataAttempt()}catch(t){if(t instanceof fe)return this.cache.invalidate(this.source),yield this.getMetadataAttempt();throw t}})}};var q=class{constructor(e){this._options=e||{}}onAdd(e){return this._map=e,this._container=document.createElement("div"),this._container.className="maplibregl-ctrl maplibregl-ctrl-group",this._container.style.cssText=this._options.cssText||"padding: 10px;",this._container.innerHTML=this._options.content||"We out here.",this._container}onRemove(){this._container.parentNode.removeChild(this._container),this._map=void 0}};var Rt={default:"layer-switcher-ctrl",simple:"layer-switcher-ctrl-simple"};function $t(t,e){let r=document.createElement("div");r.id="layer-switcher-menu";for(let n of t){let i=document.createElement("a");i.id=n,i.href="#",i.textContent=n;let o=e.getLayoutProperty(n,"visibility");(typeof o>"u"||o==="visible")&&(i.className="active"),i.onclick=function(a){let s=this.textContent,c=e.getLayoutProperty(s,"visibility");if(console.log(s,c),typeof c>"u"||c==="visible"){e.setLayoutProperty(s,"visibility","none"),this.className="";return}e.setLayoutProperty(s,"visibility","visible"),this.className="active"},r.appendChild(i)}return r}var G=class{constructor(e){this._options=e}onAdd(e){this._map=e,this._container=document.createElement("div"),this._container.classList.add("maplibregl-ctrl"),this._container.classList.add(Rt[this._options.theme||"default"]),this._container.style.cssText=this._options.cssText||"";let r=this._options.layerIds;return this._container.appendChild($t(r,e)),this._container}onRemove(){this._container.parentNode.removeChild(this._container),this._map=void 0}getDefaultPosition(){return"top-left"}};var zt=Object.prototype.toString,N=Array.isArray||function(e){return zt.call(e)==="[object Array]"};function pe(t){return typeof t=="function"}function Bt(t){return N(t)?"array":typeof t}function de(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function Ke(t,e){return t!=null&&typeof t=="object"&&e in t}function It(t,e){return t!=null&&typeof t!="object"&&t.hasOwnProperty&&t.hasOwnProperty(e)}var Ht=RegExp.prototype.test;function Vt(t,e){return Ht.call(t,e)}var Nt=/\S/;function Kt(t){return!Vt(Nt,t)}var Zt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function jt(t){return String(t).replace(/[&<>"'`=\/]/g,function(r){return Zt[r]})}var Wt=/\s*/,Ft=/\s+/,Ze=/\s*=/,Jt=/\s*\}/,qt=/#|\^|\/|>|\{|&|=|!/;function Gt(t,e){if(!t)return[];var r=!1,n=[],i=[],o=[],a=!1,s=!1,c="",u=0;function l(){if(a&&!s)for(;o.length;)delete i[o.pop()];else o=[];a=!1,s=!1}var f,h,v;function m(x){if(typeof x=="string"&&(x=x.split(Ft,2)),!N(x)||x.length!==2)throw new Error("Invalid tags: "+x);f=new RegExp(de(x[0])+"\\s*"),h=new RegExp("\\s*"+de(x[1])),v=new RegExp("\\s*"+de("}"+x[1]))}m(e||C.tags);for(var g=new Y(t),b,y,d,O,A,E;!g.eos();){if(b=g.pos,d=g.scanUntil(f),d)for(var R=0,Q=d.length;R<Q;++R)O=d.charAt(R),Kt(O)?(o.push(i.length),c+=O):(s=!0,r=!0,c+=" "),i.push(["text",O,b,b+1]),b+=1,O===`
+`&&(l(),c="",u=0,r=!1);if(!g.scan(f))break;if(a=!0,y=g.scan(qt)||"name",g.scan(Wt),y==="="?(d=g.scanUntil(Ze),g.scan(Ze),g.scanUntil(h)):y==="{"?(d=g.scanUntil(v),g.scan(Jt),g.scanUntil(h),y="&"):d=g.scanUntil(h),!g.scan(h))throw new Error("Unclosed tag at "+g.pos);if(y==">"?A=[y,d,b,g.pos,c,u,r]:A=[y,d,b,g.pos],u++,i.push(A),y==="#"||y==="^")n.push(A);else if(y==="/"){if(E=n.pop(),!E)throw new Error('Unopened section "'+d+'" at '+b);if(E[1]!==d)throw new Error('Unclosed section "'+E[1]+'" at '+b)}else y==="name"||y==="{"||y==="&"?s=!0:y==="="&&m(d)}if(l(),E=n.pop(),E)throw new Error('Unclosed section "'+E[1]+'" at '+g.pos);return Yt(Xt(i))}function Xt(t){for(var e=[],r,n,i=0,o=t.length;i<o;++i)r=t[i],r&&(r[0]==="text"&&n&&n[0]==="text"?(n[1]+=r[1],n[3]=r[3]):(e.push(r),n=r));return e}function Yt(t){for(var e=[],r=e,n=[],i,o,a=0,s=t.length;a<s;++a)switch(i=t[a],i[0]){case"#":case"^":r.push(i),n.push(i),r=i[4]=[];break;case"/":o=n.pop(),o[5]=i[2],r=n.length>0?n[n.length-1][4]:e;break;default:r.push(i)}return e}function Y(t){this.string=t,this.tail=t,this.pos=0}Y.prototype.eos=function(){return this.tail===""};Y.prototype.scan=function(e){var r=this.tail.match(e);if(!r||r.index!==0)return"";var n=r[0];return this.tail=this.tail.substring(n.length),this.pos+=n.length,n};Y.prototype.scanUntil=function(e){var r=this.tail.search(e),n;switch(r){case-1:n=this.tail,this.tail="";break;case 0:n="";break;default:n=this.tail.substring(0,r),this.tail=this.tail.substring(r)}return this.pos+=n.length,n};function V(t,e){this.view=t,this.cache={".":this.view},this.parent=e}V.prototype.push=function(e){return new V(e,this)};V.prototype.lookup=function(e){var r=this.cache,n;if(r.hasOwnProperty(e))n=r[e];else{for(var i=this,o,a,s,c=!1;i;){if(e.indexOf(".")>0)for(o=i.view,a=e.split("."),s=0;o!=null&&s<a.length;)s===a.length-1&&(c=Ke(o,a[s])||It(o,a[s])),o=o[a[s++]];else o=i.view[e],c=Ke(i.view,e);if(c){n=o;break}i=i.parent}r[e]=n}return pe(n)&&(n=n.call(this.view)),n};function D(){this.templateCache={_cache:{},set:function(e,r){this._cache[e]=r},get:function(e){return this._cache[e]},clear:function(){this._cache={}}}}D.prototype.clearCache=function(){typeof this.templateCache<"u"&&this.templateCache.clear()};D.prototype.parse=function(e,r){var n=this.templateCache,i=e+":"+(r||C.tags).join(":"),o=typeof n<"u",a=o?n.get(i):void 0;return a==null&&(a=Gt(e,r),o&&n.set(i,a)),a};D.prototype.render=function(e,r,n,i){var o=this.getConfigTags(i),a=this.parse(e,o),s=r instanceof V?r:new V(r,void 0);return this.renderTokens(a,s,n,e,i)};D.prototype.renderTokens=function(e,r,n,i,o){for(var a="",s,c,u,l=0,f=e.length;l<f;++l)u=void 0,s=e[l],c=s[0],c==="#"?u=this.renderSection(s,r,n,i,o):c==="^"?u=this.renderInverted(s,r,n,i,o):c===">"?u=this.renderPartial(s,r,n,o):c==="&"?u=this.unescapedValue(s,r):c==="name"?u=this.escapedValue(s,r,o):c==="text"&&(u=this.rawValue(s)),u!==void 0&&(a+=u);return a};D.prototype.renderSection=function(e,r,n,i,o){var a=this,s="",c=r.lookup(e[1]);function u(h){return a.render(h,r,n,o)}if(c){if(N(c))for(var l=0,f=c.length;l<f;++l)s+=this.renderTokens(e[4],r.push(c[l]),n,i,o);else if(typeof c=="object"||typeof c=="string"||typeof c=="number")s+=this.renderTokens(e[4],r.push(c),n,i,o);else if(pe(c)){if(typeof i!="string")throw new Error("Cannot use higher-order sections without the original template");c=c.call(r.view,i.slice(e[3],e[5]),u),c!=null&&(s+=c)}else s+=this.renderTokens(e[4],r,n,i,o);return s}};D.prototype.renderInverted=function(e,r,n,i,o){var a=r.lookup(e[1]);if(!a||N(a)&&a.length===0)return this.renderTokens(e[4],r,n,i,o)};D.prototype.indentPartial=function(e,r,n){for(var i=r.replace(/[^ \t]/g,""),o=e.split(`
+`),a=0;a<o.length;a++)o[a].length&&(a>0||!n)&&(o[a]=i+o[a]);return o.join(`
+`)};D.prototype.renderPartial=function(e,r,n,i){if(n){var o=this.getConfigTags(i),a=pe(n)?n(e[1]):n[e[1]];if(a!=null){var s=e[6],c=e[5],u=e[4],l=a;c==0&&u&&(l=this.indentPartial(a,u,s));var f=this.parse(l,o);return this.renderTokens(f,r,n,l,i)}}};D.prototype.unescapedValue=function(e,r){var n=r.lookup(e[1]);if(n!=null)return n};D.prototype.escapedValue=function(e,r,n){var i=this.getConfigEscape(n)||C.escape,o=r.lookup(e[1]);if(o!=null)return typeof o=="number"&&i===C.escape?String(o):i(o)};D.prototype.rawValue=function(e){return e[1]};D.prototype.getConfigTags=function(e){return N(e)?e:e&&typeof e=="object"?e.tags:void 0};D.prototype.getConfigEscape=function(e){if(e&&typeof e=="object"&&!N(e))return e.escape};var C={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:void 0,escape:void 0,parse:void 0,render:void 0,Scanner:void 0,Context:void 0,Writer:void 0,set templateCache(t){X.templateCache=t},get templateCache(){return X.templateCache}},X=new D;C.clearCache=function(){return X.clearCache()};C.parse=function(e,r){return X.parse(e,r)};C.render=function(e,r,n,i){if(typeof e!="string")throw new TypeError('Invalid template! Template should be a "string" but "'+Bt(e)+'" was given as the first argument for mustache#render(template, view, partials)');return X.render(e,r,n,i)};C.escape=jt;C.Scanner=Y;C.Context=V;C.Writer=D;var ge=C;function ve(t,e,r){return r!==null?ge.render(r,t.properties):e===null?Object.keys(t.properties).map(i=>`${i}: ${t.properties[i]}`).join("</br>"):t.properties[e]}function je(t,e){let r=new maplibregl.Popup({closeOnClick:!1,closeButton:!1});return t.on("mouseout",n=>r.remove()),({coordinate:n,object:i})=>{i?(r.setHTML(ge.render(e,i)).setLngLat(n),r.addTo(t)):r.remove()}}var Qt=new He;maplibregl.addProtocol("pmtiles",Qt.tile);maplibregl.LayerSwitcherControl=G;maplibregl.InfoBoxControl=q;function er(){if(typeof deck>"u")return;let t=new deck.JSONConfiguration({classes:deck});return new deck.JSONConverter({configuration:t})}typeof MapboxDraw<"u"&&(MapboxDraw.constants.classes.CONTROL_BASE="maplibregl-ctrl",MapboxDraw.constants.classes.CONTROL_PREFIX="maplibregl-ctrl-",MapboxDraw.constants.classes.CONTROL_GROUP="maplibregl-ctrl-group");var K=class{constructor(e){this._id=e.container,this._map=new maplibregl.Map(e),this._map.on("mouseover",()=>{this._map.getCanvas().style.cursor="pointer"}),this._map.on("mouseout",()=>{this._map.getCanvas().style.cursor=""}),this._JSONConverter=er()}getMap(){return this._map}applyMapMethod(e,r){this._map[e](...r)}addControl(e,r,n){this._map.addControl(new maplibregl[e](r),n)}addMarker({lngLat:e,popup:r,options:n}){let i=new maplibregl.Marker(n).setLngLat(e);if(r){let o=new maplibregl.Popup(r.options).setHTML(r.text);i.setPopup(o)}i.addTo(this._map)}addLayer(e,r){this._map.addLayer(e,r),typeof Shiny<"u"&&this._map.on("click",e.id,n=>{console.log(n,n.features[0]);let i=e.id.replaceAll("-","_"),o=`${this._id}_layer_${i}`,a={props:n.features[0].properties,layer_id:e.id};console.log(o,a),Shiny.onInputChange(o,a)})}addPopup(e,r=null,n=null){let i={closeButton:!1},o=new maplibregl.Popup(i);this._map.on("click",e,a=>{let s=a.features[0],c=ve(s,r,n);o.setLngLat(a.lngLat).setHTML(c).addTo(this._map)})}addTooltip(e,r=null,n=null){let i={closeButton:!1,closeOnClick:!1},o=new maplibregl.Popup(i);this._map.on("mousemove",e,a=>{let s=a.features[0],c=ve(s,r,n);o.setLngLat(a.lngLat).setHTML(c).addTo(this._map)}),this._map.on("mouseleave",e,()=>{o.remove()})}setSourceData(e,r){this._map.getSource(e).setData(r)}addDeckOverlay(e,r=null){if(typeof this._JSONConverter>"u"){console.log("deck or JSONConverter is undefined");return}let n=this._convertDeckLayers(e,r);this._deckOverlay=new deck.MapboxOverlay({interleaved:!0,layers:n}),this._map.addControl(this._deckOverlay)}_convertDeckLayers(e,r=null){return e.map(n=>{let i=r&&typeof r=="object"?r[n.id]:r,o=je(this._map,i);return n.onHover=({layer:a,coordinate:s,object:c})=>{if(i&&o({coordinate:s,object:c}),typeof Shiny<"u"){let u=`${this._id}_layer_${n.id}`;Shiny.onInputChange(u,c)}},this._JSONConverter.convert(n)})}setDeckLayers(e,r=null){console.log("Updating Deck.GL layers");let n=this._convertDeckLayers(e,r);this._deckOverlay.setProps({layers:n})}addMapboxDraw(e,r,n=null){let i=new MapboxDraw(e);this._map.addControl(i,r),n&&i.add(n),typeof Shiny<"u"&&this._map.on("draw.selectionchange",o=>{let a=`${this._id}_draw_features_selected`,s={features:o.features,random:Math.random()};console.log(a,s),Shiny.onInputChange(a,s)})}render(e){e.forEach(([r,n])=>{if(["addLayer","addPopup","addTooltip","addMarker","addPopup","addControl","setSourceData","addDeckOverlay","setDeckLayers","addMapboxDraw"].includes(r)){console.log("Custom method",r,n),this[r](...n);return}console.log("Map method",r),this.applyMapMethod(r,n)})}};var tr="0.1.0";console.log("pymaplibregl",tr);typeof Shiny>"u"&&(window.pymaplibregl=function({mapOptions:t,calls:e}){let r="pymaplibregl",n=document.getElementById(r),i=new K(Object.assign({container:n.id},t));i.getMap().on("load",()=>{i.render(e)})});if(typeof Shiny<"u"){class t extends Shiny.OutputBinding{find(r){return r.find(".shiny-maplibregl-output")}renderValue(r,n){console.log("id:",r.id,"payload:",n);let i=window._maplibreWidget=new K(Object.assign({container:r.id},n.mapData.mapOptions)),o=i.getMap();o.on("load",()=>{i.render(n.mapData.calls)}),o.on("click",s=>{console.log(s);let c=`${r.id}`,u={coords:s.lngLat,point:s.point};console.log(c,u),Shiny.onInputChange(c,u)});let a=`pymaplibregl-${r.id}`;console.log(a),Shiny.addCustomMessageHandler(a,({id:s,calls:c})=>{console.log(s,c),i.render(c)})}}Shiny.outputBindings.register(new t,"shiny-maplibregl-output")}})();
+/*! Bundled license information:
+
+mustache/mustache.mjs:
+  (*!
+   * mustache.js - Logic-less {{mustache}} templates with JavaScript
+   * http://github.com/janl/mustache.js
+   *)
+*/
+
+// ...
+(() => {
+    var data = {"mapOptions": {"bearing": 0, "center": [0, 20], "pitch": 0, "style": {"version": 8, "sources": {"satellite": {"type": "raster", "tiles": ["https://api.maptiler.com/tiles/satellite-v2/{z}/{x}/{y}.jpg?key=zHkOvEKXRU94s1PSxs7w"], "tileSize": 256, "attribution": "&copy; MapTiler", "maxzoom": 19}, "terrainSource": {"type": "raster-dem", "url": "https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=zHkOvEKXRU94s1PSxs7w", "tileSize": 256}, "hillshadeSource": {"type": "raster-dem", "url": "https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=zHkOvEKXRU94s1PSxs7w", "tileSize": 256}}, "layers": [{"id": "satellite", "type": "raster", "source": "satellite"}, {"id": "hills", "type": "hillshade", "source": "hillshadeSource", "layout": {"visibility": "visible"}, "paint": {"hillshade-shadow-color": "#473B24"}}], "terrain": {"source": "terrainSource", "exaggeration": 1.0}}, "zoom": 1, "height": "600px"}, "calls": [["addControl", ["NavigationControl", {"showCompass": true, "showZoom": true, "visualizePitch": false}, "top-right"]], ["addControl", ["FullscreenControl", {}, "top-right"]], ["addControl", ["ScaleControl", {"unit": "metric"}, "bottom-left"]], ["addControl", ["InfoBoxControl", {"content": "<img src=\"data:image/png;base64,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\">", "cssText": "font-size: 20px; color: black;\n        font-weight: normal; padding: 5px;\n        background-color: white; border-radius: 5px;"}, "bottom-right"]], ["addControl", ["LayerSwitcherControl", {"layerIds": ["Chlorophyll-a"], "theme": "default", "cssText": "padding: 5px; border: 1px solid darkgrey; border-radius: 4px;"}, "top-left"]], ["addLayer", [{"id": "Chlorophyll-a", "type": "raster", "source": {"attribution": "", "tileSize": 256, "tiles": ["https://titiler.xyz/cog/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?colormap_name=jet&vmin=0&vmax=25&nodata=nan&url=https%3A%2F%2Fgithub.com%2Fopengeos%2Fpace-data%2Freleases%2Fdownload%2Fchla%2Flatest.tif&bidx=1&rescale=-1.458062767982483%2C0.5182958245277405"], "type": "raster"}}, null]], ["setLayoutProperty", ["Chlorophyll-a", "visibility", "visible"]], ["setPaintProperty", ["Chlorophyll-a", "raster-opacity", 1.0]], ["fitBounds", [[[-179.9999969495141, -90.00000457806081], [180.00001220830316, 89.99999694866628]]]]]};
+    pymaplibregl(data);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/notebook/chla.ipynb b/notebook/chla.ipynb
new file mode 100644
index 0000000..4806c68
--- /dev/null
+++ b/notebook/chla.ipynb
@@ -0,0 +1,49 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import leafmap.maplibregl as leafmap"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "m = leafmap.Map(style=\"3d-terrain\")\n",
+    "url = \"https://github.com/opengeos/pace-data/releases/download/chla/latest.tif\"\n",
+    "m.add_colorbar(cmap=\"jet\", vmin=0, vmax=25, label=\"Chlorophyll-a concentration (mg/m3)\")\n",
+    "m.add_layer_control(layer_ids=[\"Chlorophyll-a\"])\n",
+    "m.add_cog_layer(url, colormap_name=\"jet\", vmin=0, vmax=25, name=\"Chlorophyll-a\")\n",
+    "m.to_html(\"chla.html\", title=\"PACE Chlorophyll-a\")\n",
+    "m"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}