diff --git a/.gitignore b/.gitignore index 9f74371..f138f50 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,8 @@ scratch.ipynb # The built book -- never check into the repo. _build - +# Temporary files generated from notebooks +201/virtual_zarr/ # IPython & Jupyter profile_default/ diff --git a/101/BasicsShapeSize.ipynb b/101/BasicsShapeSize.ipynb new file mode 100644 index 0000000..a4a6269 --- /dev/null +++ b/101/BasicsShapeSize.ipynb @@ -0,0 +1,407 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# Basics of Chunk Shape and Size\n", + "\n", + "The goal of this notebook is to learn the basics about chunk shape and size.\n", + "We will discuss several factors to think about when deciding on chunk shape and size for datasets being written to storage.\n", + "These factors can effect the read pattern from storage and subsequently the computations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import fsspec" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Accessing the Example Dataset\n", + "\n", + "In this notebook, we will use the monthly PRISM v2 dataset as an example for understanding the effects of chunk shape and size.\n", + "Let's go ahead and read in the file using xarray.\n", + "To do this, we will use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) to get a mapper to the Zarr file the HyTEST OSN.\n", + "\n", + "```{note}\n", + "The xarray loader is \"lazy\", meaning it will read just enough of the data to make decisions about its shape, structure, etc.\n", + "It will pretend like the whole dataset is in memory (and we can treat it that way), but it will only load data as required.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem(\n", + " 's3',\n", + " anon=True, # anonymous = does not require credentials\n", + " client_kwargs={'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + ")\n", + "ds = xr.open_dataset(\n", + " fs.get_mapper('s3://mdmf/gdp/PRISM_v2.zarr/'),\n", + " engine='zarr'\n", + ")\n", + "ds" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Chunk Shape and Size\n", + "\n", + "Given what we know about this data, we can apply some storage principles to form a strategy for how best to chunk the data if we were to write it to storage (assuming it isn't already).\n", + "Broadly, we need to specify chunk shape and size.\n", + "\n", + "### Shape Considerations\n", + "\n", + "\"[**Chunk shape**](../back/Glossary.md#term-Chunk-shape)\" is the shape of a chunk, which specifies the number of elements in each dimension.\n", + "So, we will need to decide on the size of each of the dimensions of the chunks.\n", + "The preferred shape of each chunk will depend on the read pattern for future analyses.\n", + "Our goal is to chunk the data so that future reads will be performant, and that depends on whether the analyses favor one dimension or another.\n", + "For some datasets, this will be very apparent.\n", + "For example, streamflow gage data is very likely to be consumed along the `time` dimension.\n", + "So, a collection of data from multiple gages is _more likely_ to have the individual time series analyzed as opposed to analyzing all gages at a given time.\n", + "Therefore, we would want a chunk shape that is larger along the time dimension.\n", + "For datasets where there is no clear preference, we can try to chunk based on likely read patterns, but allow for other patterns without too much of a performance penalty. \n", + "\n", + "Let's see how we might do this for our example dataset.\n", + "Being this dataset spans space and time, it will likely be used in one of two dominant read patterns: \n", + "\n", + "* Time series for a given location (or small spatial extent)\n", + " * Special case: Is it likely that the time series will be subset by a logical unit (e.g., will this monthly data be consumed in blocks of 12 (i.e., yearly))? \n", + "* Full spatial extent for a given point in time. \n", + " * Special case: Are specific spatial regions more used than others? \n", + " \n", + "Let's look at a couple of options for space and time chunking:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Time Dimension\n", + "\n", + "As we can see above, the example dataset has 1512 monthly time steps. \n", + "How many chunks would we have if we chunked in groups of twelve (i.e., a year at a time)?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(f\"Number of chunks: {len(ds.time) // 12}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, a user could get an single year of this monthly data as a single chunk.\n", + "If they wanted a full time series across the entire dataset, they would need to read 126 chunks.\n", + "\n", + "So this is where the judgement call gets made: Which is the more likely read pattern for time: year-by-year, or the whole time series (or some sequence of a few years)?\n", + "For PRISM, it is more likely that someone will want more than just one year of data.\n", + "A happy medium for chunk shape along the time dimension could be 6 years of data per chunk." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "time_chunk_shape = 12 * 6\n", + "print(f\"Number of chunks: {len(ds.time) / time_chunk_shape}; Chunk of shape: {time_chunk_shape}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This pattern means only 21 chunks (instead of the 126 chunks we were considering a moment ago) are needed for a full time series in a given location." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Spatial Dimension\n", + "\n", + "As we can see in our example dataset, it techincally contains two spatial dimensions: `lat` and `lon`.\n", + "So, we're really chunking both of these dimensions when we talk about chunking with respect to space.\n", + "While we will consider them both together here, it is important to point out that they can have separate chunk shapes.\n", + "This leads to the the question of whether future users of this data will want strips of latitude or longitude, square \"tiles\" in space, or some proportionally-sized tiles of latitude and longitude? \n", + "That is, is it important that the North-South extent be broken into the same number of chunks as the East-West extent?\n", + "Let's start by chunking this into square tiles.\n", + "Being that there are more `lon` elements than `lat` elements, this means there will be more `lon` chunks than `lat` chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nlon = len(ds.lon)\n", + "nlat = len(ds.lat)\n", + "space_chunk_size = nlat // 4 # split the smaller of the two dimensions into 4 chunks\n", + "print(f\"Number of 'lon' chunks: {nlon / space_chunk_size}; Chunk of shape {space_chunk_size}\")\n", + "print(f\"Number of 'lat' chunks: {nlat / space_chunk_size}; Chunk of shape {space_chunk_size}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is important to note that we have just over a round number of chunks.\n", + "Having `9.06` longitude chunks means we will have 10 chunks in practice, but that last one is not full-sized.\n", + "In this case, this means that the last chunk in the given dimension will be extremely thin. \n", + "\n", + "In the case of the latitude chunks, the extra `0.006` of a chunk means that the last, fractional chunk (or [\"**partial chunk**\"](../back/Glossary.md#term-Partial-Chunk)) is only one `lat` observation.\n", + "(This occurred as `//` is floor division and `lat` does not have a number of elements divisible by 4.)\n", + "This all but guarantees that two chunks are needed for a small spatial extent near the \"end\" of the `lat` dimension.\n", + "\n", + "```{tip}\n", + "Ideally, we would want partial chunks to be at least half the size of the standard chunk.\n", + "The bigger that \"remainder\" fraction, the better. \n", + "```\n", + "\n", + "Let's adjust the chunk shape a little so that we don't have that sliver.\n", + "We're still committed to square tiles, so let's try a larger chunk shape to change the size of that last fraction.\n", + "Increasing the chunk size a little should get us bigger \"remainders\"." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space_chunk_size = 157\n", + "print(f\"Number of 'lon' chunks: {nlon / space_chunk_size}; Chunk of shape {space_chunk_size}\")\n", + "print(f\"Number of 'lat' chunks: {nlat / space_chunk_size}; Chunk of shape {space_chunk_size}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this pattern, the \"remainder\" latitude chunk will have a shape of 150 in the `lat` dimension, and the \"remainder\" longitude chunk will have a shape of 149 in the `lon` dimension.\n", + "All others will be a square 157 observations in both dimensions.\n", + "This amounts to a 9x4 chunk grid, with the last chunk in each dimension being partial. \n", + "\n", + "The entire spatial extent for a single time step can be read in 36 chunks with this chunk shape. \n", + "That seems a little high, given that this dataset will likely be taken at full spatial extent for a typical analysis. \n", + "Let's go a little bigger to see what that gets us:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "space_chunk_size = 354 # 157 * 2\n", + "print(f\"Number of 'lon' chunks: {nlon / space_chunk_size}; Chunk of shape {space_chunk_size}\")\n", + "print(f\"Number of 'lat' chunks: {nlat / space_chunk_size}; Chunk of shape {space_chunk_size}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is just as good in terms of full-chunk remainders, and the whole extent can be read in with only 8 chunks.\n", + "The smallest remainder is still >75% of a full-sized square tile, which is acceptable." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, we could stop being committed to square tiles and try and split the spatial regions more evenly.\n", + "For example, we could get as close to a 4x2 split as possible:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Add one to do a ceil divide\n", + "lon_space_chunk_size = nlon // 4 + 1\n", + "lat_space_chunk_size = nlat // 2 + 1\n", + "print(f\"Number of 'lon' chunks: {nlon / lon_space_chunk_size}; Chunk of shape {lon_space_chunk_size}\")\n", + "print(f\"Number of 'lat' chunks: {nlat / lat_space_chunk_size}; Chunk of shape {lat_space_chunk_size}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we could aim for a 3x3 split:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Add one to do a ceil divide\n", + "lon_space_chunk_size = nlon // 3 + 1\n", + "lat_space_chunk_size = nlat // 3 + 1\n", + "print(f\"Number of 'lon' chunks: {nlon / lon_space_chunk_size}; Chunk of shape {lon_space_chunk_size}\")\n", + "print(f\"Number of 'lat' chunks: {nlat / lat_space_chunk_size}; Chunk of shape {lat_space_chunk_size}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you might be getting, the chunking proportion between latitude and longitude is not super important.\n", + "What is important for basic chunk shape is the total number of chunks between the two and the minimization of the remainder in the final chunk of each dimension.\n", + "\n", + "```{note}\n", + "If we were really confident that most analyses wanted the full extent, we might be better off to just put the whole lat/lon dimensions into single chunks each.\n", + "This would ensure (and require) that we read the entire spatial extent.\n", + "However, our poor time-series analysis would then be stuck reading the entire dataset to get all time values for a single location.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Size Considerations\n", + "\n", + "Shape is only part of the equation.\n", + "Total \"[**chunk size**](../back/Glossary.md#term-Chunk-size)\" also matters.\n", + "Size considerations come into play mostly as a consideration of how the chunks are stored on disk.\n", + "The retrieval time is influenced by the size of each chunk.\n", + "Here are some constraints: \n", + "\n", + "* Files Too Big:\n", + " In a Zarr dataset, each chunk is stored as a separate binary file.\n", + " If we need data from a particular chunk, no matter how little or how much, that file gets opened, decompressed, and the whole thing read into memory.\n", + " A large chunk size means that there may be a lot of data transferred in situations when only a small subset of that chunk's data is actually needed.\n", + " It also means there might not be enough chunks to allow the dask workers to stay busy loading data in parallel.\n", + "\n", + "* Files Too Small:\n", + " If the chunk size is too small, the time it takes to read and decompress the data for each chunk can become comparable to the latency of S3 (typically 10-100ms).\n", + " We want the reads to take at least a second or so, so that the latency is not a significant part of the overall timing.\n", + "\n", + "```{tip}\n", + "As a general rule, aim for chunk sizes between 10 and 200 MB, depending on shape and expected read pattern of a user.\n", + "```\n", + "\n", + "#### Total Chunk Size\n", + "\n", + "To esimate the total chunk size, all we need is the expected chunk shape and data type to know how many bytes a value takes up.\n", + "As an example, let's use a chunk shape of `{'time': 72, 'lat': 354, 'lon': 354}`\n", + "This will tell us if we've hit our target of between 10 and 200 MB per chunk." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chunks = {'time': 72, 'lat': 354, 'lon': 354}\n", + "bytes_per_value = ds.tmn.dtype.itemsize\n", + "total_bytes = chunks['time'] * chunks['lat'] * chunks['lon'] * bytes_per_value\n", + "kiB = total_bytes / (2 ** 10)\n", + "MiB = kiB / (2 ** 10)\n", + "print(f\"TMN chunk size: {total_bytes} ({kiB=:.2f}) ({MiB=:.2f})\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We're looking really good for size, about 70 MiB.\n", + "This maybe even a bit low.\n", + "But we're in the (admitedly broad) range of 10-200 MiB of uncompressed data (i.e., in-memory) per chunk.\n", + "Therefore, this seems like it would be a reasonable chunk shape and size for our dataset.\n", + "If we were curious about other chunk shapes, like a non-square `lat` and `lon` chunk, we could repeat this computation to estimate its size and determine if it is reasonable.\n", + "However, we aren't going to do that here, but it is something you could try on your own if you are curious." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Review and Final Considerations\n", + "\n", + "Now that you have a general idea on how to pick chunk shape and size, let's review and add a few final considerations.\n", + "\n", + "### Basic Chunking Recommendations\n", + "\n", + "When determining the basic chunk shape and size, the choice will depend on the future read pattern and analysis.\n", + "If this pattern is unknown, then it is important to take a balanced chunking approach that does not favor one dimension over the others (i.e., larger overall shape in a given dimension).\n", + "Next, choosing a chunk shape should try to prevent partial chunks if possible.\n", + "Otherwise, partial chunks should be at least half the size of the standard chunk.\n", + "Finally, the total chunk size should be between 10 and 200 MiB for optimal performance.\n", + "\n", + "### Final Considerations\n", + "\n", + "One final thing to consider is that these basic recommendations assume that your chunked data will be static and not updated.\n", + "However, several datasets, especially climate related ones, will have their time dimesion updated.\n", + "These datasets are commonly updated at regular intervals (e.g., every year with the previous years data).\n", + "This can change the choice of chunk shape such that adding the next year's worth of data does not require rechunking the whole data set or result in small partial chunks.\n", + "For our PRISM example, if we chose a temporal chunk shape of length 72 (i.e., six years per chunk), adding a year worth of data would require appending the partial chunk until it becomes full.\n", + "Then, further new data would require starting a new partial chunk.\n", + "This could be prevented if we chose a chunk size of 12 (i.e., one year per chunk).\n", + "Then, additional data would only require making new chunks versus editing existing chunks.\n", + "Therefore, considering updates to the dataset when chunking can save a lot of time when appending the dataset in the future.\n", + "\n", + "Additionally, all of the information provided here does not discuss proper optimization of chunk shape and size.\n", + "Proper optimization would attempt to select chunk sizes that are near powers of two (i.e., $2^N$) to facilitate optimal storage and disk retrieval.\n", + "Details on this topic can be found in the advanced topic notebook of [Choosing an Optimal Chunk Size and Shape](../201/OptimalChunkSelection.ipynb)." + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/101/Compression.ipynb b/101/Compression.ipynb deleted file mode 100644 index 92c7fa5..0000000 --- a/101/Compression.ipynb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Assessing Compression\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "**OBJECTIVE**: \n", - "The objective of this chapter is to demonstrate how to read an existing dataset available as an OpenDAP endpoint, and translate it into a cloud-optimized zarr on S3. \n", - "\n", - "This notebook will evaluate how well the data is compressed when it is \n", - "written do disk. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Preamble\n", - "This is all stuff we are going to need: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import logging\n", - "\n", - "import numpy as np\n", - "import xarray as xr\n", - "import hvplot.xarray\n", - "import fsspec\n", - "import zarr\n", - "\n", - "logging.basicConfig(level=logging.INFO, force=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "%run ../utils.ipynb\n", - "_versions(['xarray', 'dask', 'zarr', 'fsspec'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## AWS Credentials\n", - "\n", - "We will use the same credentials scheme we used to write the data in \n", - "{doc}`OpenDAP_to_S3`. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "os.environ['AWS_PROFILE'] = 'osn-rsignellbucket2'\n", - "os.environ['AWS_ENDPOINT'] = 'https://renc.osn.xsede.org'\n", - "\n", - "%run ../AWS.ipynb # handles credentials for us. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The zarr store\n", - "\n", - "Let's look at the zarr data store we wrote to object storage" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# OUTPUT Location: \n", - "outdir = f's3://rsignellbucket2/testing/prism/PRISM2.zarr'\n", - "# established in earlier notebooks.\n", - "\n", - "fsw = fsspec.filesystem('s3', \n", - " anon=False, \n", - " default_fill_cache=False, \n", - " skip_instance_cache=True, \n", - " client_kwargs={ 'endpoint_url': os.environ['AWS_S3_ENDPOINT'] },\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The zarr store is actually a folder/directory, with subfolders for variables, groups, etc. \n", - "We can get a quick peek at that with a couple of zarr functions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g = zarr.convenience.open_consolidated(fsw.get_mapper(outdir)) # read zarr metadata for named file.\n", - "print(g.tree())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Sizing the chunks\n", - "\n", - "Using the filesystem utilities, build a datasets of file sizes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "flist = fsw.glob(f'{outdir}/tmx/*')\n", - "fsize = [fsw.size(f) for f in flist]\n", - "da = xr.DataArray(data=np.array(fsize)/1e6, name='size')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Plot a histogram of sizes for data files in this zarr store:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "da.hvplot.hist(title='Compressed object sizes (MB) for \"tmx\" variable', grid=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can see that most of the individual chunks are just over 4MB in size. Compare this with \n", - "the in-memory size for chunks, according to `xarray` -- 34MB per chunk. \n", - "\n", - "This tells us that we get an astonishing 9:1 compression ratio on this particular data. \n", - "\n", - "Let's look at another variable in this dataset:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "flist = fsw.glob(f'{outdir}/ppt/*')\n", - "fsize = [fsw.size(f) for f in flist]\n", - "da = xr.DataArray(data=np.array(fsize)/1e6, name='size')\n", - "da.hvplot.hist(title='Compressed object sizes (MB) for \"ppt\" variable', grid=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This variable did not compress quite as well. In the worse case, severl chunks are about\n", - "14MB each. This is still a respectable 2.5:1 compression ratio for this variable. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Total Size\n", - "The total size in GB of this dataset as stored on disk (including all metadata) is:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fsw.du(outdir)/1e9" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we count up the in-memory sizes reported by `xarray`: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "new_ds = xr.open_dataset(fsw.get_mapper(outdir), engine='zarr', chunks={})\n", - "total=0\n", - "for i in new_ds.variables:\n", - " n = new_ds[i].size\n", - " bytes = n * 4\n", - " total += bytes\n", - " print(f\"{i:10s}: {bytes: 12d}\")\n", - "print(\"=\" * 24, f\"\\nTOTAL : {total: 12d}\")\n", - "\n", - "print(f\"In GB: {total/1e9}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So... our total compression ratio for the entire dataset, including file system overhead and metadata is: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "total / fsw.du(outdir) " - ] - } - ], - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/101/EffectSizeShape.ipynb b/101/EffectSizeShape.ipynb deleted file mode 100644 index b68b067..0000000 --- a/101/EffectSizeShape.ipynb +++ /dev/null @@ -1,497 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Size and Shape of Chunks\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "**OBJECTIVE**: \n", - "The objective of this chapter is to demonstrate how to read an existing dataset available as an OpenDAP endpoint, and translate it into a cloud-optimized zarr on S3. \n", - "\n", - "This notebook will touch on chunking considerations -- Factors to think about when deciding how to break up the data into chunks/bites. And why you would want to do that to begin with. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import logging\n", - "import xarray as xr\n", - "logging.basicConfig(level=logging.INFO, force=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "%run ../utils.ipynb\n", - "_versions(['xarray'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Why Chunk\n", - "The simple reason is that the full dataset won't fit in memory. It has to be\n", - "divided in some way so that only those parts of the data being actively worked\n", - "are loaded. (See more in {doc}`WhyChunk`).\n", - "\n", - "This has other benefits when it comes to parallel algorithms. If work can be\n", - "performed in parallel, it is easy to set it up such that a separate worker is\n", - "assigned to each chunk of the data. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example Data\n", - "We're going to keep looking at the sample PRISM dataset, as read from \n", - "an OpenDAP endpoint: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# INPUT: \n", - "OPENDAP_url = 'https://cida.usgs.gov/thredds/dodsC/prism_v2'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ds_in = xr.open_dataset(OPENDAP_url, decode_times=False)\n", - "ds_in.tmn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Given what we know about this data, we can apply some cloud storage principles to form a strategy for how best to chunk the data when we write it to S3. Broadly, we need to specify chunk **size** and chunk **shape**. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Shape Considerations\n", - "\n", - "Shape refers to how to divide an array along each dimension. So we will need to decide on the chunk size for each of the dimensions of this data. \n", - "\n", - "The preferred shape of each chunk will depend on the read pattern for future analyses.\n", - "We will be chunking the data so that future reads will be performant -- and that depends on whether\n", - "the data favors one dimension or another. For some datasets, this will be very apparent (NWIS gages, \n", - "for example -- it very likely will be consumed along the `time` dimension most often. It is _more likely_\n", - "that future analysis of this data will take a time series for a given gage, as opposed to taking all\n", - "gage data for a given time). For datasets where there is no clear preference, we can try to chunk \n", - "based on likely read patterns, but allow for other patterns without too much of a performance penalty. \n", - "\n", - "Let's see how we might do this for our sample dataset. This data will likely be used in one of two \n", - "dominant read patterns: \n", - "\n", - "* Time series for a given location (or small spatial extent)\n", - " * As a special case -- is it likely that time series will be subset by a logical unit? e.g. will this\n", - " monthly data be consumed in blocks of 12 (yearly)? \n", - "* Full extent for a given point in time. \n", - " * As a special case -- are specific study areas more used than others? \n", - " \n", - "Let's look at a couple of options for space and time chunking: \n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Time Dimension\n", - "\n", - "The example dataset has 1512 time steps. What happens if we chunk in groups of \n", - "twelve (i.e. a year at a time)?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"We need {} chunks.\".format(1512 // 12))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case, a user could get an single year of this monthly data as a single chunk.\n", - "If they wanted a full time series across the entire dataset, they would need to read \n", - "126 chunks. \n", - "\n", - "So this is where the judgement call gets made -- which is the more likely read pattern \n", - "for time? Year-by-year, or the whole time set (or some sequence of a few years). In \n", - "this case, I think it is more likely to want more than just one year's data. A happy \n", - "medium for chunk size is 6 years of data per chunk: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "test_chunk_size = 12*6\n", - "print(\"TIME chunking: {} chunks of size {}\".format(1512 / test_chunk_size, test_chunk_size))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This pattern means only 21 chunks (instead of the 126 chunks we were considering a moment ago) \n", - "for a full time series in a given location. If we assume the rule-of-thumb latency for reading\n", - "and processing a chunk (100ms per read as the theoretical expectation -- see \"size\" below), \n", - "those 21 chunks can be read by a single worker in:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Expected latency in seconds: \", (21 * 100) * 0.001)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that for cluster-aware analyses, multiple chunks can be read at the same time. Total wall-clock time will be reduced in that case. With 21 chunks, maximum (theoretical) parallelism would be achieved with 21 cooperating workers.\n", - "\n", - "We'll move forward with the time dimension chunked into groups of **72** for this dataset." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SPACE\n", - "\n", - "We're realy chunking in dimensions -- and there are two dimensions to this dataset which \n", - "contribute to \"space\": `lat` and `lon`. These can have separate chunk sizes. The question \n", - "to ask is whether future users of this data will want square \"tiles\" in space, or will \n", - "they want proportionally-sized longitude and latitude? That is, is it important that the \n", - "North-South extent be broken into the same number of chunks as the East-West extent?).\n", - "I'll be breaking this into square tiles, so there will be more `lon` chunks than `lat` chunks: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# The size of the dataset: \n", - "lon=1405\n", - "lat=621\n", - "test_chunk_size = lat // 4 # split the smaller of the two dimensions into 4 chunks\n", - "print(\"LON chunking: {} chunks of size {}\".format(lon / test_chunk_size, test_chunk_size))\n", - "print(\"LAT chunking: {} chunks of size {}\".format(lat / test_chunk_size, test_chunk_size))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is important to note that we have **just over** a round number of chunks.\n", - "Having `9.06` longigutde chunks means we will have `10` chunks in practice, but \n", - "that last one is not full-sized. In this case, this means that the last chunk \n", - "in the given dimension will be extremely thin. \n", - "\n", - "In the case of that latitude chunk size, the extra `0.006` of a chunk means that\n", - "the last, fractional, chunk is only one `lat` observation. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# remainder chunksize\n", - "0.0064516129 * 155" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This all but guarantees that two chunks are needed for a small spatial extent \n", - "near the \"end\" of the `lat` dimension. Ideally, we would want partial chunks \n", - "to be at least half the size of the standard chunk. The bigger that 'remainder' \n", - "fraction, the better. \n", - "\n", - "Let's adjust numbers a little so that we don't have that sliver. We're still\n", - "committed to square tiles, so let's try a larger chunk size to change the size\n", - "of that last fraction: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "test_chunk_size = 160\n", - "print(\"LON chunking: {} chunks of size {}\".format(lon / test_chunk_size, test_chunk_size))\n", - "print(\"LAT chunking: {} chunks of size {}\".format(lat / test_chunk_size, test_chunk_size))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With this pattern, the \"remainder\" latitude chunk will be 141 in the `lat` dimension (125 \n", - "for the last `lon` chunk). All others will be a square 160 observations in both directions.\n", - "\n", - "This amounts to a 9x4 chunk grid, with the last chunk in each direction being partial. \n", - "\n", - "The entire spatial extent for a single time step can be read in 36 chunks, with this pattern. \n", - "That feels a little high to me, given that this dataset will likely be taken at full extent\n", - "for a typical analysis. Let's go a little bigger to see what that gets us: \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "test_chunk_size = 354\n", - "print(\"LON chunking: {} chunks of size {}\".format(lon / test_chunk_size, test_chunk_size))\n", - "print(\"LAT chunking: {} chunks of size {}\".format(lat / test_chunk_size, test_chunk_size))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is not *quite* as good in terms of full-chunk remainders -- but on the other hand, the whole extent \n", - "can be had in only 8 chunks. The smallest remainder is still 75% of a full-sized square tile, which is\n", - "acceptable. \n", - "\n", - "Note, that if were really confident that most analyses wanted the full extent, we might\n", - "be better off to just put the whole lat/lon dimensions into single chunks each. This \n", - "would ensure (and **require**) that we read the entire extent any time we wanted any **part** \n", - "of the extent for a given timestep. Our poor time-series analysis would then be stuck \n", - "reading the entire dataset to get all time values for a single location. `:sadface:`\n", - "\n", - "We're going to move forward here with the `lat` and `lon` dimensions being chunked at **354**\n", - "observations each. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Size Considerations\n", - "\n", - "Shape is only part of the equation. Total chunk size matters also. Size considerations\n", - "come into play mostly as a consideration of how the chunks are stored on disk. The \n", - "retrieval time is influenced by the size of each chunk. Here are some constraints: \n", - "\n", - "* Files Too Big -- In a zarr dataset, each chunk is stored as a separate binary file. \n", - " If we need data from a particular chunk, no matter how little or how much, that file gets \n", - " opened, decompressed, and the whole thing read into memory. A large chunk sizes means \n", - " that there may be a lot of data transferred in situations when only a small subset of \n", - " that chunk's data is actually needed. It also means there might not be enough chunks \n", - " to allow the dask workers to stay busy loading data in parallel. \n", - "* Files Too Small -- If the chunk size is too small, the time it takes to read and \n", - " decompress the data for each chunk can become comparable to the latency of S3 (typically \n", - " 10-100ms). We want the reads to take at least a second or so, so that the latency is\n", - " not a significant part of the overall timing.\n", - " \n", - "As a general rule, aim for chunk sizes between 10 and 200MB, depending on shape\n", - "and expected read pattern (see below). Expect 100ms latency for each separate\n", - "chunk that a process needs to open.\n", - "\n", - "### Total Chunk Size\n", - "Now that we have a rough idea of the chunk dimensions, let's compute its size in bytes. \n", - "This will tell us if we've hit our target of between 10 and 200MB per chunk. More \n", - "importantly, it will tell us if we will overwhelm the OpenDAP server -- the server \n", - "can only give us 500MB at a time. Chunks should really be smaller than this (which \n", - "we want anyway, but this 500MB limit is a hard cut-off). \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# lat lon time float32\n", - "bytes = 354 * 354 * 72 * 4\n", - "kbytes = bytes / (2**10)\n", - "mbytes = kbytes / (2**10)\n", - "print(f\"TMN chunk size: {bytes=} ({kbytes=:.2f}) ({mbytes=:.4f})\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We're looking really good for size. Maybe even a bit low.\n", - "But we're in the (admitedly broad) range of 10-200 megabytes of\n", - "uncompressed data (i.e. in-memory) per chunk. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Making the chunk plan\n", - "Now that we know how we want to chunk the data, we need to give that \n", - "information to the API which will read the data from its OpenDAP endpoint: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ds_in = xr.open_dataset(\n", - " OPENDAP_url, \n", - " decode_times=False, \n", - " chunks={ #this directs the open_dataset method to structure its reads in a particular way.\n", - " 'time': 72, \n", - " 'lon': 354, \n", - " 'lat': 354\n", - " }\n", - ")\n", - "ds_in" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Looking more closely at the `tmn` variable: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ds_in.tmn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**NOTE** that the display looks differently than it does in the {doc}`ExamineSourceData` notebook. \n", - "In that original data examination (when we did not express a chunking preference), the data was \n", - "described as `1319227560 values with dtype=float32`. In the above data description, you can see\n", - "that those observations are structured in the chunks that we've asked for. Notice that the\n", - "`xarray` description of chunk size matches our rough calculation (34.4 MB/chunk). \n", - "\n", - "Also, take note that the \"Attributes\" is still claming that `_ChunkSizes` is `[1 23 44]`. This\n", - "is clearly a lie (it was never really true, actually). This is a particular oddity with OpenDAP\n", - "(or perhaps with this server), and won't be a consideration if you are working with data from\n", - "other sources. \n", - "\n", - "We've specifically asked the dask interface to request this data according to the chunk pattern \n", - "specified -- and this is revealed in the graphical display. Dask will make specific OPeNDAP \n", - "requests *per chunk* using appropriate query parameters to the server. \n", - "\n", - "Because this chunk pattern can be provided by the server, and it is a reasonable pattern for \n", - "object storage in S3, we do **not** need to add the complexity of `rechunker`. We can just \n", - "have the zarr driver write it out according to the same plan. Even so, it is useful to \n", - "lay out exactly what the chunking plan might be if we were using `rechunker`:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chunk_plan = {\n", - " 'ppt':{'time': 72, 'lon': 354, 'lat': 354}, \n", - " 'tmx':{'time': 72, 'lon': 354, 'lat': 354}, \n", - " 'tnm':{'time': 72, 'lon': 354, 'lat': 354},\n", - " 'time_bnds': {'time': 1, 'tbnd': 2},\n", - " 'lat': (621,),\n", - " 'lon': (1405,),\n", - " 'time': (1512,),\n", - " 'tbnd': (2,)\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the coordinate variables themselves (`lat`, `lon`, etc) are stored as single-chunk stripes of data. \n", - "Recall that these are used to translate a latitude (or longitude) value into the actual corresponding array \n", - "address. These coordinate arrays will always be needed in their entirity, so we chunk them such that \n", - "they read with one chunk each. This does not affect how the data representing the data variables is chunked. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/101/ExamineDataChunking.ipynb b/101/ExamineDataChunking.ipynb new file mode 100644 index 0000000..a71b497 --- /dev/null +++ b/101/ExamineDataChunking.ipynb @@ -0,0 +1,351 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# How to Examine a Stored Dataset's Chunk Shape\n", + "\n", + "The objective of this notebook is to learn how to examine a stored dataset and understand if it is chunked and, if so, what its \"[**chunk shape**](../back/Glossary.md#term-Chunk-shape)\" is.\n", + "To do this, we will utilize an existing dataset from the HyTEST OSN, take a guided tour of the data, and show how to figure out its chunk shape." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import fsspec" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Accessing the Dataset\n", + "\n", + "Before we can open at the dataset, we must first get a mapper that will easily allow for [xarray](https://docs.xarray.dev/en/stable/index.html) to open the dataset.\n", + "To do this, we will use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) to perform an anonymous read from an endpoints outside of S3, using the S3 API (i.e., the HyTEST OSN).\n", + "This requires us to set up an S3 file system and feed it the endpoint URL.\n", + "We can then point the the file system to our dataset (in this case the PRISM V2 Zarr store) and get a mapper to the file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem(\n", + " 's3',\n", + " anon=True, # anonymous = does not require credentials\n", + " client_kwargs={'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + ")\n", + "file = fs.get_mapper('s3://mdmf/gdp/PRISM_v2.zarr/')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have our file mapper, we can open the dataset using [`xarray.open_dataset()`](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html) with `zarr` specified as our engine.\n", + "\n", + "```{note}\n", + "The xarray loader is \"lazy\", meaning it will read just enough of the data to make decisions about its shape, structure, etc.\n", + "It will pretend like the whole dataset is in memory (and we can treat it that way), but it will only load data as required.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(file, engine='zarr')\n", + "ds" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The \"rich\" HTML output to show the [`xarray.Dataset`](https://docs.xarray.dev/en/stable/generated/xarray.Dataset.html) includes a lot of information, some of which is hidden behind toggles.\n", + "Click on the icons to the right to expand and see all the metadata available for the dataset.\n", + "The page icon will display attributes attached to the data, while the database icon will display information about the dataset.\n", + "\n", + "Notable observations: \n", + "- **Dimensions**: This dataset is 3D, with data being indexed by `lat`, `lon`, and `time` (setting side `tbnd` for the moment; it is a special case).\n", + " Looking at the \"Dimensions\" line, you can see that each of these dimensions is quantified (i.e., how many unique values are available in each dimension).\n", + " - **lat** = 621\n", + " - **lon** = 1405\n", + " - **time** = 1512\n", + "- **Coordinates**: These are the convenient handles by which dimensions can be referenced.\n", + " In this dataset, a coordinate can be used to pick out a particular cell of the array.\n", + " Asking for cells where say `lat=49.9` is possible because these coordinates map the meaningful values of latitude to the behind-the-scenes cell index needed to fetch the value. \n", + "- **Data Variables**: The variables are `tmx`, `ppt`, and `tmn`, which are associated with three indices by which data values are located in space and time (the \"Dimensions\"). \n", + "- **Indexes**: This is an internal data structure to help xarray quickly find items in the array.\n", + "- **Attributes**: Arbitrary metadata that has been given to the dataset. \n", + "\n", + "Let's look at one of the data variables to learn more about it. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Variable = [`xarray.DataArray`](https://docs.xarray.dev/en/stable/generated/xarray.DataArray.html#xarray.DataArray)\n", + "\n", + "Each data variable is its own N-dimensional array (in this case, 3-dimensional, indexed by `lat`, `lon`, and `time`).\n", + "We can look at the individual variables by examining its array separately from the dataset: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.tmn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note from the top line that this variable is indexed as a tuple in `(time, lat, lon)`.\n", + "So, behind the scenes, there is an array whose first index is a value between 0 and 1511. \n", + "But how do we know the time value of index 0 (or any index, really)?\n", + "The \"Coordinates\" are the lookup table to say what \"real\" time value is associated with each index address. \n", + "\n", + "You'll notice that the data description in this case is merely \"1319227560 values with dtype=float64\" with no indication as to how it is chunked.\n", + "Assuming our 3-D array is fully populated, this value makes sense:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# time lat lon\n", + "1512 * 621 * 1405" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In terms of chunking, this is where it gets interesting.\n", + "If you thoroughly looked at the rich HTML output, you may have noticed that there is no reference to chunking anywhere.\n", + "Occasionally, some datasets will include some info in their \"Attributes\" that potentially indicate how the data is chunked.\n", + "For example, some may include a `_ChunkSizes` that gives the chunk shape of the data, expressed as a tuple to match the dimensions.\n", + "However, we should be skeptical of any information on how the data is chunked in the \"Attributes\".\n", + "Virtually anything can be set as an attribute on the dataset, and it does not affect the internal structure of the dataset **AT ALL**.\n", + "Therefore, we need to directly access the data in a way that returns the true chunk shape of the stored dataset.\n", + "\n", + "To do this, we can simply check the variables \"encoding\".\n", + "This returns metadata that was used by xarray when reading the data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.tmn.encoding" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From here we can see two keys dealing with chunks: `'chunks'` and `'preferred_chunks'`.\n", + "While not identical entries, both contain the same information of how the data is chunked.\n", + "The difference between the two is `'chunks'` is the actual chunk shape of the chunks stored on disk (what is commonly termed \"[**stored chunks**](../back/Glossary.md#term-Stored-chunks)\"), while `'preferred_chunks'` is the chunk shape that the engine used to open the dataset chose.\n", + "Generally, these are the same, but they may be different if the engine you use has not been set to equate them.\n", + "Therefore, our data has a stored chunk shape of `{'time': 72, 'lat': 354, 'lon': 354}`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting the Chunking When Reading Data\n", + "\n", + "While checking the \"encoding\" of the variable can tell you what the dataset's stored chunk shape is, it is typically easier to do this in one step when you open the dataset.\n", + "To do this, all we need is to add a another keyword when we open the dataset with xarray: `chunks={}`.\n", + "As per the [`xarray.open_dataset` documentation](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html): \n", + "\n", + "> `chunks={}` loads the data with dask using the engine’s preferred chunk size, generally identical to the format’s chunk size.\n", + "\n", + "In other words, using `chunks={}` will load the data with chunk shape equal to `'preferred_chunks'`.\n", + "Let's check this out and see how our data looks when we include this keyword when opening." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(file, engine='zarr', chunks={})\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now if we inspect the data variables metadata, we will see that the data is now read in as a dask array.\n", + "Let's look at at the `tmn` variable again to simplify this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.tmn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see the data is chunked into chunks of shape `(72, 354, 354)` with a \"[**chunk size**](../back/Glossary.md#term-Chunk-size) of ~70 MiB.\n", + "This is exactly what we saw when looking at the encoding.\n", + "So, this additional keyword worked as expected and gives us a standard way to open chunked datasets using the stored chunk shape as our chunk shape!\n", + "\n", + "Note that the coordinate variables themselves (`lat`, `lon`, and `time`) are stored as single unchunked arrays of data.\n", + "Recall that these are used to translate a coordinate value into the index of the corresponding array.\n", + "Therefore, these coordinate arrays will always be needed in their entirity.\n", + "So, they are included in each chunk such that they read whenever a chunk is read, and they do not affect how the data representing the data variables is chunked. \n", + "\n", + "\n", + "## Changing the Chunk Shape and Size\n", + "\n", + "Now that we know our stored chunk shape and size or how to find them, they may not always be the optimal choice for performing analysis.\n", + "For example, [Zarr recommends a stored chunk size of at least 1 MB uncompressed](https://zarr.readthedocs.io/en/stable/tutorial.html#chunk-size-and-shape) as they give better performance.\n", + "However, [dask recommends chunk sizes between 10 MB and 1 GB for computations](https://docs.dask.org/en/stable/array-chunks.html#specifying-chunk-shapes), depending on the availability of RAM and the duration of computations.\n", + "Therefore, our stored chunk size may not be large enough for optimal computations.\n", + "Thankfully, stored chunks do not need to be the same size as those we use for our computations.\n", + "In other words, we can group multiple smaller stored chunks together when performing our computations.\n", + "Xarray makes this easy by allowing us to adjust the chunk shape and size, either as we load the data or after.\n", + "\n", + "Let's show how this works by increasing our chunks of the minimum monthly temperature to a size of ~500 MiB.\n", + "To do so when reading in the data, all we need to do is actually specify the chunk shape to `chunks`.\n", + "For our example, let's do chunks of shape: `{'time': 150, 'lat': 310, 'lon': 1405}`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Note we drop the other variables and select tmn when reading the data\n", + "ds_tmn = xr.open_dataset(file, engine='zarr',\n", + " chunks={'time': 150, 'lat': 310, 'lon': 1405},\n", + " drop_variables=['ppt', 'time_bnds', 'tmx', 'crs']).tmn\n", + "ds_tmn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nice!\n", + "As we can see, the chunk shape is now reflected in data description with about the right chunk size we wanted.\n", + "However, we did get a warning indicating that:\n", + "\n", + "```\n", + "UserWarning: The specified chunks separate the stored chunks along dimension X starting at index i. This could degrade performance. Instead, consider rechunking after loading.\n", + "```\n", + "\n", + "```{important}\n", + "This warning is telling us that the chunk shape we have chosen is not a multiple (or grouping) of the the stored chunks, and if we really want this chunk shape, we should rechunk.\n", + "```\n", + "\n", + "Oops, as we are not attached to this chunk shape nor wanting to rechunk the data (see the [Why (re)Chunk Data? notebook](WhyChunk.ipynb) for reasons why you might), we need to select a chunk shape that is a **multiple** of the stored chunks.\n", + "This time, let's try: `{'time': 72*2, 'lat': 354*2, 'lon': 354*2}`.\n", + "This should increase our chunk size by a factor of 8 ($2^3 = 8$).\n", + "Close to the ~500 MiB we are wanting." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds_tmn = xr.open_dataset(file, engine='zarr',\n", + " chunks={'time': 72 * 2, 'lat': 354 * 2, 'lon': 354 * 2},\n", + " drop_variables=['ppt', 'time_bnds', 'tmx', 'crs']).tmn\n", + "ds_tmn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Look at that, no warning and close to the chunk size we wanted!\n", + "\n", + "As a final note, we selected our chunk shape while reading in the data.\n", + "However, we could change them after using [`xarray.Dataset.chunk()`](https://docs.xarray.dev/en/stable/generated/xarray.Dataset.chunk.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.tmn.chunk({'time': 72 * 2, 'lat': 354 * 2, 'lon': 354 * 2})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`````{admonition} Not Recommended\n", + ":class: warning\n", + "We do not recommend using this method as you will not get the same warning notifying you that the chosen chunk shape does not match a multiple of the stored chunk shape.\n", + "Therefore, if you choose a non-multiple chunk shape you could slow down your whole workflow as the data will have to be rechunked to meet your requested chunk shape.\n", + "`````" + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/101/ExamineSourceData.ipynb b/101/ExamineSourceData.ipynb deleted file mode 100644 index 1ee9be4..0000000 --- a/101/ExamineSourceData.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Examine Source Data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "**OBJECTIVE**: \n", - "The objective of this chapter is to demonstrate how to read an existing dataset available as an OpenDAP endpoint, and translate it into a cloud-optimized zarr on S3. \n", - "\n", - "This notebook will take a guided tour of the input data, and show how to pick out key metadata about the structure of the dataset. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import logging\n", - "import xarray as xr\n", - "logging.basicConfig(level=logging.INFO, force=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "%run ../utils.ipynb\n", - "_versions(['xarray'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Source Data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# INPUT: \n", - "OPENDAP_url = 'https://cida.usgs.gov/thredds/dodsC/prism_v2'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `xarray` loader is \"lazy\" -- it will read just enough of the data to make decisions about its shape, structure, etc. It will pretend like the whole dataset is in memory (and we can treat it that way), but it will only load data as required. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data Set" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# lazy-load\n", - "ds_in = xr.open_dataset(OPENDAP_url)#, decode_times=False)\n", - "# and show it:\n", - "ds_in" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The \"rich\" HTML output to show the `xarray.Dataset` includes a lot of information, some of which is hidden behind toggles. Click on the icons to the right to expand and see all the metadata available for the dataset. \n", - "\n", - "Notable observations: \n", - "* **Dimensions** -- This dataset is 3D, with data being indexed by `lon`, `lat`, and `time` (setting \n", - " side `time_bnds` for the moment; it is a special case). Looking at the \"Dimensions\" line, you \n", - " can see that each of these dimensions is quantified -- how many unique values are available in \n", - " each dimension: \n", - " * **lon** = 1405\n", - " * **lat** = 621\n", - " * **time** = 1512\n", - "* **Coordinates** -- These are the convenient handles by which dimensions can be referenced. In this \n", - " dataset, a coordinate can be used to pick out a particular cell of the array. Asking for \n", - " cells where `lat=49.9` is possible because these coordinates map the meaningful values of latitude\n", - " to the behind-the-scenes cell index needed to fetch the value. \n", - "* **Data Variables** -- The variables are `tmx`, `ppt`, and `tmn`, which are associated \n", - " with three indices by which data values are located in space and time (the _Dimensions_). \n", - "* **Indexes** -- this is an internal data structure to help `xarray` quickly find items in the array.\n", - "* **Attributes** -- Arbitrary metadata associated with the dataset. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's look at one of the data variables to learn more about how it is presented by the OPeNDAP endpoint. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Variable = \"Data Array\"\n", - "\n", - "Each data variable is its own N-dimensional array (in this case, 3-dimensional, indexed by lat, lon, and time). We can look at the individual variables by examining its array separately from the dataset: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ds_in.tmn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note from the top line that this variable is indexed as a tuple in `(time, lat, lon)`. So, behind the scenes, there is an array whose first index is a value between 0 and 1511. How do we know the time value of index 0? (or any index, really) The \"Coordinates\" are the lookup table to say what \"real\" time value is associated with each index address. \n", - "\n", - "You'll notice that the data description in this case is merely \"1319227560 values with dtype=float32\"\n", - "with no indication as to how it is chunked. Assuming our 3-D array is fully populated, this value makes sense:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# time lat lon\n", - "1512 * 621 * 1405" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In terms of chunking, this is where it gets interesting.\n", - "\n", - "Notice that in the data attributes, that `_ChunkSizes` gives the chunk \n", - "sizes of the data, expressed as a tuple to match the dimensions. If we\n", - "choose to believe this, it indicates that the data are broken into \n", - "chunks, each of which is \n", - "* 1 timestep, \n", - "* 23 latitude steps, and \n", - "* 44 longitude steps. \n", - "\n", - "In this case, we should be skeptical, because this information comes from an \"Attribute\", which \n", - "may or may not be relevant. Virtually anything can be set as an attribute on the dataset, and \n", - "it does not affect the internal structure **AT ALL**. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ds_in.tmn.attrs['spam'] = \"Delicious\"\n", - "ds_in.tmn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the case of this OpenDAP data, we can choose to believe that this is how\n", - "the server would like to give us the data as a default. If we accept that\n", - "default: \n", - "\n", - "Gven that `tmn` is stored as a `float32` (4 bytes), each chunk is of size: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# time lat lon float32\n", - "bytes = 1 * 23 * 44 * 4\n", - "kbytes = bytes / (2**10)\n", - "mbytes = kbytes / (2**10)\n", - "print(f\"TMN chunk size: {bytes=} ({kbytes=:.2f})({mbytes=:.4f})\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is an **extremely** small chunk size, and not at all suitable for cloud storage.\n", - "We certainly will want to change that when we write this data. \n", - "\n", - "The good news is that we are not stuck with it. The opendap server is offering us \n", - "its default chunking for network API requests, but this is configurable. We can \n", - "change it to something more suitable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## OpenDAP Considerations\n", - "\n", - "A subtle point about this particular dataset, given that we are reading it \n", - "from an OpenDAP Server: The server can't give us data in chunks bigger than\n", - "500MB. \n", - "\n", - "When it comes time to read this data, we need to specify the pattern that we\n", - "want the data in. This will ensure that each individual data request (i.e. \n", - "each 'chunk') is smaller than this. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/101/Rechunking.ipynb b/101/Rechunking.ipynb new file mode 100644 index 0000000..eb49048 --- /dev/null +++ b/101/Rechunking.ipynb @@ -0,0 +1,439 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "60a93f80-def8-48cc-b31f-65772a2bdc12", + "metadata": {}, + "source": [ + "# Rechunking" + ] + }, + { + "cell_type": "markdown", + "id": "169ec966-1ad9-489d-92b9-89b8e2240bce", + "metadata": {}, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "This notebook was inspired by the material in [this notebook by James McCreight](https://github.com/NCAR/rechunk_retro_nwm_v21/blob/main/notebooks/usage_example_rerechunk_chrtout.ipynb), and [the Rechunker Tutorial](https://rechunker.readthedocs.io/en/latest/tutorial.html).\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "markdown", + "id": "507993a5-5380-47db-b9eb-3347ec6ee28b", + "metadata": {}, + "source": [ + "The goal of this notebook is to learn how to \"[**rechunk**](../back/Glossary.md#term-Rechunking)\" data.\n", + "This will be a culmination of all the [previous introductory material](index.md) where we will:\n", + "\n", + "1. [Read in a Zarr store](ExamineDataChunking.ipynb)\n", + "2. [Check the current chunking](ExamineDataChunking.ipynb)\n", + "3. [Choose a new chunk shape](BasicsShapeSize.ipynb)\n", + "4. Rechunk using [Rechunker](https://rechunker.readthedocs.io/en/latest/index.html)\n", + "5. [Confirm the proper creation of the Zarr store by Rechunker](WriteChunkedFiles.ipynb)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb67d60e-ad2b-40a3-9a48-54518e47dc17", + "metadata": {}, + "outputs": [], + "source": [ + "%xmode Minimal\n", + "import xarray as xr\n", + "import fsspec\n", + "from rechunker import rechunk\n", + "import zarr\n", + "import shutil\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "id": "60378aa5-336d-42e4-85b7-ef7f54cee32f", + "metadata": {}, + "source": [ + "## Read in a Zarr Store\n", + "\n", + "For the dataset in this tutorial, we will use the data from the National Water Model Reanalysis Version 2.1.\n", + "The full dataset is part of the [AWS Open Data Program](https://aws.amazon.com/opendata/), available via the S3 bucket at: `s3://noaa-nwm-retro-v2-zarr-pds/`.\n", + "\n", + "As this is a Zarr store, we can easily read it in directly with [`xarray.open_dataset()`](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html), including the keyword `chunks={}` to make sure it loads the data with dask using the stored chunks' shape and size." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72c2d2ac-d9b8-4104-82c5-f10241c0f373", + "metadata": {}, + "outputs": [], + "source": [ + "file = fsspec.get_mapper('s3://noaa-nwm-retro-v2-zarr-pds', anon=True)\n", + "ds = xr.open_dataset(file, chunks={}, engine='zarr')\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "3f01e966-bd18-4971-be94-797ade9b82d0", + "metadata": {}, + "source": [ + "## Check the Current Chunk Shape and Size\n", + "\n", + "From the output, we can see that there are two dimensions, `time` of length 227,904 and `feature_id` of length 2,729,077.\n", + "Next, both `time` and `feature_id` are coodinates, along with two extra coordinates of `latitude` and `longitude` which are tied to the `feature_id`.\n", + "Inspecting these extra coordinates in detail, we can notice that they are \"chunked\", but only to a single chunk of size 10.41 MiB.\n", + "This is good, as we will want them in a single chunk for writing, such that they are fully read in with each data variable chunk.\n", + "Finally, there are eight data variables, all having both of the dimensions, meaning they are 2D data.\n", + "Examining the variables in detail, they all have chunks of shape `{'time': 672, 'feature_id': 30000}` and size of 153.81 MiB or 76.9 MiB (depending if the variable is 64 or 32 bit, respectively).\n", + "Additionally, we can see that each variable is a whopping 4.53 or 2.26 TiB in memory, which means the whole dataset is almost 32 TiB!\n", + "\n", + "This is a bit more than we want to work with in our example.\n", + "So, let's go ahead an select a subset of the data that is about 1 GiB in memory.\n", + "While this is not a larger-than-memory dataset anymore, it is still reasonably large that it will work well for this example without taking forever to get data and rechunk.\n", + "For the subset, let's only look at `streamflow` and `velocity` for the first 15,000 `feature_id` and the one year time range of water year 2018 (i.e., October 2017 to September 2018).\n", + "\n", + "```{note}\n", + "As we are not working on AWS, we have selected this subset to minimize the number of chunks that effectively need to be downloaded from the S3 bucket.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd193245-46ac-4aac-a638-b8d19cccd68e", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['streamflow', 'velocity']]\n", + "ds = ds.isel(feature_id=slice(0, 15000))\n", + "ds = ds.sel(time=slice('2017-10-01', '2018-09-30'))\n", + "ds" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "04fabae9-9c45-4b69-b829-256f9eee1012", + "metadata": {}, + "source": [ + "Now, our subset of data is only about 1 GiB per data variable and has a chunk shape of `{'time': 672, 'feature_id': 15000}` with size of 76.9 MiB.\n", + "This is a good chunk size and between the optimal range of 10 to 200 MiB.\n", + "However, the chunk shape may not be an optimal choice for our analysis as it is chunked completely by `feature_id` (i.e., all feature IDs for a given time can be read in a single chunk).\n", + "\n", + "## Choose a New Chunk Shape and Size\n", + "\n", + "To decide on a new chunk shape and size, we need to determine how we will use the data.\n", + "As we just discussed, an analysis which samples all locations for a single point in time would need to fetch only a single chunk, which is perfect for that analysis.\n", + "However, a time-series analysis (i.e. sampling all time-step values for a single `feature_id`) would require 13 chunks to be read for one feature.\n", + "This means many more chunks must be fetched for this read pattern.\n", + "Thinking of data usage, the preferred format for the streamflow data variable is likely time-series wise chunking as this variable is more often used as full time series at a single location.\n", + "The same goes for velocity.\n", + "However, for the purpose of this example, let's assume that we don't know how velocity will be used and give it a different chunking pattern, one where we balance the number of chunks between each variable." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6084e9a6-2de1-40ba-b7b5-15e70393f2c4", + "metadata": {}, + "outputs": [], + "source": [ + "nfeature = len(ds.feature_id)\n", + "ntime = len(ds.time)\n", + "\n", + "streamflow_chunk_plan = {'time': ntime, 'feature_id': 1}\n", + "bytes_per_value = ds.streamflow.dtype.itemsize\n", + "total_bytes = streamflow_chunk_plan['time'] * streamflow_chunk_plan['feature_id'] * bytes_per_value\n", + "streamflow_MiB = total_bytes / (2 ** 10) ** 2\n", + "print(\"STREAMFLOW \\n\"\n", + " f\"Chunk of shape {streamflow_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {ntime / (ntime / streamflow_chunk_plan['time']) - streamflow_chunk_plan['time']} \\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {nfeature / (nfeature / streamflow_chunk_plan['feature_id']) - streamflow_chunk_plan['feature_id']} \\n\"\n", + " f\"Chunk size: {streamflow_MiB:.2f} [MiB] \\n\")\n", + "\n", + "chunks_per_dim = 3\n", + "velocity_chunk_plan = {'time': ntime // chunks_per_dim, 'feature_id': nfeature // chunks_per_dim}\n", + "bytes_per_value = ds.velocity.dtype.itemsize\n", + "total_bytes = velocity_chunk_plan['time'] * velocity_chunk_plan['feature_id'] * bytes_per_value\n", + "velocity_MiB = total_bytes / (2 ** 10) ** 2\n", + "print(\"VELOCITY \\n\"\n", + " f\"Chunk of shape {velocity_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {ntime / chunks_per_dim - velocity_chunk_plan['time']} \\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {nfeature / chunks_per_dim - velocity_chunk_plan['feature_id']} \\n\"\n", + " f\"Chunk size: {velocity_MiB:.2f} [MiB]\")" + ] + }, + { + "cell_type": "markdown", + "id": "f1ffc944-fe70-413e-b0f8-8bc7bdbb5280", + "metadata": {}, + "source": [ + "Okay, so, the time-series streamflow chunking for a single feature ID has way too small of a chunk size.\n", + "If we increase the number of feature IDs per chunk by a factor of 1000, we should have the right size for that chunk\n", + "As for velocity, the split of the data into three chunks along both dimensions resulted in no partial chunks and a chunk size of 111 MiB.\n", + "This is within our optimal chunk size range.\n", + "So, let's stick with the velocity chunks and recheck the streamflow chunking with 1000 features per time series chunk." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af8609df-8627-4368-be50-3288ac6c1148", + "metadata": {}, + "outputs": [], + "source": [ + "streamflow_chunk_plan = {'time': ntime, 'feature_id': 1000}\n", + "bytes_per_value = ds.streamflow.dtype.itemsize\n", + "total_bytes = streamflow_chunk_plan['time'] * streamflow_chunk_plan['feature_id'] * bytes_per_value\n", + "streamflow_MiB = total_bytes / (2 ** 10) ** 2\n", + "print(\"STREAMFLOW \\n\"\n", + " f\"Chunk of shape {streamflow_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {ntime / (ntime / streamflow_chunk_plan['time']) - streamflow_chunk_plan['time']} \\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {nfeature / (nfeature / streamflow_chunk_plan['feature_id']) - streamflow_chunk_plan['feature_id']} \\n\"\n", + " f\"Chunk size: {streamflow_MiB:.2f} [MiB] \\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "23fdac77-f8ca-4392-b3d4-41806d6c3b2b", + "metadata": {}, + "source": [ + "Alright, no remainders and a reasonable chunk size.\n", + "Time to get to rechunking!" + ] + }, + { + "cell_type": "markdown", + "id": "3234b824-aa75-402f-9976-0b9d9f90e821", + "metadata": {}, + "source": [ + "## Rechunk with [Rechunker](https://rechunker.readthedocs.io/en/latest/index.html)\n", + "\n", + "This is a relatively trivial example, due to the smaller size of the subset of the dataset.\n", + "As the whole subset can fit into memory easily, chunking in general is largely unnecesary in terms of optimizing I/O (however, parallelism is still a consideration). \n", + "But it is worth doing, as the concepts will apply if we take this to the full dataset.\n", + "\n", + "First thing we need is a chunk plan to describe the chunk layout we want.\n", + "We already created a basic version of this above that describes the chunk shapes of streamflow and velocity.\n", + "We just need to place it into a more cohesive list along with chunk shapes for the coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0a072a5-c198-4e2c-a2d7-9f801b9dc081", + "metadata": {}, + "outputs": [], + "source": [ + "chunk_plan = {\n", + " 'streamflow': streamflow_chunk_plan,\n", + " 'velocity': velocity_chunk_plan,\n", + " # We don't want any of the coordinates chunked\n", + " 'latitude': (nfeature,),\n", + " 'longitude': (nfeature,), \n", + " 'time': (ntime,),\n", + " 'feature_id': (nfeature,)\n", + "}\n", + "chunk_plan" + ] + }, + { + "cell_type": "markdown", + "id": "bfbdfce8-992d-4412-ad19-cdad10dc379c", + "metadata": {}, + "source": [ + "With this plan, we can ask [Rechunker](https://rechunker.readthedocs.io/en/latest/index.html) to re-write the data using the prescribed chunking pattern.\n", + "Rechunker will take the currently read in data and rechunk it using an intermediate Zarr store for efficiency.\n", + "The result will be our rechunked data saved to a new Zarr store." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7609cb35-431f-4b2b-a59f-55186d8a286d", + "metadata": {}, + "outputs": [], + "source": [ + "outfile = \"rechunked_nwm.zarr\"\n", + "temp_store = \"/tmp/scratch.zarr\"\n", + "result = rechunk(\n", + " ds,\n", + " target_chunks=chunk_plan,\n", + " max_mem=\"2GB\",\n", + " target_store=outfile ,\n", + " temp_store=temp_store\n", + ")\n", + "result" + ] + }, + { + "cell_type": "markdown", + "id": "37af1b74-f0f0-4b1e-bcfb-5dac59fe4f51", + "metadata": {}, + "source": [ + "Oh, that is not what we wanted!\n", + "We seem to have gotten an error indicating overlap in chunks between the read and write.\n", + "Looking at the error, it is saying that the first `time` chunk we are reading is a partial chunk and not a full chunk.\n", + "So, when Rechunker tries to read the data and then write the first rechunk, it is having to read two chunks to write to the one chunk.\n", + "This is a one-to-many write, which can corrupt our file when done in parallel with dask.\n", + "Thank goodness Rechunker caught this for us!\n", + "Reading the recommended fix, it seems the only way to go about this is to call `chunk()` and reset the chunking on the original data.\n", + "In other words, after we select the subset from the dataset, we need to realign the chunks such that the first chunk is not a partial chunk.\n", + "This is simple enough to do.\n", + "So much so, we can just do it when passing the dataset subset to Rechunker.\n", + "\n", + "```{note}\n", + "`rechunker.rechunk` does not overwrite any data.\n", + "If it sees that `rechunked_nwm.zarr` or `/tmp/scratch.zarr` already exist, it will raise an exception.\n", + "Be sure that these locations do not exist before calling Rechunker. \n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2e7c339-75d1-408a-9f01-3837466fec11", + "metadata": {}, + "outputs": [], + "source": [ + "# We must delete the started rechunked zarr stores\n", + "shutil.rmtree(outfile)\n", + "shutil.rmtree(temp_store)\n", + "\n", + "result = rechunk(\n", + " ds.chunk({'time': 672, 'feature_id': 15000}),\n", + " target_chunks=chunk_plan,\n", + " max_mem=\"2GB\",\n", + " target_store=outfile ,\n", + " temp_store=temp_store\n", + ")\n", + "result" + ] + }, + { + "cell_type": "markdown", + "id": "47856c25-e913-4ff7-bcc5-b79b5426fecb", + "metadata": {}, + "source": [ + "Alright, that worked with no problems!\n", + "Now, we must specifically direct rechunk to calculate.\n", + "To do this, we can call `execute()` on our `result` `Rechunked` object.\n", + "Without the call to `execute()`, the Zarr dataset will be empty, and `result` will only hold a 'task graph' outlining the calculation steps.\n", + "\n", + "```{tip}\n", + "Rechunker also writes a minimalist data group, meaning that variable metadata is not consolidated.\n", + "This is not a required step, but it will really spead up future workflows when the data is read back in using xarray.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d15fca4-0ec1-410a-bee5-877ffcbcbb9b", + "metadata": {}, + "outputs": [], + "source": [ + "_ = result.execute()\n", + "_ = zarr.consolidate_metadata(outfile)" + ] + }, + { + "cell_type": "markdown", + "id": "7d79751d-4b6c-4bb8-a033-36440d7fdf5d", + "metadata": {}, + "source": [ + "## Confirm the Creation of the Zarr Store by Rechunker\n", + "\n", + "Let's read in the resulting re-chunked dataset to confirm it turned out how we intended." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad4ca918-3ff7-4d46-9d9f-ec2522f30f63", + "metadata": {}, + "outputs": [], + "source": [ + "ds_rechunked = xr.open_zarr(outfile)\n", + "ds_rechunked" + ] + }, + { + "cell_type": "markdown", + "id": "1267a63c-0822-490a-ac3e-076364805132", + "metadata": {}, + "source": [ + "Great, our chunk shapes are exactly what we specified!\n", + "Let's do one final check that will compare our original subset of the dataset with our new rechunked dataset, that way we can confirm nothing unexpected happened during rechunking.\n", + "\n", + "```{note}\n", + "For our small example dataset this is easy as the data will fit into memory.\n", + "More efficient and better ways should be used for larger datasets.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42eb5583-b63b-4b4f-8ed3-eca58f70cef2", + "metadata": {}, + "outputs": [], + "source": [ + "np.abs(ds - ds_rechunked).compute().max()" + ] + }, + { + "cell_type": "markdown", + "id": "8f3a8f56-d777-41ec-890a-3e0779f34d2c", + "metadata": {}, + "source": [ + "Perfect!\n", + "The maximum absolute difference between each both the `streamflow` and `velocity` variables is 0.\n", + "In other words, they are exactly the same, and Rechunker worked as expect.\n", + "\n", + "Now that you know how to rechunk a Zarr store using Rechunker, you should know all of the basics there are in terms of chunking.\n", + "You are now ready to explore more [advanced chunking topics in chunking](../201/index.md) if you are interested!\n", + "\n", + "## Clean Up\n", + "\n", + "As we don't want to keep this rechunked Zarr on our local machine, let's go ahead and delete it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81014ed7-0c33-438f-915e-af46fd01df29", + "metadata": {}, + "outputs": [], + "source": [ + "shutil.rmtree(outfile)\n", + "shutil.rmtree(temp_store)" + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/101/SecondaryExample.ipynb b/101/SecondaryExample.ipynb deleted file mode 100644 index 523c9ea..0000000 --- a/101/SecondaryExample.ipynb +++ /dev/null @@ -1,270 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2979f859-1640-4633-b52a-b10cb3482fd4", - "metadata": {}, - "source": [ - "# Another Example\n", - "\n", - "Taking what we learned reading OpenDAP data, let's do another example, end-to-end, of\n", - "reading a dataset from a tredds server. The `gridmet` data for precipitation will be\n", - "our new example dataset: \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00d2ca69-26f6-4b2a-bc5c-b11e0bb7f23f", - "metadata": {}, - "outputs": [], - "source": [ - "# Example Dataset: gridmet\n", - "DATA_url = r\"http://thredds.northwestknowledge.net:8080/thredds/dodsC/agg_met_pr_1979_CurrentYear_CONUS.nc\"\n" - ] - }, - { - "cell_type": "markdown", - "id": "12c9573c-f965-458c-88a8-5376ded065da", - "metadata": {}, - "source": [ - "## Preamble\n", - "Stuff we need..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19421b21-eb10-4d4d-b8a6-8a28de456a6a", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import logging\n", - "import xarray as xr\n", - "\n", - "logging.basicConfig(level=logging.INFO, force=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ddb8b2fa-d386-4cae-b8bb-e820bed27d65", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "%run ../utils.ipynb\n", - "_versions(['xarray', 'dask'])" - ] - }, - { - "cell_type": "markdown", - "id": "c1e5f8ac-6f5b-43a6-a7a7-4006ceda54cb", - "metadata": {}, - "source": [ - "## Examine Data\n", - "Lazy-load the data using defaults to see how the overall structure looks:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9ebc6a80-a610-47b9-89d0-a26e8c469f44", - "metadata": {}, - "outputs": [], - "source": [ - "# lazy-load\n", - "ds_in = xr.open_dataset(DATA_url + r\"#fillmismatch\", decode_coords=True, chunks={})\n", - "# and show it:\n", - "ds_in" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "abead8bb-a65e-4af6-90a0-165996f12ce1", - "metadata": {}, - "outputs": [], - "source": [ - "ds_in.precipitation_amount" - ] - }, - { - "cell_type": "markdown", - "id": "065a21ed-4230-4338-b64c-d48438c3c0ed", - "metadata": {}, - "source": [ - "The data is being presented to us from the server as if it is one big chunk. This is almost certainly not how it is stored on the server end. And more importantly, that 48GB chunk is too big for the server to provide all at once. Typically, data requests are capped at 500MB. \n", - "\n", - "But because we did not specify a chunk pattern, we get the illusion that it is one big chunk, and it is up to the server and the client (inside the `open_dataset()` method) to negotiate the transfer. \n", - "\n", - "A hint as to the way the server thinks of this data (absent chunking directives) is the `_ChunkSizes` attribute: `[61 98 231]` for `(day, lat, lon)`. Using that chunking pattern, the data is sized like so: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "760ea923-404b-4ed1-9a49-be8e4549eabe", - "metadata": {}, - "outputs": [], - "source": [ - "# day #lat #lon #float32\n", - "bytes = 61 * 98 * 231 * 4\n", - "kbytes = bytes / (2**10)\n", - "mbytes = kbytes / (2**10)\n", - "print(f\"TMN chunk size: {bytes=} ({kbytes=:.2f})({mbytes=:.4f})\")" - ] - }, - { - "cell_type": "markdown", - "id": "a1469889-2267-4301-b561-4fdbae4dba8a", - "metadata": {}, - "source": [ - "## Establish Chunking Preference\n", - "Will proceed with the assumption that this data will most likely be taken at full extent, for short time intervals. \n", - "\n", - "Examining each of the dimensions of this dataset: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f23f2317-e504-4882-b936-da482f2864ba", - "metadata": {}, - "outputs": [], - "source": [ - "day = 16169/365 #how many chunks for a year-at-a-time\n", - "day" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a60542a-e5e8-448b-b25c-db04947f42d7", - "metadata": {}, - "outputs": [], - "source": [ - "lat = 585 / 3 # split into 3 chunks\n", - "lat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "868e11d0-a3a5-4ac8-9b7f-043e7e29be3f", - "metadata": {}, - "outputs": [], - "source": [ - "lon = 1386 /3 # split into 3 chunks\n", - "lon" - ] - }, - { - "cell_type": "markdown", - "id": "da090e6f-4c11-439c-86f7-3246431b3a7b", - "metadata": {}, - "source": [ - "If we chunk with this pattern, how big will each chunk be? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e1be74e-2bcc-48cb-becc-ea10e40cf3ff", - "metadata": {}, - "outputs": [], - "source": [ - "# day #lat #lon #float32\n", - "bytes = 365 * 195 * 462 * 4\n", - "kbytes = bytes / (2**10)\n", - "mbytes = kbytes / (2**10)\n", - "print(f\"Chunk size: {bytes=} ({kbytes=:.2f})({mbytes=:.4f})\")" - ] - }, - { - "cell_type": "markdown", - "id": "99737679-82da-4ca4-b4f7-f2fe97411553", - "metadata": {}, - "source": [ - " 125MB chunk seems reasonable, but it does mean that a time-series read pattern will have to take in 45 chunks (assuming the spatial extent of the analysis is within one lat/lon chunk). To bring that down, let's take the time dimension as 2 years at a time. Just to make the numbers more round, we'll express the time as 24 30-day months: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e0df8131-d350-48bb-b6c0-932486d2a13a", - "metadata": {}, - "outputs": [], - "source": [ - "ds_in = xr.open_dataset(\n", - " DATA_url + r\"#fillmismatch\", \n", - " decode_coords=True, \n", - " chunks={'day': 24*30, 'lon': 462, 'lat': 195}\n", - ")\n", - "ds_in" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e49d852b-5f98-408f-b24b-708c6b1227aa", - "metadata": {}, - "outputs": [], - "source": [ - "ds_in.precipitation_amount" - ] - }, - { - "cell_type": "markdown", - "id": "94c55815-6cd2-4ff3-a48c-97d61739c4cc", - "metadata": {}, - "source": [ - "This chunk pattern favors the spatial extent. Six chunks are needed to read the entire spatial extent for one time step. \n", - "\n", - "The time data is chunked by two year blocks (assuming alignment with year boundaries, which is almost certainly not true). It would be more accurate to say that the time is in two-year-sized chunks, but may not align with the calendar year. An entire time-series for a small spatial extent will require 23 chunks to be read." - ] - }, - { - "cell_type": "markdown", - "id": "3873a668-7e42-4c35-84a5-9cc4a91d9bd7", - "metadata": {}, - "source": [ - "## Important\n", - "The chunk specification in the `open_dataset()` call does not reconfigure the data itself. It governs how the data driver formulates its requests to the server. The chunking information specified in the open dataset call helps the driver establish the boundaries for its queries. It will then request the data, a chunk at a time, from the server. How the server holds that data is hidden from us, and we really don't need to care. The data driver on our end (from within `xarray.open_dataset()`) does the necessary work to ensure data alignment and that the block/chunk sizes will align to what we want. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cc397e76-c4fb-48db-80c7-3064429ad0ca", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/101/WhyChunk.ipynb b/101/WhyChunk.ipynb index ddf1969..60a5f67 100644 --- a/101/WhyChunk.ipynb +++ b/101/WhyChunk.ipynb @@ -6,19 +6,8 @@ "source": [ "# Why (re)Chunk Data?\n", "\n", - "Re-organizing stored data such that it matches the analysis use-case.\n", - "\n", - "Inspiration from:\n", - "\n", - "\n", - ":::{note}\n", - "* The [`rechunker` documentation](https://rechunker.readthedocs.io/en/latest/index.html) contains several \n", - "examples and a tutorial covering how to re-chunk data. Much of what is here replicates concepts covered\n", - "in that material. This document uses data that _looks_ like data you might encounter in a `HyTest` workflow.\n", - "\n", - "* The `zarr` data standard has a nice tutorial also which covers details of \n", - " [optimizing chunking strategies](https://zarr.readthedocs.io/en/stable/tutorial.html#changing-chunk-shapes-rechunking).\n", - ":::" + "If you are completely new to chunking, then you are probably interested in learning \"what is data chunking?\" and \"why should I care?\".\n", + "The goal of this notebooks is to answer these two basic questions and give you the understanding of what it means for data to be chunked and why you would want to do it." ] }, { @@ -28,23 +17,43 @@ "tags": [] }, "source": [ - "## What is chunking and why should you care?\n", + "## What is chunking?\n", "\n", - "The idea of data '_chunks_' is closely aligned with the NetCDF and [zarr](https://zarr.dev/) \n", - "standards for storing N-dimensional arrays of typed data. \n", + "Since modern computers were invented, there have existed datasets that were too large to fully read into computer memory.\n", + "These datasets have come to be known as \"[**larger-than-memory**](../back/Glossary.md#term-Larger-than-memory)\" datasets.\n", + "While these datasets may be larger than memory, we will still want to access them and perform analysis on the data.\n", + "This where chunking comes in.\n", + "\"[**Chunking**](../back/Glossary.md#term-Chunking)\" is the process of breaking down large amounts of data into smaller, more manageable pieces.\n", + "By breaking the data down into \"[**chunks**](../back/Glossary.md#term-Chunk)\", it allows for us to work with the chunks of the larger overall dataset using a structured approach without exceeding our machines available memory.\n", + "Additionally, proper chunking can allow for faster retrieval and analysis when we only need to work with part of the dataset.\n", + "\n", + "```{note}\n", + "Chunks are not another dimension to your data, but merely a map to how the dataset is partitioned into more palatable sized units for manipulation in memory.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Why should I care?\n", "\n", - "Chunks become more important as the size of the array increases. For very large arrays, it \n", - "is helpful to organize the memory it occupies into sub-units. These sub-units are the \n", - "chunks. Note that this is not another dimension to the array, but merely a map to how the \n", - "large array is partitioned into more palatable sized units for manipulation in memory. \n", - "Array-handling libraries (`numpy`, `xarray`, `pandas`, and others) will handle all of the \n", - "record-keeping to know which chunk holds a given unit of the array. \n", + "The simple reason you should care is that you are working with dataset that is larger-than-memory.\n", + "It has to be divided in some way so that only those parts of the data being actively worked on are loaded.\n", + "Otherwise, your machine would crash.\n", + "This has benefits when it comes to parallel algorithms.\n", + "If work can be performed on independent chunks, it is easy to set it up such that separate parallel workers each work on a chunk of the data simultaneously. \n", + "Therefore, proper chunking can allow for faster retrieval and analysis of the dataset.\n", + "Even datasets that are small enough to fit into memory can still technically be chunked.\n", + "So even proper chunking of them can potentially speed up retrieval and analysis.\n", + "To help you understand this, let's begin with a simple example.\n", "\n", - "### Example - first principles\n", - "A quick side-bar to illustrate two chunking patterns for a simple 2D array. This is a \n", - "simplified use-case. Consider a square array of integer values. Just for exposition, \n", - "let's use a small array 10x10. \n", + "### Example - First Principles\n", "\n", + "In this example, we will illustrate two common memory organization strategies (analagous to chunking) that computers use when handling basic multidimensional data.\n", + "To simplify this, let's consider a small 10x10 array of integer values.\n", "\n", "$$\n", "\\def\\arraystretch{2.0}\n", @@ -73,16 +82,13 @@ "\\end{array}\n", "$$\n", "\n", - "\n", - "Computer memory is not addressed in grids -- it is a linear address space, so the\n", - "2D matrix has to be organized in memory such that it presents as 2D, while being\n", - "stored as 1D. Two common options are **row-major** \n", - "order, and **column-major** order:\n", - "* Row-Major -- A row of data occupies a contiguous block of memory. This implies that \n", - " cells which are logicall adjacent vertically are not physicall near one another in \n", - " memory. The 'distance' from `r0c0` to `r0c1` (a one-cell logical move within the row) \n", - " is short, while the 'distance' to `r1c0` (a one-cell logical move within the column) \n", - " is long.\n", + "While this is easy for us humans to visualize, computer memory is not addressed in grids.\n", + "Instead, it is organized as a linear address space.\n", + "So, the 2D matrix has to be organized in memory such that it presents as 2D, while being stored as 1D.\n", + "Two common options are **row-major** order, and **column-major** order:\n", + "- **Row-Major**: A row of data occupies a contiguous block of memory.\n", + " This implies that cells which are logically adjacent vertically are not physically near one another in memory.\n", + " The \"distance\" from `r0c0` to `r0c1` (a one-cell logical move within the row) is short, while the \"distance\" to `r1c0` (a one-cell logical move within the column) is long.\n", "\n", "$$\n", "\\def\\arraystretch{2.0}\n", @@ -93,9 +99,8 @@ "\\end{array}\n", "$$\n", "\n", - "* Column-Major -- A column of the array occupies a contiguious block of memory. This \n", - " implies that cells which are adjacent horizontally are not near one another physically \n", - " in memory. \n", + "- **Column-Major**: A column of the array occupies a contiguious block of memory.\n", + " This implies that cells which are adjacent horizontally are not near one another physically in memory. \n", "\n", "$$\n", "\\def\\arraystretch{2.0}\n", @@ -106,59 +111,34 @@ "\\end{array}\n", "$$\n", "\n", + "In either mapping, `r3c5` (for example) still fetches the same value.\n", + "For a single value, this is not a problem.\n", + "The array is still indexed/addressed in the same way as far as the user is concerned, but the memory organization strategy determines how nearby an \"adjacent\" index is.\n", + "This becomes important when trying to get a subsection of the data.\n", + "For example, if the array is in row-major order and we select say `r0`, this is fast for the computer as all the data is adjacent.\n", + "However, if we wanted `c0`, then the computer has to access every 10th value in memory, which as you can imagine is not as efficient.\n", "\n", - "In either mapping, `r3c5` (for example) still fetches the same value. The array \n", - "still indexes/addresses in the same way as far as the user is concerned, but the \n", - "chunking plan determines how nearby an 'adjacent' index is. \n", - "\n", - "### Example - extend to chunking\n", - "The basic idea behind chunking is an extension of this memory organization principle. \n", - "As the size of the array increases, the chunk pattern becomes more relevant. Suppose \n", - "the data is big enough that only a row or column at a time can fit into memory. \n", - "If your data is chunked by **rows**, and you need to process a **column** of data -- your \n", - "process will need to read a lot of data, skipping most of it, to get the $i^{th}$ \n", - "column value for each row. For this analysis, it would be better if the array could \n", - "be '_re-chunked_' from row-major order to column-major order. This would favor \n", - "column operations.\n", - "\n", + "### Extend to Chunking\n", "\n", - "## Pros & Cons\n", - "Data that is well-organized to optimize one kind of analysis may not suit another \n", - "kind of analysis on the same data. Re-chunking is time-consuming, and it produces \n", - "a separate copy of the dataset, increasing storage requirements. The initial time \n", - "commitment is a one-time operation so that future analyses can run quickly. The \n", - "space commitment can be substantial if a complex dataset needs to be organized for \n", - "many different analyses.\n" + "The basic idea behind chunking is an extension of this memory organization principle.\n", + "As the size of the array increases, the chunk shape becomes more relevant.\n", + "Now suppose the square array is now larger-than-memory and stored on disk such that only a single row or column can fit into memory at a time.\n", + "If your data is chunked by row, and you need to process the $i^{th}$ column, you will have to read one row at a time into memory, skip to the $i^{th}$ column value in each row, and extract that value.\n", + "For this analysis, you can easily see why this would be slow due to the massive amount of I/O and be better if the array could instead be chunked in column-major order.\n", + "Just to make this clear, if your data was now chunked by columns, all you would have to do is read the $i^{th}$ column into memory, and you would be good to go.\n", + "Meaning you would just need a single read from disk versus reading however many rows your data has.\n", + "While handling chunks may seem like it would become complicated, array-handling libraries ([numpy](https://numpy.org/), [xarray](https://xarray.dev/), [pandas](https://pandas.pydata.org/), [dask](https://www.dask.org/), and others) will handle all of the record-keeping to know which chunk holds what data within the dataset. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Examining a Small Dataset\n", - "Let's read a sample dataset and examine how it is chunked. \n", + "## Toy Example\n", "\n", - "As a test datasaet, we've taken a random sampling of 400 stream gages for \n", - "the month of July, 2000 from the National Water Model Reanalysis Version 2.1.\n", - "The full dataset is part of the \n", - "[AWS Open Data Program](https://aws.amazon.com/opendata/), \n", - "available via the S3 bucket at \n", - "```\n", - "s3://noaa-nwm-retrospective-2-1-zarr-pds/noaa-nwm-retrospective-2-1-zarr-pds/chrtout.zarr\n", - "``` \n", - " \n", - " Our subset of that data for use in this tutorial is included in the HyTEST catalog:\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%run ../AWS.ipynb\n", - "## Establish AWS credentials" + "By now, we have hopefully answered both of the question about \"what is data chunking?\" and \"why should I care?\".\n", + "To really drive home the idea, let's apply the above theoretical example using [dask](https://docs.dask.org/en/stable/).\n", + "In this case, we will generate a square array of ones to test how different \"[**chunk shapes**](../back/Glossary.md#term-Chunk-shape)\" compare." ] }, { @@ -167,61 +147,18 @@ "metadata": {}, "outputs": [], "source": [ - "import xarray as xr \n", - "import intake\n", - "url = 'https://raw.githubusercontent.com/hytest-org/hytest/main/dataset_catalog/hytest_intake_catalog.yml'\n", - "cat = intake.open_catalog(url)\n", - "sampleData = cat['rechunking-tutorial-cloud'].to_dask()\n", - "sampleData" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The critical items to notice in this output are highlighted here: \n", - "
\n",
-    "<xarray.Dataset>\n",
-    "\n",
-    "Dimensions:     (feature_id: 400, time: 744)  <-- NOTE: Two dimensions\n",
-    "\n",
-    "                   +--- most coordinates are tied to feature_id dimension \n",
-    "                   | \n",
-    "Coordinates:       V\n",
-    "    elevation   (feature_id) float32 dask.array<chunksize=(400,), meta=np.ndarray>\n",
-    "  * feature_id  (feature_id) int32 3109 189899 239166 ... 947070134 1010003783\n",
-    "    gage_id     (feature_id) |S15 dask.array<chunksize=(400,), meta=np.ndarray>\n",
-    "    latitude    (feature_id) float32 dask.array<chunksize=(400,), meta=np.ndarray>\n",
-    "    longitude   (feature_id) float32 dask.array<chunksize=(400,), meta=np.ndarray>\n",
-    "    order       (feature_id) int32 dask.array<chunksize=(400,), meta=np.ndarray>\n",
-    "  * time        (time) datetime64[ns] 2000-07-01 ... 2000-07-31T23:00:00\n",
-    "\n",
-    "Data variables:\n",
-    "    streamflow  (time, feature_id) float64 dask.array<chunksize=(256, 16), meta=np.ndarray>\n",
-    "    velocity    (time, feature_id) float64 dask.array<chunksize=(256, 16), meta=np.ndarray>\n",
-    "                 ^^^^  ^^^^^^^^^^\n",
-    "                 the data variables are addressed by both dimensions; this is 2D data.\n",
-    "
" + "import dask.array as da" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Data Structure\n", - "\n", - "This dataset is a 'stack' of two 2D arrays. They are named 'streamflow' and 'velocity'. The indices \n", - "into each of those 2D arrays are `time` on one axis, and `feature_id` on the other. The feature id \n", - "is bound to a number of other coordinates, so you can relate/refer to a given feature by its elevation, \n", - "gage_id, latitude, longitude, or stream order. \n", + "### Chunk by Rows\n", "\n", - "Note the `chunksize` highlighted in green. This says that the data is stored in blocks mapping to 256 \n", - "adjacent time-steps for 16 adjacent features. (**NOTE**: _The original data is not chunked this way; we've \n", - "deliberately fiddled with the chunk configuration for this tutorial_)\n", - "\n", - "### Two Example Read Patterns\n", - "A time-series analysis (i.e. sampling all time-step values for a single `feature_id`) would require \n", - "multiple chunks to be fetched. " + "First, let's start with the square array chunked by rows.\n", + "We'll do a 50625x50625 array as this is about 19 GiB, which is larger than the typical memory availablity of a laptop.\n", + "The nice thing about dask is that we can see how big our array and chunks are in the output. " ] }, { @@ -230,18 +167,19 @@ "metadata": {}, "outputs": [], "source": [ - "# Fetch all the time values for a specific feature_id\n", - "sampleData['streamflow'].sel(feature_id=1343034)" + "vals = da.ones(shape=(50625, 50625), chunks=(1, 50625))\n", + "vals" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This data has 744 time-steps available, chunked into chunks of 256 values each. Three chunks are needed to hold this time-series for one feature. Not too bad, but not good either. \n", + "Now, let's see how long on average it takes to get the first column.\n", "\n", - "On the other hand, an analysis which samples all locations for a single point in time would need \n", - "to fetch multiple chunks also. \n" + "```{note}\n", + "We use the `.compute()` method on our slice to ensure its extraction is not lazily performed.\n", + "```" ] }, { @@ -250,35 +188,17 @@ "metadata": {}, "outputs": [], "source": [ - "# Fetch all the gage values for a single day\n", - "sampleData['streamflow'].sel(time='07-01-2000')" + "%%timeit\n", + "vals[:, 0].compute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "### Chunk by Columns\n", "\n", - "This dataset has 400 features, broken into chunks of 16 data values in each chunk. Many \n", - "more chunks must be fetched for this read pattern. This is much worse: the I/O engine \n", - "needs to find and retrieve 25 chunks vs 3 in the previous example. Each separate chunk/file\n", - "is a full trip through the I/O stack. \n", - "\n", - "If we were going to do either of those analyses on a very large dataset with this pattern,\n", - "we'd want to re-chunk the data to optimize for our read pattern. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Re-Chunking the Sample Data\n", - "This is a trivial example, due to the small size of the dataset -- It all fits in memory easily,\n", - "so chunking is largely unnecesary in terms of optimizing I/O (parallelism is still a consideration). \n", - "But it is worth doing, as concepts will apply when we take this to the full-sized data.\n", - "\n", - "First thing we need is a chunk plan to describe the chunk layout we want. This can be generated \n", - "using various methods. For this dataset, it's easy enough to write it manually:" + "Switching the array to be chunked by columns." ] }, { @@ -287,25 +207,15 @@ "metadata": {}, "outputs": [], "source": [ - "# Numbers are *size* of the chunk. \n", - "chunk_plan = {\n", - " 'streamflow': {'time': 744, 'feature_id': 1}, # all time records in one chunk for each feature_id\n", - " 'velocity': {'time': 744, 'feature_id': 1},\n", - " 'elevation': (400,),\n", - " 'gage_id': (400,),\n", - " 'latitude': (400,),\n", - " 'longitude': (400,), \n", - " 'order': (400,), \n", - " 'time': (744,),\n", - " 'feature_id': (400,)\n", - "}" + "vals = da.ones(shape=(50625, 50625), chunks=(50625, 1))\n", + "vals" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "With this plan, we can ask `rechunker` to re-write the data using the prescribed chunking pattern.\n" + "Time to see how much faster this is." ] }, { @@ -314,46 +224,24 @@ "metadata": {}, "outputs": [], "source": [ - "import rechunker\n", - "outfile = r\"/tmp/outfile.zarr\"\n", - "result = rechunker.rechunk(\n", - " sampleData,\n", - " chunk_plan,\n", - " \"2GB\", #<--- Max Memory\n", - " outfile ,\n", - " temp_store=\"/tmp/scratch.zarr\" \n", - ")\n", - "_ = result.execute() # Note that we must specifically direct rechunk to calculate.\n", - "# without the call to execute(), the zarr dataset will be empty, and result will hold only\n", - "# a 'task graph' outlining the calculation steps." + "%%timeit\n", + "vals[:, 0].compute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Note that `rechunker.rechunk` does not overwrite any data. If it sees that `/tmp/outfile.zarr` or `/tmp/scratch.zarr` already exist, it will balk and likely raise an exception. Be sure that these locations do not exist. \n", - "\n", - "The `rechunker` also writes a minimalist data group. Meaning that variable metadata is not consolidated. This is not a required step, but it will really spead up future workflows when the\n", - "data is read back in. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import zarr\n", - "_ = zarr.consolidate_metadata(outfile)" + "As expected, the time difference is massive when properly chunked." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Results\n", - "Let's read in the resulting re-chunked dataset to see how it looks:" + "### Balanced Chunks\n", + "\n", + "As a final example, let's check a square chunk shape that keeps about the same number of elements as the pure row and column chunking." ] }, { @@ -362,29 +250,8 @@ "metadata": {}, "outputs": [], "source": [ - "reChunkedData = xr.open_zarr(outfile)\n", - "reChunkedData" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note here that for both `streamflow` and `velocity`, the chunksize in the `time` dimension is 744 (the total number of time steps). Analyses which favor fetching all time-step values for a given `facility_id` will prefer this chunking strategy." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Comparison\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Before Re-Chunking:" + "vals = da.ones(shape=(50625, 50625), chunks=(225, 225))\n", + "vals" ] }, { @@ -393,15 +260,16 @@ "metadata": {}, "outputs": [], "source": [ - "sampleData['streamflow'].sel(feature_id=1343034)\n", - "# Note: three chunks needed to service a single feature_id" + "%%timeit\n", + "vals[:, 0].compute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### After re-chunking:" + "As we can see, this is only slightly slower when accessing the first column compared to the column chunking.\n", + "However, let's time how long it takes to access a single row." ] }, { @@ -410,30 +278,36 @@ "metadata": {}, "outputs": [], "source": [ - "reChunkedData['streamflow'].sel(feature_id=1343034) \n", - "# All data for the specified feature_id is in a single chunk\n" + "%%timeit\n", + "vals[0, :].compute()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Cleaning Up" + "As expected, it is about the same as accessing a single column.\n", + "However, that means it is drastically faster than the column chunking when accessing rows.\n", + "Therefore, a chunk shape that balances the dimensions is more generally applicable when both dimensions are needed for analysis." ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "cell_type": "markdown", + "metadata": { + "tags": [] + }, "source": [ - "import shutil\n", - "if os.path.exists(outfile):\n", - " print(f\"removing {outfile}\")\n", - " shutil.rmtree(outfile)\n", - "if os.path.exists(r\"/tmp/scratch.zarr\"):\n", - " print(\"removing scratch space\")\n", - " shutil.rmtree(r\"/tmp/scratch.zarr\")" + "## Pros & Cons to Chunking\n", + "\n", + "As a wrap up, let's review some of the pros and cons to chunking.\n", + "Some we have clearly discussed while others may be more subtle.\n", + "The primary pro, as we hopefully conveyed with our previous example, is that well chunked data substantially speeds up any analysis that favors that chunk shape.\n", + "However, this becomes a con when you change your analysis to one that favors a new chunk shape.\n", + "In other words, data that is well-organized to optimize one kind of analysis may not suit another kind of analysis on the same data.\n", + "While not a problem for our example here, changing the chunk shape (known as \"[**rechunking**](../back/Glossary.md#term-Rechunking)\") on an established dataset is time-consuming, and it produces a separate copy of the dataset, increasing storage requirements.\n", + "The space commitment can be substantial if a complex dataset needs to be organized for many different analyses.\n", + "If our example above used unique values that we wanted to keep as we changed chunking, this would have meant that rather than having a single ~19 GiB dataset, we would have needed to keep all three, tripling our storage to almost 60 GiB.\n", + "Therefore, selecting an appropriate chunk shape is critical when generating widely used datasets." ] } ], @@ -453,7 +327,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.12.0" }, "vscode": { "interpreter": { diff --git a/101/WriteChunkedFiles.ipynb b/101/WriteChunkedFiles.ipynb new file mode 100644 index 0000000..e0219f8 --- /dev/null +++ b/101/WriteChunkedFiles.ipynb @@ -0,0 +1,480 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "bd95288c-1388-4732-9626-ca4014335d66", + "metadata": {}, + "source": [ + "# Writing Chunked Files" + ] + }, + { + "cell_type": "markdown", + "id": "b2240372-1697-4083-873b-d5b25653a2d0", + "metadata": {}, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "This notebook is based on the [Xarray User-guide for reading and writing Zarr](https://docs.xarray.dev/en/stable/user-guide/io.html#zarr).\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "markdown", + "id": "9262bf36-4d8b-4b1d-9d7c-6730462cf7a6", + "metadata": {}, + "source": [ + "The goal of this notebook is to learn how to load a collection of NetCDF files, chunk the data, write the data in Zarr format, and confirm the proper creation of the Zarr store.\n", + "We will be writing to our local storage for simplicity (as this is just a tutorial notebook), but you can easily change the output path to be anywhere including cloud storage." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c10a55d-a68f-472f-929f-a64e2ddab733", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "import numpy as np\n", + "import hvplot.xarray" + ] + }, + { + "cell_type": "markdown", + "id": "f3203b0b-6377-4b12-ae9e-5afb21dacc3a", + "metadata": {}, + "source": [ + "## Example Dataset\n", + "\n", + "In this notebook, we will use the daily gridMET precipitation dataset as an example for reading data and writing to Zarr.\n", + "The data is currently hosted on the HyTEST OSN as a collection NetCDF files.\n", + "To get the files, we will use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) to open each year of precipitation data to a list.\n", + "Then, we can read in the all the files at once using [`xarray.open_mfdataset`](https://docs.xarray.dev/en/stable/generated/xarray.open_mfdataset.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad046ac6-2559-4944-bbc2-ca7066cdbc8f", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem(\n", + " 's3',\n", + " anon=True, # anonymous = does not require credentials\n", + " client_kwargs={'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + ")\n", + "precip_files = [fs.open(file) for file in fs.glob('s3://mdmf/gdp/netcdf/gridmet/gridmet/pr_*.nc')]\n", + "ds = xr.open_mfdataset(\n", + " precip_files,\n", + " chunks={},\n", + " engine='h5netcdf'\n", + ")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "65d41caf-b46e-46bd-a0f7-d4d69e0fc573", + "metadata": {}, + "source": [ + "## Selecting Chunk Shape and Size\n", + "\n", + "As we can see in the rich HTML output of our dataset, the NetCDF files were already chunked with pattern of `{'day': 61, 'lat': 98, 'lon': 231}`.\n", + "However, the size of these chunks are relatively small and near the lower limit of an acceptable chunk size of 10 MiB.\n", + "So, it would be better if we could increase our chunk sizes to say 70-110 MiB.\n", + "To do this, we will simply use multiples of the current chunks as to not completely rechunk the dataset (grouping chunks is way faster than completely changing chunk shape).\n", + "Our goal will be to try and evenly distribute the number of chunks between the time and space dimensions.\n", + "\n", + "First, let's check how many chunks are in the temporal and spatial dimensions with the current chunk shape." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4bc95190-e181-4ce7-b5d4-cf3ccfb8b7e7", + "metadata": {}, + "outputs": [], + "source": [ + "time_chunk_shape = ds.precipitation_amount.encoding['preferred_chunks']['day']\n", + "lat_chunk_shape = ds.precipitation_amount.encoding['preferred_chunks']['lat']\n", + "lon_chunk_shape = ds.precipitation_amount.encoding['preferred_chunks']['lon']\n", + "\n", + "print(f\"Number of temporal chunks: {np.ceil(len(ds.day) / time_chunk_shape)}\")\n", + "print(f\"Number of spatial chunks: {np.ceil(len(ds.lat) / lat_chunk_shape) * np.ceil(len(ds.lon) / lon_chunk_shape)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9e6d4183-6ed3-41cc-9829-ef8a601fb7ae", + "metadata": {}, + "source": [ + "Okay, so there are about 7 times as many time chunks as there are spatial chunks.\n", + "Let's try to balance this better so that there are an approximately equal amount.\n", + "We will do this by simply increasing the time chunk shape by a factor of 7.\n", + "Then, we can double check our chunk size to see if it aligns with out chunk size goal.\n", + "\n", + "```{note}\n", + "Also by increasing our temporal chunk shape by a factor of seven, it is now larger than a whole year.\n", + "This means if we only wanted a single year, we would at most need to read two chunks.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f7477f21-beed-4dda-a14b-b6c05fd4f0b6", + "metadata": {}, + "outputs": [], + "source": [ + "chunk_plan = {\n", + " \"day\": time_chunk_shape * 7, \n", + " \"lat\" : lat_chunk_shape,\n", + " \"lon\" : lon_chunk_shape\n", + "}\n", + "\n", + "bytes_per_value = ds.precipitation_amount.dtype.itemsize\n", + "\n", + "print(f\"Number of temporal chunks: {np.ceil(len(ds.day) / chunk_plan['day'])}\")\n", + "print(f\"Number of spatial chunks: {np.ceil(len(ds.lat) / chunk_plan['lat']) * np.ceil(len(ds.lon) / chunk_plan['lon'])}\")\n", + "print(f\"Chunk size in MiB: {(bytes_per_value * chunk_plan['day'] * chunk_plan['lat'] * chunk_plan['lon']) / 2 ** 10 / 2 ** 10}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5bf00120-5465-4c90-8855-e2dc5c6dca4f", + "metadata": {}, + "source": [ + "Nice!\n", + "That got us the exact same number of chunks and the chunk size we were looking for.\n", + "As a final check, let's make sure none of the ending chunks contain <50% data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a49fdfe2-7621-454f-9d43-5ed183aff7b2", + "metadata": {}, + "outputs": [], + "source": [ + "print(f\"Number of day chunks: {(len(ds.day) / chunk_plan['day'])}\")\n", + "print(f\"Number of lat chunks: {(len(ds.lat) / chunk_plan['lat'])}\")\n", + "print(f\"Number of lon chunks: {(len(ds.lon) / chunk_plan['lon'])}\")" + ] + }, + { + "cell_type": "markdown", + "id": "8f0988e8-8174-4d16-9876-d332d24c7421", + "metadata": {}, + "source": [ + "Perfect!\n", + "So the final day chunk is only 77% full, but that is good enough.\n", + "Let's now chunk the dataset to our chunking plan." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ddfd13c6-e7be-4e0e-861c-134317a87533", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds.chunk(chunk_plan)\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "1d206001-3e5e-4805-b87a-de0c22bcd7d6", + "metadata": {}, + "source": [ + "Now, let's save this data to a Zarr!" + ] + }, + { + "cell_type": "markdown", + "id": "78aa84b3-4482-47f3-8e61-105e7b4e3b16", + "metadata": {}, + "source": [ + "## Writing Chunked Zarr" + ] + }, + { + "cell_type": "markdown", + "id": "72ad607c-8491-45ea-bb90-ec7394419dd6", + "metadata": {}, + "source": [ + "As discussed in the [Xarray User-guide for reading and writing Zarr](https://docs.xarray.dev/en/stable/user-guide/io.html#specifying-chunks-in-a-zarr-store), chunks are specified to our Zarr store in one of three ways in the preferential order of:\n", + "\n", + " 1. Manual chunk sizing through the use of the `encoding` argument\n", + " 2. Automatic chunking based on chunks of the dask arrays\n", + " 3. Default chunk behavior determined by the Zarr library\n", + "\n", + "In our case, we updated the dask array chunks by calling `ds.chunk()`.\n", + "Therefore, we have the correct chunks and should be good to go.\n", + "\n", + "```{tip}\n", + "This is our preferred method over using the `encoding` argument, as the positional ordering of the chunk shape in the `encoding` argument must match the positional ordering of the dimensions in each array.\n", + "If they do not match you can get incorrect chunk shapes in the Zarr store.\n", + "\n", + "If you have multiple variables, using `encoding` could allow for specifying individual chunking shapes for each variable.\n", + "However, if this is the case, we recommend updating each variable individually using, for example, `ds.precipitation_amount.chunk()` to change the individual variable chunk shape.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edd08cea-4469-466b-b8f6-193abd094a2a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's actually use only one time chunk as this is an\n", + "# example and we don't want to write 90 GiB\n", + "ds_write = ds.isel(day=slice(0, chunk_plan['day']))\n", + "\n", + "outfile = \"gridmet_precip.zarr\"\n", + "_ = ds_write.to_zarr(outfile)" + ] + }, + { + "cell_type": "markdown", + "id": "8a5fa0fe-7d6a-4808-9a36-b56f469e95d7", + "metadata": {}, + "source": [ + "Now, let's read in the just-written dataset to verify its integrity and chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "044e3c96-60e4-4fb7-b185-a36e693ddc55", + "metadata": {}, + "outputs": [], + "source": [ + "ds_read = xr.open_dataset(outfile, engine='zarr', chunks={})\n", + "ds_read" + ] + }, + { + "cell_type": "markdown", + "id": "3f8cf24d-7ba5-4ccb-b468-521df61df28d", + "metadata": {}, + "source": [ + "Great! Everything looks good!" + ] + }, + { + "cell_type": "markdown", + "id": "98f88d0e-e2a6-41fd-9afa-917f5ab4c0dd", + "metadata": {}, + "source": [ + "## Assessing Compression\n", + "\n", + "Now that our Zarr store is made, let's check how much the data was compressed.\n", + "By default, [Zarr uses the Blosc compressor](https://docs.xarray.dev/en/stable/user-guide/io.html#zarr-compressors-and-filters) when calling [`xarray.Dataset.to_zarr()`](https://docs.xarray.dev/en/stable/generated/xarray.Dataset.to_zarr.html) if we don't specify a compressor in the `encoding`.\n", + "So, our data should be compressed by default, and we can examine each chunk on disk to confirm their compression factor.\n", + "\n", + "To examine this, let's create a new local `filesystem` to get the file info." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d85378aa-17cf-42ae-9a59-851d5f1222f4", + "metadata": {}, + "outputs": [], + "source": [ + "fs_local = fsspec.filesystem('local')" + ] + }, + { + "cell_type": "markdown", + "id": "9d14b6aa-86d5-4bbb-a546-80e8aa4b6157", + "metadata": {}, + "source": [ + "Now, estimate the file sizes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6312d4ea-f1a3-4f52-9392-1fb6b000b199", + "metadata": {}, + "outputs": [], + "source": [ + "# Exclude any hidden files (i.e., starts with .)\n", + "chunkfiles = fs_local.glob(outfile + \"/precipitation_amount/[!.]*\")\n", + "filesize = np.array([fs_local.du(file) for file in chunkfiles])\n", + "filesize_MiB = xr.DataArray(data=filesize / 2**10 / 2**10, name='Size', attrs={'units': 'MiB'})\n", + "\n", + "print(\"Stored Chunk Size Summary Statistics [MiB]:\\n\"\n", + " f\"Total: {filesize_MiB.sum():.4f}\\n\"\n", + " f\"Minimum: {filesize_MiB.min():.4f}\\n\"\n", + " f\"Mean: {filesize_MiB.mean():.4f}\\n\"\n", + " f\"Maximum: {filesize_MiB.max():.4f}\")\n", + "filesize_MiB.hvplot.hist(ylabel='Counts')" + ] + }, + { + "cell_type": "markdown", + "id": "2c0c0dda-8a16-4cc3-8952-460978a6ef6f", + "metadata": {}, + "source": [ + "As we can see, the total dataset (excluding coordinates) is only 85 MiB on disk, with chunk sizes varying from 76 KiB to 4.8 MiB.\n", + "This size is drastically smaller than the quoted total size for the xarray output, which said 2.58 GiB.\n", + "Same for the individual chunks, which were quoted at 73.75 MiB.\n", + "Let's get an exact comparison and compression ratio for the data we read in." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62ebc894-d4f5-4582-b917-8611797c38ab", + "metadata": {}, + "outputs": [], + "source": [ + "bytes_per_value = ds_read.precipitation_amount.dtype.itemsize\n", + "total_size = ds_read['precipitation_amount'].size * bytes_per_value\n", + "chunk_size = np.array(ds_read['precipitation_amount'].encoding['chunks']).prod() * bytes_per_value\n", + "print(\"Read-in Chunk Size Summary Statistics:\\n\"\n", + " f\"Total: {total_size / (2**10)**3:.4f} [GiB]\\n\"\n", + " f\"Chunks: {chunk_size / (2**10)**2:.4f} [MiB]\")\n", + "\n", + "print(\"\\n\"\n", + " \"Compression Ratio Summary Statistics:\\n\"\n", + " f\"Total: {total_size / filesize.sum():.3f}\\n\"\n", + " f\"Minimum: {(chunk_size / filesize).min():.4f}\\n\"\n", + " f\"Mean: {(chunk_size / filesize).mean():.4f}\\n\"\n", + " f\"Maximum: {(chunk_size / filesize).max():.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "54041c1f-03a5-4544-910b-e8bd79ff5fa2", + "metadata": {}, + "source": [ + "Ooph! This tells us that we get an astonishing average compression ratio of 30:1 on this particular data.\n", + "Pretty good results.\n", + "\n", + "## Appending New Chunk\n", + "\n", + "Since this compression is so good, let's go ahead and add another time chunk onto our existing Zarr store.\n", + "This is simple in xarray, especially since we are just appending another time chunk.\n", + "All we have to do is [add `append_dim` to our `.to_zarr()` call to append to the time dimension](https://docs.xarray.dev/en/stable/user-guide/io.html#modifying-existing-zarr-stores)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f95b58c-f36f-4204-bb90-509449f87bcd", + "metadata": {}, + "outputs": [], + "source": [ + "ds_write = ds.isel(day=slice(chunk_plan['day'], chunk_plan['day']* 2))\n", + "_ = ds_write.to_zarr(outfile, append_dim='day')" + ] + }, + { + "cell_type": "markdown", + "id": "c7c1185f-4292-4450-a354-751e99c54c63", + "metadata": {}, + "source": [ + "Now, let's read in the appended dataset to verify everything worked." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f376daab-ca29-4740-a506-afb348b4b35d", + "metadata": {}, + "outputs": [], + "source": [ + "ds_read = xr.open_dataset(outfile, engine='zarr', chunks={})\n", + "ds_read" + ] + }, + { + "cell_type": "markdown", + "id": "0d30e43d-6bf0-4f85-ab22-0c693e08ef1f", + "metadata": {}, + "source": [ + "Sweet!\n", + "That looks like it worked as expected.\n", + "Let's now double check the compression on these files." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd24f82f-e026-40bd-a051-60385f822479", + "metadata": {}, + "outputs": [], + "source": [ + "# Exclude any hidden files (i.e., starts with .)\n", + "chunkfiles = fs_local.glob(outfile + \"/precipitation_amount/[!.]*\")\n", + "filesize = np.array([fs_local.du(file) for file in chunkfiles])\n", + "filesize_MiB = xr.DataArray(data=filesize / 2**10 / 2**10, name='Size', attrs={'units': 'MiB'})\n", + "\n", + "print(\"Stored Chunk Size Summary Statistics [MiB]:\\n\"\n", + " f\"Total: {filesize_MiB.sum():.4f}\\n\"\n", + " f\"Minimum: {filesize_MiB.min():.4f}\\n\"\n", + " f\"Mean: {filesize_MiB.mean():.4f}\\n\"\n", + " f\"Maximum: {filesize_MiB.max():.4f}\")\n", + "filesize_MiB.hvplot.hist(ylabel='Counts')" + ] + }, + { + "cell_type": "markdown", + "id": "d3b98935-4e14-407e-b7a6-aa2a081cfa1a", + "metadata": {}, + "source": [ + "Looks like we stayed at the same levels of compression which is great.\n", + "\n", + "## Clean Up\n", + "\n", + "So, hopefully now you know the basics of how to create a Zarr store from some NetCDF files and set its chunks' shape.\n", + "The same methods would apply when rechunking a dataset, which we will get into next.\n", + "\n", + "As we don't want to keep this Zarr on our local machine, let's go ahead and delete it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4761366c-ad04-457b-8b1d-a6d9610054d5", + "metadata": {}, + "outputs": [], + "source": [ + "# Clean up by deleting the zarr store\n", + "fs_local.rm(outfile, recursive=True)" + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/101/index.md b/101/index.md index 56bba4d..4b289cf 100644 --- a/101/index.md +++ b/101/index.md @@ -1,21 +1,10 @@ -# Chunking 101 +# Introduction to Chunking -A gentle introduction to concepts and workflows. - -This introductory chapter will illustrate some key concepts for writing -chunked data (in zarr format) to object storage in 'the cloud'. We'll be -eventually be writing to an OSN storage device using the S3 API, although -you could, in theory, write anywhere (including a local file system). - -The illustration dataset will be PRISM(v2), accessed via its OpenDAP -endpoint at - - -Buckle up... we will get up to speed fast. +In this first series of notebooks, we will go over basic introductory topics associated with chunking. +As you will soon learn, "chunking" is an an essential part of the data preparation workflow, particularly for large datasets. +The key concepts you should understand have after this series include: ```{tableofcontents} ``` - -The dask performance report for the total conversion workflow is [here](../performance_reports/OpenDAP_to_S3-perfreport.html) - +Buckle up... we will get up to speed fast. diff --git a/201/00_grid_rechunk.ipynb b/201/00_grid_rechunk.ipynb deleted file mode 100644 index 45c1343..0000000 --- a/201/00_grid_rechunk.ipynb +++ /dev/null @@ -1,58 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "23c8086d-13e4-47af-811c-482464eed528", - "metadata": { - "tags": [] - }, - "source": [ - "# Rechunk NWM 1km gridded output\n", - "\n", - "The NWM 1km gridded output is available on AWS S3 as hourly NetCDF files, so we we would like to rechunk them to be read by the Zarr library.\n", - "\n", - "One approach would be to download all the files and work on them locally, like Pangeo forge often does. We will try a different approach, of first kerchunking the NetCDF files to make them more performant, then running rechunker on the kerchunked dataset. In both steps, we will use a Dask Gateway cluster, with workers writing directly to S3.\n" - ] - }, - { - "cell_type": "markdown", - "id": "885c6a17-a487-4ddd-8596-ac2006b14068", - "metadata": {}, - "source": [ - "## Chunking and rechunking resources\n", - "* [\"Making Earth Science data more accessible\"](https://www.slideserve.com/kiaria/making-earth-science-data-more-accessible-experience-with-chunking-and-compression), AMS presentation slides by Russ Rew, Unidata (2013)\n", - "* [\"Rechunker: The missing link for chunked array analytics\"](https://medium.com/pangeo/rechunker-the-missing-link-for-chunked-array-analytics-5b2359e9dc11), Medium blog post by Ryan Abernathy, Columbia University (2020)\n", - "* [\"Rechunker\" Python Library Documentation](https://rechunker.readthedocs.io/en/latest/)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "90a81208-88ea-4921-9e21-aade42fc3952", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.10.9" - }, - "vscode": { - "interpreter": { - "hash": "21742c3f70e60132a0f53ab9a02119f1da5d00e790acd69466294df8491d8f10" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/03_rechunk_broken.ipynb b/201/03_rechunk_broken.ipynb deleted file mode 100644 index 4e0204b..0000000 --- a/201/03_rechunk_broken.ipynb +++ /dev/null @@ -1,6772 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a4108776-2095-4696-a4b6-fef7c2496fce", - "metadata": {}, - "source": [ - "# Rechunk the kerchunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "import fsspec.implementations.reference\n", - "import zarr\n", - "import xarray as xr\n", - "from pathlib import Path\n", - "\n", - "from rechunker import rechunk" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0.5.1'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import rechunker\n", - "rechunker.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'2.14.2'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import zarr\n", - "zarr.__version__" - ] - }, - { - "cell_type": "markdown", - "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", - "metadata": {}, - "source": [ - "#### Start a Dask Gateway cluster\n", - "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Region: us-west-2\n", - "No Cluster running.\n", - "Starting new cluster.\n", - "Setting Cluster Environment Variable AWS_DEFAULT_REGION us-west-2\n", - "Setting Fixed Scaling workers=30\n", - "Reconnect client to clear cache\n", - "client.dashboard_link (for new browser tab/window or dashboard searchbar in Jupyterhub):\n", - "https://nebari.esipfed.org/gateway/clusters/dev.6940f68830f24c31a7531b96dd43a6da/status\n", - "Propagating environment variables to workers\n", - "Using environment: users/users-pangeofu\n" - ] - } - ], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append('/shared/users/rsignell/lib')\n", - "import ebdpy as ebd\n", - "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", - "\n", - "client, cluster, gateway = ebd.start_dask_cluster(\n", - " profile=os.environ['AWS_PROFILE'],\n", - " worker_max=30,\n", - " region='us-west-2', \n", - " worker_profile='Medium Worker',\n", - " use_existing_cluster=False,\n", - " adaptive_scaling=False, \n", - " wait_for_cluster=False, \n", - " propagate_env=True)" - ] - }, - { - "cell_type": "markdown", - "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", - "metadata": {}, - "source": [ - "#### Open Kerchunked Dataset JSON for one year" - ] - }, - { - "cell_type": "raw", - "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", - "metadata": {}, - "source": [ - "year = '1984'\n", - "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", - "\n", - "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", - "r_opts = {'anon':True}\n", - "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "d80146a7-d6a5-4df9-b8ee-b39d2470535c", - "metadata": {}, - "outputs": [], - "source": [ - "#client.close()" - ] - }, - { - "cell_type": "markdown", - "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", - "metadata": {}, - "source": [ - "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.7 s, sys: 256 ms, total: 4.96 s\n", - "Wall time: 7.04 s\n" - ] - } - ], - "source": [ - "%%time\n", - "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", - " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", - "metadata": {}, - "source": [ - "#### Select high-priority vars only" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 116631, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs      object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 144, y: 3840, x: 4608)>\n",
-       "dask.array<getitem, shape=(144, 3840, 4608), dtype=float64, chunksize=(1, 3840, 4608), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds['ACCET'].isel(time=slice(0,144))" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "15d511f0-f82e-4250-930c-145feff08d27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Conventions': 'CF-1.6',\n", - " 'GDAL_DataType': 'Generic',\n", - " 'TITLE': 'OUTPUT FROM WRF-Hydro v5.2.0-beta2',\n", - " 'code_version': 'v5.2.0-beta2',\n", - " 'model_configuration': 'retrospective',\n", - " 'model_initialization_time': '1979-02-01_00:00:00',\n", - " 'model_output_type': 'land',\n", - " 'model_output_valid_time': '1979-02-01_03:00:00',\n", - " 'model_total_valid_times': 472,\n", - " 'proj4': '+proj=lcc +units=m +a=6370000.0 +b=6370000.0 +lat_1=30.0 +lat_2=60.0 +lat_0=40.0 +lon_0=-97.0 +x_0=0 +y_0=0 +k_0=1.0 +nadgrids=@null +wktext +no_defs'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.attrs" - ] - }, - { - "cell_type": "markdown", - "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", - "metadata": {}, - "source": [ - "#### set up zarr stores for temporary and final zarr stores on S3" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", - "metadata": {}, - "outputs": [], - "source": [ - "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", - "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "61d64b30-f089-4200-8e98-56dd5d80bc48", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write.rm(temp_name, recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "99febcd6-6e57-4997-a296-56e6e047fa0e", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write.rm(target_name, recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", - "metadata": {}, - "outputs": [], - "source": [ - "temp_store = fs_write.get_mapper(temp_name)\n", - "target_store = fs_write.get_mapper(target_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.drop('crs')" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", - "metadata": {}, - "outputs": [], - "source": [ - "a = len(ds.time)/(144/2)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", - "metadata": {}, - "outputs": [], - "source": [ - "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.640266927083334" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a/b" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", - "metadata": {}, - "outputs": [], - "source": [ - "#client.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "76f39719-735f-4a8a-96ab-f50018a92441", - "metadata": {}, - "outputs": [], - "source": [ - "#from dask.distributed import Client" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", - "metadata": {}, - "outputs": [], - "source": [ - "#client = Client(threads_per_worker=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", - "metadata": {}, - "outputs": [], - "source": [ - "#client.amm.start()" - ] - }, - { - "cell_type": "raw", - "id": "5793ef68-f5d0-4e4a-b0d6-c774afd4b72f", - "metadata": {}, - "source": [ - "import zarr.storage\n", - "from numcodecs import Zstd\n", - "zarr.storage.default_compressor = Zstd(level=9)" - ] - }, - { - "cell_type": "markdown", - "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", - "metadata": {}, - "source": [ - "#### Rechunk!" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", - "metadata": {}, - "outputs": [], - "source": [ - "rechunked = rechunk(ds.isel(time=slice(0,144)), target_chunks={'y':96*2, 'x':132*2, 'time':144/2},\n", - " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", - "metadata": {}, - "outputs": [ - { - "ename": "KilledWorker", - "evalue": "Attempted to run task ('copy_intermediate_to_write-5ed80e53379ab8fab117fb3baf6c8bb2', 2) on 3 different workers, but all those workers died while running it. The last worker that attempt to run the task was tls://10.10.82.121:33131. Inspecting worker logs is often a good next step to diagnose what went wrong. For more information see https://distributed.dask.org/en/stable/killed.html.", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKilledWorker\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m:1\u001b[0m\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/rechunker/api.py:70\u001b[0m, in \u001b[0;36mRechunked.execute\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mexecute\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 56\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 57\u001b[0m \u001b[38;5;124;03m Execute the rechunking.\u001b[39;00m\n\u001b[1;32m 58\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[38;5;124;03m :func:`rechunker.rechunk`.\u001b[39;00m\n\u001b[1;32m 69\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m---> 70\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_executor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute_plan\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_plan\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 71\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_target\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/rechunker/executors/dask.py:48\u001b[0m, in \u001b[0;36mDaskPipelineExecutor.execute_plan\u001b[0;34m(self, plan, **kwargs)\u001b[0m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mexecute_plan\u001b[39m(\u001b[38;5;28mself\u001b[39m, plan: Delayed, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m---> 48\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdask\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mplan\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/dask/base.py:599\u001b[0m, in \u001b[0;36mcompute\u001b[0;34m(traverse, optimize_graph, scheduler, get, *args, **kwargs)\u001b[0m\n\u001b[1;32m 596\u001b[0m keys\u001b[38;5;241m.\u001b[39mappend(x\u001b[38;5;241m.\u001b[39m__dask_keys__())\n\u001b[1;32m 597\u001b[0m postcomputes\u001b[38;5;241m.\u001b[39mappend(x\u001b[38;5;241m.\u001b[39m__dask_postcompute__())\n\u001b[0;32m--> 599\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[43mschedule\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdsk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkeys\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 600\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m repack([f(r, \u001b[38;5;241m*\u001b[39ma) \u001b[38;5;28;01mfor\u001b[39;00m r, (f, a) \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(results, postcomputes)])\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/client.py:3168\u001b[0m, in \u001b[0;36mClient.get\u001b[0;34m(self, dsk, keys, workers, allow_other_workers, resources, sync, asynchronous, direct, retries, priority, fifo_timeout, actors, **kwargs)\u001b[0m\n\u001b[1;32m 3166\u001b[0m should_rejoin \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m 3167\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 3168\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgather\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpacked\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43masynchronous\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43masynchronous\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdirect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirect\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3169\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 3170\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m f \u001b[38;5;129;01min\u001b[39;00m futures\u001b[38;5;241m.\u001b[39mvalues():\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/client.py:2328\u001b[0m, in \u001b[0;36mClient.gather\u001b[0;34m(self, futures, errors, direct, asynchronous)\u001b[0m\n\u001b[1;32m 2326\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2327\u001b[0m local_worker \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m-> 2328\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msync\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2329\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_gather\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2330\u001b[0m \u001b[43m \u001b[49m\u001b[43mfutures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2331\u001b[0m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2332\u001b[0m \u001b[43m \u001b[49m\u001b[43mdirect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2333\u001b[0m \u001b[43m \u001b[49m\u001b[43mlocal_worker\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlocal_worker\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2334\u001b[0m \u001b[43m \u001b[49m\u001b[43masynchronous\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43masynchronous\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2335\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/utils.py:345\u001b[0m, in \u001b[0;36mSyncMethodMixin.sync\u001b[0;34m(self, func, asynchronous, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m future\n\u001b[1;32m 344\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 345\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msync\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 346\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mloop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallback_timeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallback_timeout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\n\u001b[1;32m 347\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/utils.py:412\u001b[0m, in \u001b[0;36msync\u001b[0;34m(loop, func, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m error:\n\u001b[1;32m 411\u001b[0m typ, exc, tb \u001b[38;5;241m=\u001b[39m error\n\u001b[0;32m--> 412\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exc\u001b[38;5;241m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m 413\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 414\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/utils.py:385\u001b[0m, in \u001b[0;36msync..f\u001b[0;34m()\u001b[0m\n\u001b[1;32m 383\u001b[0m future \u001b[38;5;241m=\u001b[39m wait_for(future, callback_timeout)\n\u001b[1;32m 384\u001b[0m future \u001b[38;5;241m=\u001b[39m asyncio\u001b[38;5;241m.\u001b[39mensure_future(future)\n\u001b[0;32m--> 385\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m future\n\u001b[1;32m 386\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[1;32m 387\u001b[0m error \u001b[38;5;241m=\u001b[39m sys\u001b[38;5;241m.\u001b[39mexc_info()\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/tornado/gen.py:769\u001b[0m, in \u001b[0;36mRunner.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 766\u001b[0m exc_info \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 768\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 769\u001b[0m value \u001b[38;5;241m=\u001b[39m \u001b[43mfuture\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 770\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[1;32m 771\u001b[0m exc_info \u001b[38;5;241m=\u001b[39m sys\u001b[38;5;241m.\u001b[39mexc_info()\n", - "File \u001b[0;32m/home/conda/users/13259f350cf05dffa52b42290281692a474bd10ee5089522e374427087d365d6-20230321-174204-546117-151-pangeofu/lib/python3.10/site-packages/distributed/client.py:2191\u001b[0m, in \u001b[0;36mClient._gather\u001b[0;34m(self, futures, errors, direct, local_worker)\u001b[0m\n\u001b[1;32m 2189\u001b[0m exc \u001b[38;5;241m=\u001b[39m CancelledError(key)\n\u001b[1;32m 2190\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2191\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exception\u001b[38;5;241m.\u001b[39mwith_traceback(traceback)\n\u001b[1;32m 2192\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[1;32m 2193\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m errors \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mskip\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n", - "\u001b[0;31mKilledWorker\u001b[0m: Attempted to run task ('copy_intermediate_to_write-5ed80e53379ab8fab117fb3baf6c8bb2', 2) on 3 different workers, but all those workers died while running it. The last worker that attempt to run the task was tls://10.10.82.121:33131. Inspecting worker logs is often a good next step to diagnose what went wrong. For more information see https://distributed.dask.org/en/stable/killed.html." - ] - } - ], - "source": [ - "%%time\n", - "rechunked.execute(retries=10)" - ] - }, - { - "cell_type": "raw", - "id": "aecea580-d6b2-46d3-84be-ed24354def9d", - "metadata": {}, - "source": [ - "def trim_memory() -> int:\n", - " libc = ctypes.CDLL('libc.so.6')\n", - " return libc.malloc_trim(0)" - ] - }, - { - "cell_type": "raw", - "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", - "metadata": {}, - "source": [ - "client.run(trim_memory)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "zarr.convenience.consolidate_metadata(target_store)" - ] - }, - { - "cell_type": "markdown", - "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", - "metadata": {}, - "source": [ - "#### Explore the rechunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", - "metadata": {}, - "outputs": [], - "source": [ - "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 144, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 144, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "cee33374-49d0-4607-a812-c9ed98eefb48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 144, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-7e3d64a2ef877f4a0434821c8cc36ce5ACCET, shape=(144, 3840, 4608), dtype=float64, chunksize=(72, 192, 264), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import hvplot.xarray\n" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", - "metadata": {}, - "outputs": [ - { - "data": {}, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ], - "text/plain": [ - ":Curve [time] (ACCET)" - ] - }, - "execution_count": 33, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "1002" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET[:,2000,2000].hvplot(x='time')" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "9093e34d-ced3-4c20-9485-7449fd673dde", - "metadata": {}, - "outputs": [], - "source": [ - "client.close()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4a5070b-2ca8-4794-b354-495cbb81adf1", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeofu", - "language": "python", - "name": "conda-env-users-users-pangeofu-py" - }, - "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.10.9" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/03_rechunk_fsstore.ipynb b/201/03_rechunk_fsstore.ipynb deleted file mode 100644 index 2cf86a7..0000000 --- a/201/03_rechunk_fsstore.ipynb +++ /dev/null @@ -1,4824 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a4108776-2095-4696-a4b6-fef7c2496fce", - "metadata": {}, - "source": [ - "# Rechunk the kerchunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "import fsspec.implementations.reference\n", - "import zarr\n", - "import xarray as xr\n", - "from pathlib import Path\n", - "\n", - "from rechunker import rechunk" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0.5.0'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import rechunker\n", - "rechunker.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'2.13.3'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import zarr\n", - "zarr.__version__" - ] - }, - { - "cell_type": "markdown", - "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", - "metadata": {}, - "source": [ - "#### Start a Dask Gateway cluster\n", - "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Region: us-west-2\n", - "Existing Dask clusters:\n", - "Cluster Index c_idx: 0 / Name: dev.86df4e246414441789173f5a323ec67b ClusterStatus.RUNNING\n", - "Using existing cluster [0].\n", - "Setting Fixed Scaling workers=30\n", - "Reconnect client to clear cache\n", - "client.dashboard_link (for new browser tab/window or dashboard searchbar in Jupyterhub):\n", - "https://nebari.esipfed.org/gateway/clusters/dev.86df4e246414441789173f5a323ec67b/status\n", - "Propagating environment variables to workers\n", - "Using environment: users/users-pangeo50\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "coiled.analytics.computation.interval is set to '10m'. Ignoring this old default value, using '15s' instead. To override, use any value other than '10m'.\n" - ] - } - ], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append('/shared/users/rsignell/lib')\n", - "import ebdpy as ebd\n", - "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", - "\n", - "client, cluster, gateway = ebd.start_dask_cluster(\n", - " profile=os.environ['AWS_PROFILE'],\n", - " worker_max=30,\n", - " region='us-west-2', \n", - " worker_profile='Medium Worker',\n", - " use_existing_cluster=True,\n", - " adaptive_scaling=False, \n", - " wait_for_cluster=False, \n", - " propagate_env=True)" - ] - }, - { - "cell_type": "markdown", - "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", - "metadata": {}, - "source": [ - "#### Open Kerchunked Dataset JSON for one year" - ] - }, - { - "cell_type": "raw", - "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", - "metadata": {}, - "source": [ - "year = '1984'\n", - "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", - "\n", - "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", - "r_opts = {'anon':True}\n", - "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", - "metadata": {}, - "source": [ - "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", - "metadata": {}, - "outputs": [], - "source": [ - "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", - " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", - "metadata": {}, - "source": [ - "#### Select high-priority vars only" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 116631, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs      object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 144, y: 3840, x: 4608)>\n",
-       "dask.array<getitem, shape=(144, 3840, 4608), dtype=float64, chunksize=(1, 3840, 4608), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds['ACCET'].isel(time=slice(0,144))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "15d511f0-f82e-4250-930c-145feff08d27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Conventions': 'CF-1.6',\n", - " 'GDAL_DataType': 'Generic',\n", - " 'TITLE': 'OUTPUT FROM WRF-Hydro v5.2.0-beta2',\n", - " 'code_version': 'v5.2.0-beta2',\n", - " 'model_configuration': 'retrospective',\n", - " 'model_initialization_time': '1979-02-01_00:00:00',\n", - " 'model_output_type': 'land',\n", - " 'model_output_valid_time': '1979-02-01_03:00:00',\n", - " 'model_total_valid_times': 472,\n", - " 'proj4': '+proj=lcc +units=m +a=6370000.0 +b=6370000.0 +lat_1=30.0 +lat_2=60.0 +lat_0=40.0 +lon_0=-97.0 +x_0=0 +y_0=0 +k_0=1.0 +nadgrids=@null +wktext +no_defs'}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.attrs" - ] - }, - { - "cell_type": "markdown", - "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", - "metadata": {}, - "source": [ - "#### set up zarr stores for temporary and final zarr stores on S3" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", - "metadata": {}, - "outputs": [], - "source": [ - "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", - "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61d64b30-f089-4200-8e98-56dd5d80bc48", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write.rm(temp_name, recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99febcd6-6e57-4997-a296-56e6e047fa0e", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write.rm(target_name, recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", - "metadata": {}, - "outputs": [], - "source": [ - "temp_store = fs_write.get_mapper(temp_name)\n", - "target_store = fs_write.get_mapper(target_name)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3e9891e-edd8-4d01-902d-f196cd6932a0", - "metadata": {}, - "outputs": [], - "source": [ - "temp_store = zarr.storage.FFStore(temp_name)\n", - "target_store = zarr.storage.FSStore(target_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.drop('crs')" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", - "metadata": {}, - "outputs": [], - "source": [ - "a = len(ds.time)/(144/2)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", - "metadata": {}, - "outputs": [], - "source": [ - "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.640266927083334" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a/b" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", - "metadata": {}, - "outputs": [], - "source": [ - "#client.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "76f39719-735f-4a8a-96ab-f50018a92441", - "metadata": {}, - "outputs": [], - "source": [ - "#from dask.distributed import Client" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", - "metadata": {}, - "outputs": [], - "source": [ - "#client = Client(threads_per_worker=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", - "metadata": {}, - "outputs": [], - "source": [ - "#client.amm.start()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e4ab8ecb-f1d0-46f5-bad4-a008fa819ea0", - "metadata": {}, - "outputs": [], - "source": [ - "import zarr.storage\n", - "from numcodecs import Zstd\n", - "zarr.storage.default_compressor = Zstd(level=9)" - ] - }, - { - "cell_type": "markdown", - "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", - "metadata": {}, - "source": [ - "#### Rechunk!" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", - "metadata": {}, - "outputs": [], - "source": [ - "rechunked = rechunk(ds.isel(time=slice(0,144)), target_chunks={'y':96*2, 'x':132*2, 'time':144/2},\n", - " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 5.61 s, sys: 380 ms, total: 5.99 s\n", - "Wall time: 2min 23s\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/conda/users/7eabd1068e2d4c33f6c1a158421b1506445f2b6d569062096a4034455ed28f1f-20230315-135602-197474-122-pangeo50/lib/python3.9/site-packages/dask_gateway/client.py:1014: RuntimeWarning: coroutine 'rpc.close_rpc' was never awaited\n", - " self.scheduler_comm.close_rpc()\n" - ] - } - ], - "source": [ - "%%time\n", - "rechunked.execute(retries=10)" - ] - }, - { - "cell_type": "raw", - "id": "aecea580-d6b2-46d3-84be-ed24354def9d", - "metadata": {}, - "source": [ - "def trim_memory() -> int:\n", - " libc = ctypes.CDLL('libc.so.6')\n", - " return libc.malloc_trim(0)" - ] - }, - { - "cell_type": "raw", - "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", - "metadata": {}, - "source": [ - "client.run(trim_memory)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", - "metadata": {}, - "outputs": [], - "source": [ - "zarr.convenience.consolidate_metadata(target_store)" - ] - }, - { - "cell_type": "markdown", - "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", - "metadata": {}, - "source": [ - "#### Explore the rechunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", - "metadata": {}, - "outputs": [], - "source": [ - "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", - "metadata": {}, - "outputs": [], - "source": [ - "ds2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cee33374-49d0-4607-a812-c9ed98eefb48", - "metadata": {}, - "outputs": [], - "source": [ - "ds2.ACCET" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", - "metadata": {}, - "outputs": [], - "source": [ - "import hvplot.xarray\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", - "metadata": {}, - "outputs": [], - "source": [ - "ds2.ACCET[:,2000,2000].hvplot(x='time')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9093e34d-ced3-4c20-9485-7449fd673dde", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo50", - "language": "python", - "name": "conda-env-users-users-pangeo50-py" - }, - "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.9.15" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/03_rechunk_works-Copy1.ipynb b/201/03_rechunk_works-Copy1.ipynb deleted file mode 100644 index 49c7c3b..0000000 --- a/201/03_rechunk_works-Copy1.ipynb +++ /dev/null @@ -1,6686 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a4108776-2095-4696-a4b6-fef7c2496fce", - "metadata": {}, - "source": [ - "# Rechunk the kerchunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "import fsspec.implementations.reference\n", - "import zarr\n", - "import xarray as xr\n", - "from pathlib import Path\n", - "\n", - "from rechunker import rechunk" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0.5.1'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import rechunker\n", - "rechunker.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'2.13.3'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import zarr\n", - "zarr.__version__" - ] - }, - { - "cell_type": "markdown", - "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", - "metadata": {}, - "source": [ - "#### Start a Dask Gateway cluster\n", - "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Region: us-west-2\n", - "Existing Dask clusters:\n", - "Cluster Index c_idx: 0 / Name: dev.cfce53af031244b2ba9880afa0165089 ClusterStatus.RUNNING\n", - "Using existing cluster [0].\n", - "Setting Fixed Scaling workers=30\n", - "Reconnect client to clear cache\n", - "client.dashboard_link (for new browser tab/window or dashboard searchbar in Jupyterhub):\n", - "https://nebari.esipfed.org/gateway/clusters/dev.cfce53af031244b2ba9880afa0165089/status\n", - "Propagating environment variables to workers\n", - "Using environment: users/users-pangeo\n" - ] - } - ], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append('/shared/users/rsignell/lib')\n", - "import ebdpy as ebd\n", - "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", - "\n", - "client, cluster, gateway = ebd.start_dask_cluster(\n", - " profile=os.environ['AWS_PROFILE'],\n", - " worker_max=30,\n", - " region='us-west-2', \n", - " worker_profile='Medium Worker',\n", - " use_existing_cluster=True,\n", - " adaptive_scaling=False, \n", - " wait_for_cluster=False, \n", - " propagate_env=True)" - ] - }, - { - "cell_type": "markdown", - "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", - "metadata": {}, - "source": [ - "#### Open Kerchunked Dataset JSON for one year" - ] - }, - { - "cell_type": "raw", - "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", - "metadata": {}, - "source": [ - "year = '1984'\n", - "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", - "\n", - "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", - "r_opts = {'anon':True}\n", - "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", - "metadata": {}, - "source": [ - "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3.17 s, sys: 112 ms, total: 3.28 s\n", - "Wall time: 3.8 s\n" - ] - } - ], - "source": [ - "%%time\n", - "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", - " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", - "metadata": {}, - "source": [ - "#### Select high-priority vars only" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 116631, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs      object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 72, y: 3840, x: 4608)>\n",
-       "dask.array<getitem, shape=(72, 3840, 4608), dtype=float64, chunksize=(1, 3840, 4608), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds['ACCET'].isel(time=slice(0,72))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "15d511f0-f82e-4250-930c-145feff08d27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Conventions': 'CF-1.6',\n", - " 'GDAL_DataType': 'Generic',\n", - " 'TITLE': 'OUTPUT FROM WRF-Hydro v5.2.0-beta2',\n", - " 'code_version': 'v5.2.0-beta2',\n", - " 'model_configuration': 'retrospective',\n", - " 'model_initialization_time': '1979-02-01_00:00:00',\n", - " 'model_output_type': 'land',\n", - " 'model_output_valid_time': '1979-02-01_03:00:00',\n", - " 'model_total_valid_times': 472,\n", - " 'proj4': '+proj=lcc +units=m +a=6370000.0 +b=6370000.0 +lat_1=30.0 +lat_2=60.0 +lat_0=40.0 +lon_0=-97.0 +x_0=0 +y_0=0 +k_0=1.0 +nadgrids=@null +wktext +no_defs'}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.attrs" - ] - }, - { - "cell_type": "markdown", - "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", - "metadata": {}, - "source": [ - "#### set up zarr stores for temporary and final zarr stores on S3" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", - "metadata": {}, - "outputs": [], - "source": [ - "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", - "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7c043b20-3e43-435e-9e45-7023b178698a", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write.rm(temp_name, recursive=True)\n", - "fs_write.rm(target_name, recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", - "metadata": {}, - "outputs": [], - "source": [ - "temp_store = fs_write.get_mapper(temp_name)\n", - "target_store = fs_write.get_mapper(target_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.drop('crs')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", - "metadata": {}, - "outputs": [], - "source": [ - "a = len(ds.time)/(144/2)" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", - "metadata": {}, - "outputs": [], - "source": [ - "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.640266927083334" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a/b" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", - "metadata": {}, - "outputs": [], - "source": [ - "#client.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "76f39719-735f-4a8a-96ab-f50018a92441", - "metadata": {}, - "outputs": [], - "source": [ - "#from dask.distributed import Client" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", - "metadata": {}, - "outputs": [], - "source": [ - "#client = Client(threads_per_worker=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", - "metadata": {}, - "outputs": [], - "source": [ - "#client.amm.start()" - ] - }, - { - "cell_type": "raw", - "id": "5793ef68-f5d0-4e4a-b0d6-c774afd4b72f", - "metadata": {}, - "source": [ - "import zarr.storage\n", - "from numcodecs import Zstd\n", - "zarr.storage.default_compressor = Zstd(level=9)" - ] - }, - { - "cell_type": "markdown", - "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", - "metadata": {}, - "source": [ - "#### Rechunk!" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", - "metadata": {}, - "outputs": [], - "source": [ - "rechunked = rechunk(ds.isel(time=slice(0,72)), target_chunks={'y':96*2, 'x':132*2, 'time':72},\n", - " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.46 s, sys: 165 ms, total: 4.63 s\n", - "Wall time: 1min 32s\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "rechunked.execute(retries=10)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "zarr.convenience.consolidate_metadata(target_store)" - ] - }, - { - "cell_type": "markdown", - "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", - "metadata": {}, - "source": [ - "#### Explore the rechunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", - "metadata": {}, - "outputs": [], - "source": [ - "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 72, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 72, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "cee33374-49d0-4607-a812-c9ed98eefb48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 144, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-4e2c432fb5ab0d7258d1d4529d62748cACCET, shape=(144, 3840, 4608), dtype=float64, chunksize=(72, 192, 264), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import hvplot.xarray\n" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", - "metadata": {}, - "outputs": [ - { - "data": {}, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ], - "text/plain": [ - ":Curve [time] (ACCET)" - ] - }, - "execution_count": 31, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "1002" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET[:,2000,2000].hvplot(x='time')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.10.9" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/03_rechunk_works.ipynb b/201/03_rechunk_works.ipynb deleted file mode 100644 index b8e2df6..0000000 --- a/201/03_rechunk_works.ipynb +++ /dev/null @@ -1,8479 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a4108776-2095-4696-a4b6-fef7c2496fce", - "metadata": {}, - "source": [ - "# Rechunk the kerchunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "import fsspec.implementations.reference\n", - "import zarr\n", - "import xarray as xr\n", - "from pathlib import Path\n", - "\n", - "from rechunker import rechunk" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0.5.1'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import rechunker\n", - "rechunker.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'2.13.3'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import zarr\n", - "zarr.__version__" - ] - }, - { - "cell_type": "markdown", - "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", - "metadata": {}, - "source": [ - "#### Start a Dask Gateway cluster\n", - "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Region: us-west-2\n", - "Existing Dask clusters:\n", - "Cluster Index c_idx: 0 / Name: dev.6940f68830f24c31a7531b96dd43a6da ClusterStatus.RUNNING\n", - "Using existing cluster [0].\n", - "Setting Fixed Scaling workers=30\n", - "Reconnect client to clear cache\n", - "client.dashboard_link (for new browser tab/window or dashboard searchbar in Jupyterhub):\n", - "https://nebari.esipfed.org/gateway/clusters/dev.6940f68830f24c31a7531b96dd43a6da/status\n", - "Propagating environment variables to workers\n", - "Using environment: users/users-pangeo\n" - ] - } - ], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append('/shared/users/rsignell/lib')\n", - "import ebdpy as ebd\n", - "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", - "\n", - "client, cluster, gateway = ebd.start_dask_cluster(\n", - " profile=os.environ['AWS_PROFILE'],\n", - " worker_max=30,\n", - " region='us-west-2', \n", - " worker_profile='Medium Worker',\n", - " use_existing_cluster=True,\n", - " adaptive_scaling=False, \n", - " wait_for_cluster=False, \n", - " propagate_env=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "4351541b-de66-4135-853e-16bfd52a39a6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "
\n", - "
\n", - "

Client

\n", - "

Client-3f3be597-c8d8-11ed-93a3-fa8a693ae98c

\n", - " \n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "\n", - "
Connection method: Cluster objectCluster type: dask_gateway.GatewayCluster
\n", - " Dashboard: https://nebari.esipfed.org/gateway/clusters/dev.6940f68830f24c31a7531b96dd43a6da/status\n", - "
\n", - "\n", - " \n", - "\n", - " \n", - "
\n", - "

Cluster Info

\n", - "
\n", - "

GatewayCluster

\n", - " \n", - "
\n", - "\n", - "
\n", - " \n", - "\n", - "
\n", - "
" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "client" - ] - }, - { - "cell_type": "markdown", - "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", - "metadata": {}, - "source": [ - "#### Open Kerchunked Dataset JSON for one year" - ] - }, - { - "cell_type": "raw", - "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", - "metadata": {}, - "source": [ - "year = '1984'\n", - "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", - "\n", - "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", - "r_opts = {'anon':True}\n", - "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", - "metadata": {}, - "source": [ - "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.57 s, sys: 296 ms, total: 4.87 s\n", - "Wall time: 6.09 s\n" - ] - } - ], - "source": [ - "%%time\n", - "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", - " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", - " backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 3840, 1, 4608), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", - "metadata": {}, - "source": [ - "#### Select high-priority vars only" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 116631, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(1, 3840, 4608), meta=np.ndarray>\n",
-       "    crs      object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 72, y: 3840, x: 4608)>\n",
-       "dask.array<getitem, shape=(72, 3840, 4608), dtype=float64, chunksize=(1, 3840, 4608), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds['ACCET'].isel(time=slice(0,72))" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "15d511f0-f82e-4250-930c-145feff08d27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Conventions': 'CF-1.6',\n", - " 'GDAL_DataType': 'Generic',\n", - " 'TITLE': 'OUTPUT FROM WRF-Hydro v5.2.0-beta2',\n", - " 'code_version': 'v5.2.0-beta2',\n", - " 'model_configuration': 'retrospective',\n", - " 'model_initialization_time': '1979-02-01_00:00:00',\n", - " 'model_output_type': 'land',\n", - " 'model_output_valid_time': '1979-02-01_03:00:00',\n", - " 'model_total_valid_times': 472,\n", - " 'proj4': '+proj=lcc +units=m +a=6370000.0 +b=6370000.0 +lat_1=30.0 +lat_2=60.0 +lat_0=40.0 +lon_0=-97.0 +x_0=0 +y_0=0 +k_0=1.0 +nadgrids=@null +wktext +no_defs'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.attrs" - ] - }, - { - "cell_type": "markdown", - "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", - "metadata": {}, - "source": [ - "#### set up zarr stores for temporary and final zarr stores on S3" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", - "metadata": {}, - "outputs": [], - "source": [ - "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", - "metadata": {}, - "outputs": [], - "source": [ - "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", - "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "7c043b20-3e43-435e-9e45-7023b178698a", - "metadata": {}, - "outputs": [], - "source": [ - "try:\n", - " fs_write.rm(temp_name, recursive=True)\n", - "except:\n", - " pass\n", - "try:\n", - " fs_write.rm(target_name, recursive=True)\n", - "except:\n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", - "metadata": {}, - "outputs": [], - "source": [ - "temp_store = fs_write.get_mapper(temp_name)\n", - "target_store = fs_write.get_mapper(target_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.drop('crs')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1619" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = int(len(ds.time)/(72))\n", - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "349.09090909090907" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))\n", - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.637760416666667" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a/b" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", - "metadata": {}, - "outputs": [], - "source": [ - "#client.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "76f39719-735f-4a8a-96ab-f50018a92441", - "metadata": {}, - "outputs": [], - "source": [ - "#from dask.distributed import Client" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", - "metadata": {}, - "outputs": [], - "source": [ - "#client = Client(threads_per_worker=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", - "metadata": {}, - "outputs": [], - "source": [ - "#client.amm.start()" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "26f90202-40e2-410c-b05c-f4a312b9364e", - "metadata": {}, - "outputs": [], - "source": [ - "import zarr.storage\n", - "from numcodecs import Zstd\n", - "zarr.storage.default_compressor = Zstd(level=9)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "152c8ba0-63f9-42bf-81f8-e18969c9ed06", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "14.598144" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "(192 * 264 * 72)*4/1e6" - ] - }, - { - "cell_type": "markdown", - "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", - "metadata": {}, - "source": [ - "#### Rechunk!" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", - "metadata": {}, - "outputs": [], - "source": [ - "rechunked = rechunk(ds.isel(time=slice(0,72)), target_chunks={'y':96*2, 'x':132*2, 'time':72},\n", - " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.9 s, sys: 359 ms, total: 5.26 s\n", - "Wall time: 2min 30s\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "rechunked.execute(retries=10)" - ] - }, - { - "cell_type": "raw", - "id": "aecea580-d6b2-46d3-84be-ed24354def9d", - "metadata": {}, - "source": [ - "def trim_memory() -> int:\n", - " libc = ctypes.CDLL('libc.so.6')\n", - " return libc.malloc_trim(0)" - ] - }, - { - "cell_type": "raw", - "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", - "metadata": {}, - "source": [ - "client.run(trim_memory)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "zarr.convenience.consolidate_metadata(target_store)" - ] - }, - { - "cell_type": "markdown", - "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", - "metadata": {}, - "source": [ - "#### Explore the rechunked dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", - "metadata": {}, - "outputs": [], - "source": [ - "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 72, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 72, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "cee33374-49d0-4607-a812-c9ed98eefb48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'ACCET' (time: 72, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-5d4df04ce5afa1b88ab5b376e193e5e5ACCET, shape=(72, 3840, 4608), dtype=float64, chunksize=(72, 192, 264), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Accumulated total ET\n",
-       "    units:           mm\n",
-       "    valid_range:     [-100000, 100000000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-10\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Accumulated total ET\n", - " units: mm\n", - " valid_range: [-100000, 100000000]" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls.length === 0 && js_modules.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'gridstack': {'exports': 'GridStack'}}});\n", - " require([\"gridstack\"], function(GridStack) {\n", - "\twindow.GridStack = GridStack\n", - "\ton_load()\n", - " })\n", - " require([\"notyf\"], function() {\n", - "\ton_load()\n", - " })\n", - " root._bokeh_is_loading = css_urls.length + 2;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", - " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/0.14.4/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(urls[i])\n", - " }\n", - " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/0.14.4/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(urls[i])\n", - " }\n", - " } for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " if (skip.indexOf(url) >= 0) {\n", - "\tif (!window.requirejs) {\n", - "\t on_load();\n", - "\t}\n", - "\tcontinue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (var i = 0; i < js_modules.length; i++) {\n", - " var url = js_modules[i];\n", - " if (skip.indexOf(url) >= 0) {\n", - "\tif (!window.requirejs) {\n", - "\t on_load();\n", - "\t}\n", - "\tcontinue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [];\n", - " var js_modules = [];\n", - " var css_urls = [];\n", - " var inline_js = [ function(Bokeh) {\n", - " inject_raw_css(\"table.panel-df {\\n margin-left: auto;\\n margin-right: auto;\\n border: none;\\n border-collapse: collapse;\\n border-spacing: 0;\\n color: black;\\n font-size: 12px;\\n table-layout: fixed;\\n width: 100%;\\n}\\n\\n.panel-df tr, .panel-df th, .panel-df td {\\n text-align: right;\\n vertical-align: middle;\\n padding: 0.5em 0.5em !important;\\n line-height: normal;\\n white-space: normal;\\n max-width: none;\\n border: none;\\n}\\n\\n.panel-df tbody {\\n display: table-row-group;\\n vertical-align: middle;\\n border-color: inherit;\\n}\\n\\n.panel-df tbody tr:nth-child(odd) {\\n background: #f5f5f5;\\n}\\n\\n.panel-df thead {\\n border-bottom: 1px solid black;\\n vertical-align: bottom;\\n}\\n\\n.panel-df tr:hover {\\n background: lightblue !important;\\n cursor: pointer;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".codehilite .hll { background-color: #ffffcc }\\n.codehilite { background: #f8f8f8; }\\n.codehilite .c { color: #408080; font-style: italic } /* Comment */\\n.codehilite .err { border: 1px solid #FF0000 } /* Error */\\n.codehilite .k { color: #008000; font-weight: bold } /* Keyword */\\n.codehilite .o { color: #666666 } /* Operator */\\n.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\\n.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */\\n.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */\\n.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\\n.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */\\n.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */\\n.codehilite .gd { color: #A00000 } /* Generic.Deleted */\\n.codehilite .ge { font-style: italic } /* Generic.Emph */\\n.codehilite .gr { color: #FF0000 } /* Generic.Error */\\n.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */\\n.codehilite .gi { color: #00A000 } /* Generic.Inserted */\\n.codehilite .go { color: #888888 } /* Generic.Output */\\n.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\\n.codehilite .gs { font-weight: bold } /* Generic.Strong */\\n.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\\n.codehilite .gt { color: #0044DD } /* Generic.Traceback */\\n.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\\n.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\\n.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\\n.codehilite .kp { color: #008000 } /* Keyword.Pseudo */\\n.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\\n.codehilite .kt { color: #B00040 } /* Keyword.Type */\\n.codehilite .m { color: #666666 } /* Literal.Number */\\n.codehilite .s { color: #BA2121 } /* Literal.String */\\n.codehilite .na { color: #7D9029 } /* Name.Attribute */\\n.codehilite .nb { color: #008000 } /* Name.Builtin */\\n.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */\\n.codehilite .no { color: #880000 } /* Name.Constant */\\n.codehilite .nd { color: #AA22FF } /* Name.Decorator */\\n.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */\\n.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\\n.codehilite .nf { color: #0000FF } /* Name.Function */\\n.codehilite .nl { color: #A0A000 } /* Name.Label */\\n.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\\n.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */\\n.codehilite .nv { color: #19177C } /* Name.Variable */\\n.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\\n.codehilite .w { color: #bbbbbb } /* Text.Whitespace */\\n.codehilite .mb { color: #666666 } /* Literal.Number.Bin */\\n.codehilite .mf { color: #666666 } /* Literal.Number.Float */\\n.codehilite .mh { color: #666666 } /* Literal.Number.Hex */\\n.codehilite .mi { color: #666666 } /* Literal.Number.Integer */\\n.codehilite .mo { color: #666666 } /* Literal.Number.Oct */\\n.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */\\n.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */\\n.codehilite .sc { color: #BA2121 } /* Literal.String.Char */\\n.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */\\n.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\\n.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */\\n.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\\n.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */\\n.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\\n.codehilite .sx { color: #008000 } /* Literal.String.Other */\\n.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */\\n.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */\\n.codehilite .ss { color: #19177C } /* Literal.String.Symbol */\\n.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */\\n.codehilite .fm { color: #0000FF } /* Name.Function.Magic */\\n.codehilite .vc { color: #19177C } /* Name.Variable.Class */\\n.codehilite .vg { color: #19177C } /* Name.Variable.Global */\\n.codehilite .vi { color: #19177C } /* Name.Variable.Instance */\\n.codehilite .vm { color: #19177C } /* Name.Variable.Magic */\\n.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */\\n\\n.markdown h1 { margin-block-start: 0.34em }\\n.markdown h2 { margin-block-start: 0.42em }\\n.markdown h3 { margin-block-start: 0.5em }\\n.markdown h4 { margin-block-start: 0.67em }\\n.markdown h5 { margin-block-start: 0.84em }\\n.markdown h6 { margin-block-start: 1.17em }\\n.markdown ul { padding-inline-start: 2em }\\n.markdown ol { padding-inline-start: 2em }\\n.markdown strong { font-weight: 600 }\\n.markdown a { color: -webkit-link }\\n.markdown a { color: -moz-hyperlinkText }\\n\\n.markdown .codehilite {\\n padding: 1rem 1.25rem;\\n margin-top: 1rem;\\n margin-bottom: 1rem;\\n border-radius: 0.25rem;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".bk.panel-widget-box {\\n min-height: 20px;\\n background-color: #f5f5f5;\\n border: 1px solid #e3e3e3;\\n border-radius: 4px;\\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.05);\\n box-shadow: inset 0 1px 1px rgba(0,0,0,.05);\\n overflow-x: hidden;\\n overflow-y: hidden;\\n}\\n\\n.scrollable {\\n overflow: scroll;\\n}\\n\\nprogress {\\n appearance: none;\\n -moz-appearance: none;\\n -webkit-appearance: none;\\n border: none;\\n height: 20px;\\n background-color: whiteSmoke;\\n border-radius: 3px;\\n box-shadow: 0 2px 3px rgba(0,0,0,.5) inset;\\n color: royalblue;\\n position: relative;\\n margin: 0 0 1.5em;\\n}\\n\\nprogress[value]::-webkit-progress-bar {\\n background-color: whiteSmoke;\\n border-radius: 3px;\\n box-shadow: 0 2px 3px rgba(0,0,0,.5) inset;\\n}\\n\\nprogress[value]::-webkit-progress-value {\\n position: relative;\\n background-size: 35px 20px, 100% 100%, 100% 100%;\\n border-radius:3px;\\n}\\n\\nprogress.active:not([value])::before {\\n background-position: 10%;\\n animation-name: stripes;\\n animation-duration: 3s;\\n animation-timing-function: linear;\\n animation-iteration-count: infinite;\\n}\\n\\nprogress[value]::-moz-progress-bar {\\n background-size: 35px 20px, 100% 100%, 100% 100%;\\n border-radius:3px;\\n}\\n\\nprogress:not([value])::-moz-progress-bar {\\n border-radius:3px;\\n background: linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%) left/2.5em 1.5em;\\n}\\n\\nprogress.active:not([value])::-moz-progress-bar {\\n background-position: 10%;\\n animation-name: stripes;\\n animation-duration: 3s;\\n animation-timing-function: linear;\\n animation-iteration-count: infinite;\\n}\\n\\nprogress.active:not([value])::-webkit-progress-bar {\\n background-position: 10%;\\n animation-name: stripes;\\n animation-duration: 3s;\\n animation-timing-function: linear;\\n animation-iteration-count: infinite;\\n}\\n\\nprogress.primary[value]::-webkit-progress-value { background-color: #007bff; }\\nprogress.primary:not([value])::before { background-color: #007bff; }\\nprogress.primary:not([value])::-webkit-progress-bar { background-color: #007bff; }\\nprogress.primary::-moz-progress-bar { background-color: #007bff; }\\n\\nprogress.secondary[value]::-webkit-progress-value { background-color: #6c757d; }\\nprogress.secondary:not([value])::before { background-color: #6c757d; }\\nprogress.secondary:not([value])::-webkit-progress-bar { background-color: #6c757d; }\\nprogress.secondary::-moz-progress-bar { background-color: #6c757d; }\\n\\nprogress.success[value]::-webkit-progress-value { background-color: #28a745; }\\nprogress.success:not([value])::before { background-color: #28a745; }\\nprogress.success:not([value])::-webkit-progress-bar { background-color: #28a745; }\\nprogress.success::-moz-progress-bar { background-color: #28a745; }\\n\\nprogress.danger[value]::-webkit-progress-value { background-color: #dc3545; }\\nprogress.danger:not([value])::before { background-color: #dc3545; }\\nprogress.danger:not([value])::-webkit-progress-bar { background-color: #dc3545; }\\nprogress.danger::-moz-progress-bar { background-color: #dc3545; }\\n\\nprogress.warning[value]::-webkit-progress-value { background-color: #ffc107; }\\nprogress.warning:not([value])::before { background-color: #ffc107; }\\nprogress.warning:not([value])::-webkit-progress-bar { background-color: #ffc107; }\\nprogress.warning::-moz-progress-bar { background-color: #ffc107; }\\n\\nprogress.info[value]::-webkit-progress-value { background-color: #17a2b8; }\\nprogress.info:not([value])::before { background-color: #17a2b8; }\\nprogress.info:not([value])::-webkit-progress-bar { background-color: #17a2b8; }\\nprogress.info::-moz-progress-bar { background-color: #17a2b8; }\\n\\nprogress.light[value]::-webkit-progress-value { background-color: #f8f9fa; }\\nprogress.light:not([value])::before { background-color: #f8f9fa; }\\nprogress.light:not([value])::-webkit-progress-bar { background-color: #f8f9fa; }\\nprogress.light::-moz-progress-bar { background-color: #f8f9fa; }\\n\\nprogress.dark[value]::-webkit-progress-value { background-color: #343a40; }\\nprogress.dark:not([value])::-webkit-progress-bar { background-color: #343a40; }\\nprogress.dark:not([value])::before { background-color: #343a40; }\\nprogress.dark::-moz-progress-bar { background-color: #343a40; }\\n\\nprogress:not([value])::-webkit-progress-bar {\\n border-radius: 3px;\\n background: linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%) left/2.5em 1.5em;\\n}\\nprogress:not([value])::before {\\n content:\\\" \\\";\\n position:absolute;\\n height: 20px;\\n top:0;\\n left:0;\\n right:0;\\n bottom:0;\\n border-radius: 3px;\\n background: linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%) left/2.5em 1.5em;\\n}\\n\\n@keyframes stripes {\\n from {background-position: 0%}\\n to {background-position: 100%}\\n}\\n\\n.bk-root .bk.loader {\\n overflow: hidden;\\n}\\n\\n.bk.loader::after {\\n content: \\\"\\\";\\n border-radius: 50%;\\n -webkit-mask-image: radial-gradient(transparent 50%, rgba(0, 0, 0, 1) 54%);\\n width: 100%;\\n height: 100%;\\n left: 0;\\n top: 0;\\n position: absolute;\\n}\\n\\n.bk-root .bk.loader.dark::after {\\n background: #0f0f0f;\\n}\\n\\n.bk-root .bk.loader.light::after {\\n background: #f0f0f0;\\n}\\n\\n.bk-root .bk.loader.spin::after {\\n animation: spin 2s linear infinite;\\n}\\n\\n.bk-root div.bk.loader.spin.primary-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #007bff 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.secondary-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #6c757d 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.success-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #28a745 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.danger-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #dc3545 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.warning-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #ffc107 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.info-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #17a2b8 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.light-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #f8f9fa 50%);\\n}\\n\\n.bk-root div.bk.loader.dark-light::after {\\n background: linear-gradient(135deg, #f0f0f0 50%, transparent 50%), linear-gradient(45deg, #f0f0f0 50%, #343a40 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.primary-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #007bff 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.secondary-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #6c757d 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.success-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #28a745 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.danger-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #dc3545 50%)\\n}\\n\\n.bk-root div.bk.loader.spin.warning-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #ffc107 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.info-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #17a2b8 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.light-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #f8f9fa 50%);\\n}\\n\\n.bk-root div.bk.loader.spin.dark-dark::after {\\n background: linear-gradient(135deg, #0f0f0f 50%, transparent 50%), linear-gradient(45deg, #0f0f0f 50%, #343a40 50%);\\n}\\n\\n/* Safari */\\n@-webkit-keyframes spin {\\n 0% { -webkit-transform: rotate(0deg); }\\n 100% { -webkit-transform: rotate(360deg); }\\n}\\n\\n@keyframes spin {\\n 0% { transform: rotate(0deg); }\\n 100% { transform: rotate(360deg); }\\n}\\n\\n.dot div {\\n height: 100%;\\n width: 100%;\\n border: 1px solid #000 !important;\\n background-color: #fff;\\n border-radius: 50%;\\n display: inline-block;\\n}\\n\\n.dot-filled div {\\n height: 100%;\\n width: 100%;\\n border: 1px solid #000 !important;\\n border-radius: 50%;\\n display: inline-block;\\n}\\n\\n.dot-filled.primary div {\\n background-color: #007bff;\\n}\\n\\n.dot-filled.secondary div {\\n background-color: #6c757d;\\n}\\n\\n.dot-filled.success div {\\n background-color: #28a745;\\n}\\n\\n.dot-filled.danger div {\\n background-color: #dc3545;\\n}\\n\\n.dot-filled.warning div {\\n background-color: #ffc107;\\n}\\n\\n.dot-filled.info div {\\n background-color: #17a2b8;\\n}\\n\\n.dot-filled.dark div {\\n background-color: #343a40;\\n}\\n\\n.dot-filled.light div {\\n background-color: #f8f9fa;\\n}\\n\\n/* Slider editor */\\n.slider-edit .bk-input-group .bk-input {\\n border: 0;\\n border-radius: 0;\\n min-height: 0;\\n padding-left: 0;\\n padding-right: 0;\\n font-weight: bold;\\n}\\n\\n.slider-edit .bk-input-group .bk-spin-wrapper {\\n display: contents;\\n}\\n\\n.slider-edit .bk-input-group .bk-spin-wrapper .bk.bk-spin-btn-up {\\n top: -6px;\\n}\\n\\n.slider-edit .bk-input-group .bk-spin-wrapper .bk.bk-spin-btn-down {\\n bottom: 3px;\\n}\\n\\n/* JSON Pane */\\n.bk-root .json-formatter-row .json-formatter-string, .bk-root .json-formatter-row .json-formatter-stringifiable {\\n white-space: pre-wrap;\\n}\\n\\n.ql-bubble .ql-editor {\\n border: 1px solid #ccc;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".bk.debugger-card {\\n border: 1px solid rgba(0,0,0,1);\\n color: rgba(255,255,255,1);\\n background-color: rgba(0,0,0,1);\\n border-radius: 0rem;\\n}\\n.bk.debugger-card-header {\\n align-items: center;\\n text-align: left;\\n background-color: rgba(0, 0, 0, 1)!important;\\n color: rgba(255, 255, 255, 1);\\n border-radius: 0rem;\\n display: inline-flex;\\n justify-content: start;\\n width: 100%;\\n}\\n.bk.debugger-card-button {\\n background-color: transparent;\\n color: rgba(255, 255, 255, 1);\\n margin-left: 0.5em;\\n}\\n.bk.debugger-card-title {\\n align-items: center;\\n text-align: left;\\n color: rgba(255, 255, 255, 1);\\n font-size: 1em;\\n overflow-wrap: break-word;\\n}\\n\\n/* Special debugger buttons for clearing and saving */\\n.bk button.special_btn {\\n width: 25px;\\n height: 25px;\\n background-color: black;\\n color: white;\\n display: inline-block;\\n}\\n\\n\\n.bk button.special_btn .tooltiptext {\\n visibility: hidden;\\n width: 100px;\\n background-color: darkgray;\\n color: #fff;\\n text-align: center;\\n border-radius: 6px;\\n padding: 5px 0;\\n\\n /* Position the tooltip */\\n position: relative;\\n z-index: 1;\\n top: 100%;\\n left: 100%;\\n margin-left: -100px;\\n display: block;\\n}\\n\\n.bk button.special_btn:hover .tooltiptext {\\n visibility: visible;\\n}\\n\\n\\n\\n.bk button.clear_btn:hover .shown { display: none;}\\n.bk button.clear_btn:hover:before { content: \\\"\\u2611\\\"; }\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".bk.card {\\n border: 1px solid rgba(0,0,0,.125);\\n border-radius: 0.25rem;\\n}\\n.bk.accordion {\\n border: 1px solid rgba(0,0,0,.125);\\n}\\n.bk.card-header {\\n align-items: center;\\n background-color: rgba(0, 0, 0, 0.03);\\n border-radius: 0.25rem;\\n display: inline-flex;\\n justify-content: start;\\n width: 100%;\\n}\\n.bk.accordion-header {\\n align-items: center;\\n background-color: rgba(0, 0, 0, 0.03);\\n border-radius: 0;\\n display: flex;\\n justify-content: start;\\n width: 100%;\\n}\\n.bk.card-button {\\n background-color: transparent;\\n margin-left: 0.5em;\\n}\\n.bk.card-header-row {\\n position: relative !important;\\n}\\n.bk.card-title {\\n align-items: center;\\n font-size: 1.4em;\\n font-weight: bold;\\n overflow-wrap: break-word;\\n}\\n.bk.card-header-row > .bk {\\n overflow-wrap: break-word;\\n text-align: center;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".json-formatter-row {\\n font-family: monospace;\\n}\\n.json-formatter-row,\\n.json-formatter-row a,\\n.json-formatter-row a:hover {\\n color: black;\\n text-decoration: none;\\n}\\n.json-formatter-row .json-formatter-row {\\n margin-left: 1rem;\\n}\\n.json-formatter-row .json-formatter-children.json-formatter-empty {\\n opacity: 0.5;\\n margin-left: 1rem;\\n}\\n.json-formatter-row .json-formatter-children.json-formatter-empty:after {\\n display: none;\\n}\\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\\n content: \\\"No properties\\\";\\n}\\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\\n content: \\\"[]\\\";\\n}\\n.json-formatter-row .json-formatter-string,\\n.json-formatter-row .json-formatter-stringifiable {\\n color: green;\\n white-space: pre;\\n word-wrap: break-word;\\n}\\n.json-formatter-row .json-formatter-number {\\n color: blue;\\n}\\n.json-formatter-row .json-formatter-boolean {\\n color: red;\\n}\\n.json-formatter-row .json-formatter-null {\\n color: #855A00;\\n}\\n.json-formatter-row .json-formatter-undefined {\\n color: #ca0b69;\\n}\\n.json-formatter-row .json-formatter-function {\\n color: #FF20ED;\\n}\\n.json-formatter-row .json-formatter-date {\\n background-color: rgba(0, 0, 0, 0.05);\\n}\\n.json-formatter-row .json-formatter-url {\\n text-decoration: underline;\\n color: blue;\\n cursor: pointer;\\n}\\n.json-formatter-row .json-formatter-bracket {\\n color: blue;\\n}\\n.json-formatter-row .json-formatter-key {\\n color: #00008B;\\n padding-right: 0.2rem;\\n}\\n.json-formatter-row .json-formatter-toggler-link {\\n cursor: pointer;\\n}\\n.json-formatter-row .json-formatter-toggler {\\n line-height: 1.2rem;\\n font-size: 0.7rem;\\n vertical-align: middle;\\n opacity: 0.6;\\n cursor: pointer;\\n padding-right: 0.2rem;\\n}\\n.json-formatter-row .json-formatter-toggler:after {\\n display: inline-block;\\n transition: transform 100ms ease-in;\\n content: \\\"\\\\25BA\\\";\\n}\\n.json-formatter-row > a > .json-formatter-preview-text {\\n opacity: 0;\\n transition: opacity 0.15s ease-in;\\n font-style: italic;\\n}\\n.json-formatter-row:hover > a > .json-formatter-preview-text {\\n opacity: 0.6;\\n}\\n.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\\n transform: rotate(90deg);\\n}\\n.json-formatter-row.json-formatter-open > .json-formatter-children:after {\\n display: inline-block;\\n}\\n.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\\n display: none;\\n}\\n.json-formatter-row.json-formatter-open.json-formatter-empty:after {\\n display: block;\\n}\\n.json-formatter-dark.json-formatter-row {\\n font-family: monospace;\\n}\\n.json-formatter-dark.json-formatter-row,\\n.json-formatter-dark.json-formatter-row a,\\n.json-formatter-dark.json-formatter-row a:hover {\\n color: white;\\n text-decoration: none;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-row {\\n margin-left: 1rem;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty {\\n opacity: 0.5;\\n margin-left: 1rem;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty:after {\\n display: none;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\\n content: \\\"No properties\\\";\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\\n content: \\\"[]\\\";\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-string,\\n.json-formatter-dark.json-formatter-row .json-formatter-stringifiable {\\n color: #31F031;\\n white-space: pre;\\n word-wrap: break-word;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-number {\\n color: #66C2FF;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-boolean {\\n color: #EC4242;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-null {\\n color: #EEC97D;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-undefined {\\n color: #ef8fbe;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-function {\\n color: #FD48CB;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-date {\\n background-color: rgba(255, 255, 255, 0.05);\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-url {\\n text-decoration: underline;\\n color: #027BFF;\\n cursor: pointer;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-bracket {\\n color: #9494FF;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-key {\\n color: #23A0DB;\\n padding-right: 0.2rem;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-toggler-link {\\n cursor: pointer;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-toggler {\\n line-height: 1.2rem;\\n font-size: 0.7rem;\\n vertical-align: middle;\\n opacity: 0.6;\\n cursor: pointer;\\n padding-right: 0.2rem;\\n}\\n.json-formatter-dark.json-formatter-row .json-formatter-toggler:after {\\n display: inline-block;\\n transition: transform 100ms ease-in;\\n content: \\\"\\\\25BA\\\";\\n}\\n.json-formatter-dark.json-formatter-row > a > .json-formatter-preview-text {\\n opacity: 0;\\n transition: opacity 0.15s ease-in;\\n font-style: italic;\\n}\\n.json-formatter-dark.json-formatter-row:hover > a > .json-formatter-preview-text {\\n opacity: 0.6;\\n}\\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\\n transform: rotate(90deg);\\n}\\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-children:after {\\n display: inline-block;\\n}\\n.json-formatter-dark.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\\n display: none;\\n}\\n.json-formatter-dark.json-formatter-row.json-formatter-open.json-formatter-empty:after {\\n display: block;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".bk.pn-loading {\\n overflow: hidden;\\n}\\n.bk.pn-loading:before {\\n position: absolute;\\n height: 100%;\\n width: 100%;\\n content: '';\\n z-index: 1000;\\n background-color: rgb(255,255,255,0.50);\\n border-color: lightgray;\\n background-repeat: no-repeat;\\n background-position: center;\\n background-size: auto 50%;\\n border-width: 1px;\\n cursor: progress;\\n}\\n.bk.pn-loading.arcs:hover:before {\\n cursor: progress;\\n}\\n.bk.pn-loading .pn-loading-msg {\\n position: absolute;\\n top: 72%;\\n font-size: 2em;\\n color: black;\\n width: 100%;\\n text-align: center;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\".bk.alert {\\n padding: 0.75rem 1.25rem;\\n border: 1px solid transparent;\\n border-radius: 0.25rem;\\n /* Don't set margin because that will not render correctly! */\\n /* margin-bottom: 1rem; */\\n margin-top: 15px;\\n margin-bottom: 15px;\\n}\\n.bk.alert a {\\n color: rgb(11, 46, 19); /* #002752; */\\n font-weight: 700;\\n text-decoration: rgb(11, 46, 19);\\n text-decoration-color: rgb(11, 46, 19);\\n text-decoration-line: none;\\n text-decoration-style: solid;\\n text-decoration-thickness: auto;\\n }\\n.bk.alert a:hover {\\n color: rgb(11, 46, 19);\\n font-weight: 700;\\n text-decoration: underline;\\n}\\n\\n.bk.alert-primary {\\n color: #004085;\\n background-color: #cce5ff;\\n border-color: #b8daff;\\n}\\n.bk.alert-primary hr {\\n border-top-color: #9fcdff;\\n}\\n\\n.bk.alert-secondary {\\n color: #383d41;\\n background-color: #e2e3e5;\\n border-color: #d6d8db;\\n }\\n.bk.alert-secondary hr {\\n border-top-color: #c8cbcf;\\n}\\n\\n.bk.alert-success {\\n color: #155724;\\n background-color: #d4edda;\\n border-color: #c3e6cb;\\n }\\n\\n.bk.alert-success hr {\\n border-top-color: #b1dfbb;\\n}\\n\\n.bk.alert-info {\\n color: #0c5460;\\n background-color: #d1ecf1;\\n border-color: #bee5eb;\\n }\\n.bk.alert-info hr {\\n border-top-color: #abdde5;\\n}\\n\\n.bk.alert-warning {\\n color: #856404;\\n background-color: #fff3cd;\\n border-color: #ffeeba;\\n }\\n\\n.bk.alert-warning hr {\\n border-top-color: #ffe8a1;\\n}\\n\\n.bk.alert-danger {\\n color: #721c24;\\n background-color: #f8d7da;\\n border-color: #f5c6cb;\\n}\\n.bk.alert-danger hr {\\n border-top-color: #f1b0b7;\\n}\\n\\n.bk.alert-light {\\n color: #818182;\\n background-color: #fefefe;\\n border-color: #fdfdfe;\\n }\\n.bk.alert-light hr {\\n border-top-color: #ececf6;\\n}\\n\\n.bk.alert-dark {\\n color: #1b1e21;\\n background-color: #d6d8d9;\\n border-color: #c6c8ca;\\n }\\n.bk.alert-dark hr {\\n border-top-color: #b9bbbe;\\n}\\n\\n\\n/* adjf\\u00e6l */\\n\\n.bk.alert-primary a {\\n color: #002752;\\n}\\n\\n.bk.alert-secondary a {\\n color: #202326;\\n}\\n\\n\\n.bk.alert-success a {\\n color: #0b2e13;\\n}\\n\\n\\n.bk.alert-info a {\\n color: #062c33;\\n}\\n\\n\\n.bk.alert-warning a {\\n color: #533f03;\\n}\\n\\n\\n.bk.alert-danger a {\\n color: #491217;\\n}\\n\\n.bk.alert-light a {\\n color: #686868;\\n}\\n\\n.bk.alert-dark a {\\n color: #040505;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", - " }, function(Bokeh) {\n", - " /* BEGIN bokeh.min.js */\n", - " /*!\n", - " * Copyright (c) 2012 - 2022, Anaconda, Inc., and Bokeh Contributors\n", - " * All rights reserved.\n", - " * \n", - " * Redistribution and use in source and binary forms, with or without modification,\n", - " * are permitted provided that the following conditions are met:\n", - " * \n", - " * Redistributions of source code must retain the above copyright notice,\n", - " * this list of conditions and the following disclaimer.\n", - " * \n", - " * Redistributions in binary form must reproduce the above copyright notice,\n", - " * this list of conditions and the following disclaimer in the documentation\n", - " * and/or other materials provided with the distribution.\n", - " * \n", - " * Neither the name of Anaconda nor the names of any contributors\n", - " * may be used to endorse or promote products derived from this software\n", - " * without specific prior written permission.\n", - " * \n", - " * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n", - " * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n", - " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n", - " * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n", - " * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n", - " * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n", - " * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n", - " * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n", - " * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n", - " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n", - " * THE POSSIBILITY OF SUCH DAMAGE.\n", - " */\n", - " (function(root, factory) {\n", - " const bokeh = factory();\n", - " bokeh.__bokeh__ = true;\n", - " if (typeof root.Bokeh === \"undefined\" || typeof root.Bokeh.__bokeh__ === \"undefined\") {\n", - " root.Bokeh = bokeh;\n", - " }\n", - " const Bokeh = root.Bokeh;\n", - " Bokeh[bokeh.version] = bokeh;\n", - " })(this, function() {\n", - " let define;\n", - " const parent_require = typeof require === \"function\" && require\n", - " return (function(modules, entry, aliases, externals) {\n", - " if (aliases === undefined) aliases = {};\n", - " if (externals === undefined) externals = {};\n", - "\n", - " const cache = {};\n", - "\n", - " const normalize = function(name) {\n", - " if (typeof name === \"number\")\n", - " return name;\n", - "\n", - " if (name === \"bokehjs\")\n", - " return entry;\n", - "\n", - " if (!externals[name]) {\n", - " const prefix = \"@bokehjs/\"\n", - " if (name.slice(0, prefix.length) === prefix)\n", - " name = name.slice(prefix.length)\n", - " }\n", - "\n", - " const alias = aliases[name]\n", - " if (alias != null)\n", - " return alias;\n", - "\n", - " const trailing = name.length > 0 && name[name.lenght-1] === \"/\";\n", - " const index = aliases[name + (trailing ? \"\" : \"/\") + \"index\"];\n", - " if (index != null)\n", - " return index;\n", - "\n", - " return name;\n", - " }\n", - "\n", - " const require = function(name) {\n", - " let mod = cache[name];\n", - " if (!mod) {\n", - " const id = normalize(name);\n", - "\n", - " mod = cache[id];\n", - " if (!mod) {\n", - " if (!modules[id]) {\n", - " if (externals[id] === false || (externals[id] == true && parent_require)) {\n", - " try {\n", - " mod = {exports: externals[id] ? parent_require(id) : {}};\n", - " cache[id] = cache[name] = mod;\n", - " return mod.exports;\n", - " } catch (e) {}\n", - " }\n", - "\n", - " const err = new Error(\"Cannot find module '\" + name + \"'\");\n", - " err.code = 'MODULE_NOT_FOUND';\n", - " throw err;\n", - " }\n", - "\n", - " mod = {exports: {}};\n", - " cache[id] = cache[name] = mod;\n", - "\n", - " function __esModule() {\n", - " Object.defineProperty(mod.exports, \"__esModule\", {value: true});\n", - " }\n", - "\n", - " function __esExport(name, value) {\n", - " Object.defineProperty(mod.exports, name, {\n", - " enumerable: true, get: function () { return value; }\n", - " });\n", - " }\n", - "\n", - " modules[id].call(mod.exports, require, mod, mod.exports, __esModule, __esExport);\n", - " } else {\n", - " cache[name] = mod;\n", - " }\n", - " }\n", - "\n", - " return mod.exports;\n", - " }\n", - " require.resolve = function(name) {\n", - " return \"\"\n", - " }\n", - "\n", - " const main = require(entry);\n", - " main.require = require;\n", - "\n", - " if (typeof Proxy !== \"undefined\") {\n", - " // allow Bokeh.loader[\"@bokehjs/module/name\"] syntax\n", - " main.loader = new Proxy({}, {\n", - " get: function(_obj, module) {\n", - " return require(module);\n", - " }\n", - " });\n", - " }\n", - "\n", - " main.register_plugin = function(plugin_modules, plugin_entry, plugin_aliases, plugin_externals) {\n", - " if (plugin_aliases === undefined) plugin_aliases = {};\n", - " if (plugin_externals === undefined) plugin_externals = {};\n", - "\n", - " for (let name in plugin_modules) {\n", - " modules[name] = plugin_modules[name];\n", - " }\n", - "\n", - " for (let name in plugin_aliases) {\n", - " aliases[name] = plugin_aliases[name];\n", - " }\n", - "\n", - " for (let name in plugin_externals) {\n", - " externals[name] = plugin_externals[name];\n", - " }\n", - "\n", - " const plugin = require(plugin_entry);\n", - "\n", - " for (let name in plugin) {\n", - " main[name] = plugin[name];\n", - " }\n", - "\n", - " return plugin;\n", - " }\n", - "\n", - " return main;\n", - " })\n", - " ([\n", - " function _(t,_,n,o,r){o();(0,t(1).__exportStar)(t(2),n)},\n", - " function _(t,e,r,n,o){n();var a=function(t,e){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r])},a(t,e)};r.__extends=function(t,e){if(\"function\"!=typeof e&&null!==e)throw new TypeError(\"Class extends value \"+String(e)+\" is not a constructor or null\");function r(){this.constructor=t}a(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)};function i(t){var e=\"function\"==typeof Symbol&&Symbol.iterator,r=e&&t[e],n=0;if(r)return r.call(t);if(t&&\"number\"==typeof t.length)return{next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?\"Object is not iterable.\":\"Symbol.iterator is not defined.\")}function c(t,e){var r=\"function\"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var n,o,a=r.call(t),i=[];try{for(;(void 0===e||e-- >0)&&!(n=a.next()).done;)i.push(n.value)}catch(t){o={error:t}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(o)throw o.error}}return i}function u(t){return this instanceof u?(this.v=t,this):new u(t)}r.__assign=function(){return r.__assign=Object.assign||function(t){for(var e,r=1,n=arguments.length;r=0;c--)(o=t[c])&&(i=(a<3?o(i):a>3?o(e,r,i):o(e,r))||i);return a>3&&i&&Object.defineProperty(e,r,i),i},r.__param=function(t,e){return function(r,n){e(r,n,t)}},r.__metadata=function(t,e){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(t,e)},r.__awaiter=function(t,e,r,n){return new(r||(r=Promise))((function(o,a){function i(t){try{u(n.next(t))}catch(t){a(t)}}function c(t){try{u(n.throw(t))}catch(t){a(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(i,c)}u((n=n.apply(t,e||[])).next())}))},r.__generator=function(t,e){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},\"function\"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(a){return function(c){return function(a){if(r)throw new TypeError(\"Generator is already executing.\");for(;i;)try{if(r=1,n&&(o=2&a[0]?n.return:a[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,a[1])).done)return o;switch(n=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,n=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]1||c(t,e)}))})}function c(t,e){try{(r=o[t](e)).value instanceof u?Promise.resolve(r.value.v).then(f,l):s(a[0][2],r)}catch(t){s(a[0][3],t)}var r}function f(t){c(\"next\",t)}function l(t){c(\"throw\",t)}function s(t,e){t(e),a.shift(),a.length&&c(a[0][0],a[0][1])}},r.__asyncDelegator=function(t){var e,r;return e={},n(\"next\"),n(\"throw\",(function(t){throw t})),n(\"return\"),e[Symbol.iterator]=function(){return this},e;function n(n,o){e[n]=t[n]?function(e){return(r=!r)?{value:u(t[n](e)),done:\"return\"===n}:o?o(e):e}:o}},r.__asyncValues=function(t){if(!Symbol.asyncIterator)throw new TypeError(\"Symbol.asyncIterator is not defined.\");var e,r=t[Symbol.asyncIterator];return r?r.call(t):(t=i(t),e={},n(\"next\"),n(\"throw\"),n(\"return\"),e[Symbol.asyncIterator]=function(){return this},e);function n(r){e[r]=t[r]&&function(e){return new Promise((function(n,o){(function(t,e,r,n){Promise.resolve(n).then((function(e){t({value:e,done:r})}),e)})(n,o,(e=t[r](e)).done,e.value)}))}}},r.__makeTemplateObject=function(t,e){return Object.defineProperty?Object.defineProperty(t,\"raw\",{value:e}):t.raw=e,t};var f=Object.create?function(t,e){Object.defineProperty(t,\"default\",{enumerable:!0,value:e})}:function(t,e){t.default=e};r.__importStar=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)\"default\"!==n&&Object.prototype.hasOwnProperty.call(t,n)&&(0,r.__createBinding)(e,t,n);return f(e,t),e},r.__importDefault=function(t){return t&&t.__esModule?t:{default:t}},r.__classPrivateFieldGet=function(t,e,r,n){if(\"a\"===r&&!n)throw new TypeError(\"Private accessor was defined without a getter\");if(\"function\"==typeof e?t!==e||!n:!e.has(t))throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");return\"m\"===r?n:\"a\"===r?n.call(t):n?n.value:e.get(t)},r.__classPrivateFieldSet=function(t,e,r,n,o){if(\"m\"===n)throw new TypeError(\"Private method is not writable\");if(\"a\"===n&&!o)throw new TypeError(\"Private accessor was defined without a setter\");if(\"function\"==typeof e?t!==e||!o:!e.has(t))throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");return\"a\"===n?o.call(t,r):o?o.value=r:e.set(t,r),r}},\n", - " function _(e,t,o,s,l){s();const n=e(1);l(\"version\",e(3).version),l(\"index\",e(4).index),o.embed=(0,n.__importStar)(e(4)),o.protocol=(0,n.__importStar)(e(406)),o._testing=(0,n.__importStar)(e(407));var r=e(19);l(\"logger\",r.logger),l(\"set_log_level\",r.set_log_level),l(\"settings\",e(28).settings),l(\"Models\",e(7).Models),l(\"documents\",e(5).documents),l(\"safely\",e(408).safely)},\n", - " function _(n,i,o,c,e){c(),o.version=\"2.4.3\"},\n", - " function _(e,o,t,n,s){n();const d=e(5),r=e(19),_=e(34),c=e(13),i=e(8),a=e(16),u=e(397),l=e(399),m=e(398);var f=e(397);s(\"add_document_standalone\",f.add_document_standalone),s(\"index\",f.index),s(\"add_document_from_session\",e(399).add_document_from_session);var g=e(404);async function w(e,o,t,n){(0,i.isString)(e)&&(e=JSON.parse((0,_.unescape)(e)));const s={};for(const[o,t]of(0,c.entries)(e))s[o]=d.Document.from_json(t);const a=[];for(const e of o){const o=(0,m._resolve_element)(e),d=(0,m._resolve_root_elements)(e);if(null!=e.docid)a.push(await(0,u.add_document_standalone)(s[e.docid],o,d,e.use_for_title));else{if(null==e.token)throw new Error(\"Error rendering Bokeh items: either 'docid' or 'token' was expected.\");{const s=(0,l._get_ws_url)(t,n);r.logger.debug(`embed: computed ws url: ${s}`);try{a.push(await(0,l.add_document_from_session)(s,e.token,o,d,e.use_for_title)),console.log(\"Bokeh items were rendered successfully\")}catch(e){console.log(\"Error rendering Bokeh items:\",e)}}}}return a}s(\"embed_items_notebook\",g.embed_items_notebook),s(\"kernels\",g.kernels),s(\"BOKEH_ROOT\",e(398).BOKEH_ROOT),t.embed_item=async function(e,o){const t={},n=(0,_.uuid4)();t[n]=e.doc,null==o&&(o=e.target_id);const s=document.getElementById(o);null!=s&&s.classList.add(m.BOKEH_ROOT);const d={roots:{[e.root_id]:o},root_ids:[e.root_id],docid:n};await(0,a.defer)();const[r]=await w(t,[d]);return r},t.embed_items=async function(e,o,t,n){return await(0,a.defer)(),w(e,o,t,n)}},\n", - " function _(t,_,o,r,n){r();const a=t(1);(0,a.__exportStar)(t(6),o),(0,a.__exportStar)(t(35),o)},\n", - " function _(e,t,s,o,n){o();const i=e(1),r=e(7),l=e(3),_=e(19),a=e(251),c=e(14),d=e(30),h=e(15),f=e(17),u=e(31),m=e(29),g=e(9),v=e(13),p=(0,i.__importStar)(e(77)),w=e(26),b=e(8),y=e(309),k=e(75),M=e(53),j=e(396),z=e(35);class S{constructor(e){this.document=e,this.session=null,this.subscribed_models=new Set}send_event(e){const t=new z.MessageSentEvent(this.document,\"bokeh_event\",e.to_json());this.document._trigger_on_change(t)}trigger(e){for(const t of this.subscribed_models)null!=e.origin&&e.origin!=t||t._process_event(e)}}s.EventManager=S,S.__name__=\"EventManager\",s.documents=[],s.DEFAULT_TITLE=\"Bokeh Application\";class E{constructor(e){var t;s.documents.push(this),this._init_timestamp=Date.now(),this._resolver=null!==(t=null==e?void 0:e.resolver)&&void 0!==t?t:new r.ModelResolver,this._title=s.DEFAULT_TITLE,this._roots=[],this._all_models=new Map,this._all_models_freeze_count=0,this._callbacks=new Map,this._message_callbacks=new Map,this.event_manager=new S(this),this.idle=new h.Signal0(this,\"idle\"),this._idle_roots=new WeakMap,this._interactive_timestamp=null,this._interactive_plot=null}get layoutables(){return this._roots.filter((e=>e instanceof y.LayoutDOM))}get is_idle(){for(const e of this.layoutables)if(!this._idle_roots.has(e))return!1;return!0}notify_idle(e){this._idle_roots.set(e,!0),this.is_idle&&(_.logger.info(`document idle at ${Date.now()-this._init_timestamp} ms`),this.event_manager.send_event(new a.DocumentReady),this.idle.emit())}clear(){this._push_all_models_freeze();try{for(;this._roots.length>0;)this.remove_root(this._roots[0])}finally{this._pop_all_models_freeze()}}interactive_start(e,t=null){null==this._interactive_plot&&(this._interactive_plot=e,this._interactive_plot.trigger_event(new a.LODStart)),this._interactive_finalize=t,this._interactive_timestamp=Date.now()}interactive_stop(){null!=this._interactive_plot&&(this._interactive_plot.trigger_event(new a.LODEnd),null!=this._interactive_finalize&&this._interactive_finalize()),this._interactive_plot=null,this._interactive_timestamp=null,this._interactive_finalize=null}interactive_duration(){return null==this._interactive_timestamp?-1:Date.now()-this._interactive_timestamp}destructively_move(e){if(e===this)throw new Error(\"Attempted to overwrite a document with itself\");e.clear();const t=(0,g.copy)(this._roots);this.clear();for(const e of t)if(null!=e.document)throw new Error(`Somehow we didn't detach ${e}`);if(0!=this._all_models.size)throw new Error(`this._all_models still had stuff in it: ${this._all_models}`);for(const s of t)e.add_root(s);e.set_title(this._title)}_push_all_models_freeze(){this._all_models_freeze_count+=1}_pop_all_models_freeze(){this._all_models_freeze_count-=1,0===this._all_models_freeze_count&&this._recompute_all_models()}_invalidate_all_models(){_.logger.debug(\"invalidating document models\"),0===this._all_models_freeze_count&&this._recompute_all_models()}_recompute_all_models(){let e=new Set;for(const t of this._roots)e=p.union(e,t.references());const t=new Set(this._all_models.values()),s=p.difference(t,e),o=p.difference(e,t),n=new Map;for(const t of e)n.set(t.id,t);for(const e of s)e.detach_document();for(const e of o)e.attach_document(this);this._all_models=n}roots(){return this._roots}add_root(e,t){if(_.logger.debug(`Adding root: ${e}`),!(0,g.includes)(this._roots,e)){this._push_all_models_freeze();try{this._roots.push(e)}finally{this._pop_all_models_freeze()}this._trigger_on_change(new z.RootAddedEvent(this,e,t))}}remove_root(e,t){const s=this._roots.indexOf(e);if(!(s<0)){this._push_all_models_freeze();try{this._roots.splice(s,1)}finally{this._pop_all_models_freeze()}this._trigger_on_change(new z.RootRemovedEvent(this,e,t))}}title(){return this._title}set_title(e,t){e!==this._title&&(this._title=e,this._trigger_on_change(new z.TitleChangedEvent(this,e,t)))}get_model_by_id(e){var t;return null!==(t=this._all_models.get(e))&&void 0!==t?t:null}get_model_by_name(e){const t=[];for(const s of this._all_models.values())s instanceof M.Model&&s.name==e&&t.push(s);switch(t.length){case 0:return null;case 1:return t[0];default:throw new Error(`Multiple models are named '${e}'`)}}on_message(e,t){const s=this._message_callbacks.get(e);null==s?this._message_callbacks.set(e,new Set([t])):s.add(t)}remove_on_message(e,t){var s;null===(s=this._message_callbacks.get(e))||void 0===s||s.delete(t)}_trigger_on_message(e,t){const s=this._message_callbacks.get(e);if(null!=s)for(const e of s)e(t)}on_change(e,t=!1){this._callbacks.has(e)||this._callbacks.set(e,t)}remove_on_change(e){this._callbacks.delete(e)}_trigger_on_change(e){for(const[t,s]of this._callbacks)if(!s&&e instanceof z.DocumentEventBatch)for(const s of e.events)t(s);else t(e)}_notify_change(e,t,s,o,n){this._trigger_on_change(new z.ModelChangedEvent(this,e,t,s,o,null==n?void 0:n.setter_id,null==n?void 0:n.hint))}static _instantiate_object(e,t,s,o){const n=Object.assign(Object.assign({},s),{id:e,__deferred__:!0});return new(o.get(t))(n)}static _instantiate_references_json(e,t,s){var o;const n=new Map;for(const i of e){const e=i.id,r=i.type,l=null!==(o=i.attributes)&&void 0!==o?o:{};let _=t.get(e);null==_&&(_=E._instantiate_object(e,r,l,s),null!=i.subtype&&_.set_subtype(i.subtype)),n.set(_.id,_)}return n}static _resolve_refs(e,t,s,o){function n(e){var i;if((0,f.is_ref)(e)){const o=null!==(i=t.get(e.id))&&void 0!==i?i:s.get(e.id);if(null!=o)return o;throw new Error(`reference ${JSON.stringify(e)} isn't known (not in Document?)`)}if((0,u.is_NDArray_ref)(e)){const{buffer:t,dtype:s,shape:n}=(0,u.decode_NDArray)(e,o);return(0,m.ndarray)(t,{dtype:s,shape:n})}return(0,b.isArray)(e)?function(e){const t=[];for(const s of e)t.push(n(s));return t}(e):(0,b.isPlainObject)(e)?function(e){const t={};for(const[s,o]of(0,v.entries)(e))t[s]=n(o);return t}(e):e}return n(e)}static _initialize_references_json(e,t,s,o){const n=new Map;for(const{id:i,attributes:r}of e){const e=!t.has(i),l=e?s.get(i):t.get(i),_=E._resolve_refs(r,t,s,o);l.setv(_,{silent:!0}),n.set(i,{instance:l,is_new:e})}const i=[],r=new Set;function l(e){if(e instanceof c.HasProps){if(n.has(e.id)&&!r.has(e.id)){r.add(e.id);const{instance:t,is_new:s}=n.get(e.id),{attributes:o}=t;for(const e of(0,v.values)(o))l(e);s&&(t.finalize(),i.push(t))}}else if((0,b.isArray)(e))for(const t of e)l(t);else if((0,b.isPlainObject)(e))for(const t of(0,v.values)(e))l(t)}for(const e of n.values())l(e.instance);for(const e of i)e.connect_signals()}static _event_for_attribute_change(e,t,s,o,n){if(o.get_model_by_id(e.id).property(t).syncable){const i={kind:\"ModelChanged\",model:{id:e.id},attr:t,new:s};return c.HasProps._json_record_references(o,s,n,{recursive:!0}),i}return null}static _events_to_sync_objects(e,t,s,o){const n=Object.keys(e.attributes),i=Object.keys(t.attributes),r=(0,g.difference)(n,i),l=(0,g.difference)(i,n),a=(0,g.intersection)(n,i),c=[];for(const e of r)_.logger.warn(`Server sent key ${e} but we don't seem to have it in our JSON`);for(const n of l){const i=t.attributes[n];c.push(E._event_for_attribute_change(e,n,i,s,o))}for(const n of a){const i=e.attributes[n],r=t.attributes[n];null==i&&null==r||(null==i||null==r?c.push(E._event_for_attribute_change(e,n,r,s,o)):\"data\"==n||(0,w.is_equal)(i,r)||c.push(E._event_for_attribute_change(e,n,r,s,o)))}return c.filter((e=>null!=e))}static _compute_patch_since_json(e,t){const s=t.to_json(!1);function o(e){const t=new Map;for(const s of e.roots.references)t.set(s.id,s);return t}const n=o(e),i=new Map,r=[];for(const t of e.roots.root_ids)i.set(t,n.get(t)),r.push(t);const l=o(s),_=new Map,a=[];for(const e of s.roots.root_ids)_.set(e,l.get(e)),a.push(e);if(r.sort(),a.sort(),(0,g.difference)(r,a).length>0||(0,g.difference)(a,r).length>0)throw new Error(\"Not implemented: computing add/remove of document roots\");const c=new Set;let h=[];for(const e of t._all_models.keys())if(n.has(e)){const s=E._events_to_sync_objects(n.get(e),l.get(e),t,c);h=h.concat(s)}const f=new d.Serializer({include_defaults:!1});return f.to_serializable([...c]),{references:[...f.definitions],events:h}}to_json_string(e=!0){return JSON.stringify(this.to_json(e))}to_json(e=!0){const t=new d.Serializer({include_defaults:e}),s=t.to_serializable(this._roots);return{version:l.version,title:this._title,roots:{root_ids:s.map((e=>e.id)),references:[...t.definitions]}}}static from_json_string(e){const t=JSON.parse(e);return E.from_json(t)}static from_json(e){_.logger.debug(\"Creating Document from JSON\");const t=e.version,s=-1!==t.indexOf(\"+\")||-1!==t.indexOf(\"-\"),o=`Library versions: JS (${l.version}) / Python (${t})`;s||l.version.replace(/-(dev|rc)\\./,\"$1\")==t?_.logger.debug(o):(_.logger.warn(\"JS/Python version mismatch\"),_.logger.warn(o));const n=new r.ModelResolver;null!=e.defs&&(0,j.resolve_defs)(e.defs,n);const i=e.roots,a=i.root_ids,c=i.references,d=E._instantiate_references_json(c,new Map,n);E._initialize_references_json(c,new Map,d,new Map);const h=new E({resolver:n});h._push_all_models_freeze();for(const e of a){const t=d.get(e);null!=t&&h.add_root(t)}return h._pop_all_models_freeze(),h.set_title(e.title),h}replace_with_json(e){E.from_json(e).destructively_move(this)}create_json_patch_string(e){return JSON.stringify(this.create_json_patch(e))}create_json_patch(e){for(const t of e)if(t.document!=this)throw new Error(\"Cannot create a patch using events from a different document\");const t=new d.Serializer,s=t.to_serializable(e);for(const e of this._all_models.values())t.remove_def(e);return{events:s,references:[...t.definitions]}}apply_json_patch(e,t=new Map,s){const o=e.references,n=e.events,i=E._instantiate_references_json(o,this._all_models,this._resolver);t instanceof Map||(t=new Map(t));for(const e of n)switch(e.kind){case\"RootAdded\":case\"RootRemoved\":case\"ModelChanged\":{const t=e.model.id,s=this._all_models.get(t);if(null!=s)i.set(t,s);else if(!i.has(t))throw _.logger.warn(`Got an event for unknown model ${e.model}\"`),new Error(\"event model wasn't known\");break}}const r=new Map(this._all_models),l=new Map;for(const[e,t]of i)r.has(e)||l.set(e,t);E._initialize_references_json(o,r,l,t);for(const e of n)switch(e.kind){case\"MessageSent\":{const{msg_type:s,msg_data:o}=e;let n;if(void 0===o){if(1!=t.size)throw new Error(\"expected exactly one buffer\");{const[[,e]]=t;n=e}}else n=E._resolve_refs(o,r,l,t);this._trigger_on_message(s,n);break}case\"ModelChanged\":{const o=e.model.id,n=this._all_models.get(o);if(null==n)throw new Error(`Cannot apply patch to ${o} which is not in the document`);const i=e.attr,_=E._resolve_refs(e.new,r,l,t);n.setv({[i]:_},{setter_id:s});break}case\"ColumnDataChanged\":{const o=e.column_source.id,n=this._all_models.get(o);if(null==n)throw new Error(`Cannot stream to ${o} which is not in the document`);const i=E._resolve_refs(e.new,new Map,new Map,t);if(null!=e.cols)for(const e in n.data)e in i||(i[e]=n.data[e]);n.setv({data:i},{setter_id:s,check_eq:!1});break}case\"ColumnsStreamed\":{const t=e.column_source.id,o=this._all_models.get(t);if(null==o)throw new Error(`Cannot stream to ${t} which is not in the document`);if(!(o instanceof k.ColumnDataSource))throw new Error(\"Cannot stream to non-ColumnDataSource\");const n=e.data,i=e.rollover;o.stream(n,i,s);break}case\"ColumnsPatched\":{const t=e.column_source.id,o=this._all_models.get(t);if(null==o)throw new Error(`Cannot patch ${t} which is not in the document`);if(!(o instanceof k.ColumnDataSource))throw new Error(\"Cannot patch non-ColumnDataSource\");const n=e.patches;o.patch(n,s);break}case\"RootAdded\":{const t=e.model.id,o=i.get(t);this.add_root(o,s);break}case\"RootRemoved\":{const t=e.model.id,o=i.get(t);this.remove_root(o,s);break}case\"TitleChanged\":this.set_title(e.title,s);break;default:throw new Error(`Unknown patch event ${JSON.stringify(e)}`)}}}s.Document=E,E.__name__=\"Document\"},\n", - " function _(e,o,s,r,t){r();const l=e(1),i=e(8),d=e(13),n=e(14);s.overrides={};const a=new Map;s.Models=e=>{const o=s.Models.get(e);if(null!=o)return o;throw new Error(`Model '${e}' does not exist. This could be due to a widget or a custom model not being registered before first usage.`)},s.Models.get=e=>{var o;return null!==(o=s.overrides[e])&&void 0!==o?o:a.get(e)},s.Models.register=(e,o)=>{s.overrides[e]=o},s.Models.unregister=e=>{delete s.overrides[e]},s.Models.register_models=(e,o=!1,s)=>{var r;if(null!=e)for(const t of(0,i.isArray)(e)?e:(0,d.values)(e))if(r=t,(0,i.isObject)(r)&&r.prototype instanceof n.HasProps){const e=t.__qualified__;o||!a.has(e)?a.set(e,t):null!=s?s(e):console.warn(`Model '${e}' was already registered`)}},s.register_models=s.Models.register_models,s.Models.registered_names=()=>[...a.keys()];class _{constructor(){this._known_models=new Map}get(e,o){var r;const t=null!==(r=s.Models.get(e))&&void 0!==r?r:this._known_models.get(e);if(null!=t)return t;if(void 0!==o)return o;throw new Error(`Model '${e}' does not exist. This could be due to a widget or a custom model not being registered before first usage.`)}register(e){const o=e.__qualified__;null==this.get(o,null)?this._known_models.set(o,e):console.warn(`Model '${o}' was already registered with this resolver`)}}s.ModelResolver=_,_.__name__=\"ModelResolver\";const g=(0,l.__importStar)(e(38));(0,s.register_models)(g);const u=(0,l.__importStar)(e(392));(0,s.register_models)(u)},\n", - " function _(n,t,r,e,i){e();\n", - " // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n", - " // Underscore may be freely distributed under the MIT license.\n", - " const o=n(9),u=Object.prototype.toString;function c(n){return!0===n||!1===n||\"[object Boolean]\"===u.call(n)}function f(n){return\"[object Number]\"===u.call(n)}function l(n){return\"[object String]\"===u.call(n)}function s(n){return\"symbol\"==typeof n}function a(n){const t=typeof n;return\"function\"===t||\"object\"===t&&!!n}function b(n){return a(n)&&void 0!==n[Symbol.iterator]}r.isBoolean=c,r.isNumber=f,r.isInteger=function(n){return f(n)&&Number.isInteger(n)},r.isString=l,r.isSymbol=s,r.isPrimitive=function(n){return null===n||c(n)||f(n)||l(n)||s(n)},r.isFunction=function(n){return\"[object Function]\"===u.call(n)},r.isArray=function(n){return Array.isArray(n)},r.isArrayOf=function(n,t){return(0,o.every)(n,t)},r.isArrayableOf=function(n,t){for(let r=0,e=n.length;r0,\"'step' must be a positive number\"),null==t&&(t=n,n=0);const{max:r,ceil:o,abs:i}=Math,c=n<=t?e:-e,f=r(o(i(t-n)/e),0),s=new Array(f);for(let t=0;t=0?t:n.length+t]},e.zip=function(...n){if(0==n.length)return[];const t=(0,c.min)(n.map((n=>n.length))),e=n.length,r=new Array(t);for(let o=0;on.length))),r=Array(e);for(let n=0;nn[t]))},e.argmax=function(n){return(0,c.max_by)(m(n.length),(t=>n[t]))},e.sort_by=function(n,t){const e=n.map(((n,e)=>({value:n,index:e,key:t(n)})));return e.sort(((n,t)=>{const e=n.key,r=t.key;if(e!==r){if(e>r||void 0===e)return 1;if(en.value))},e.uniq=function(n){const t=new Set;for(const e of n)t.add(e);return[...t]},e.uniq_by=function(n,t){const e=[],r=[];for(const o of n){const n=t(o);l(r,n)||(r.push(n),e.push(o))}return e},e.union=function(...n){const t=new Set;for(const e of n)for(const n of e)t.add(n);return[...t]},e.intersection=function(n,...t){const e=[];n:for(const r of n)if(!l(e,r)){for(const n of t)if(!l(n,r))continue n;e.push(r)}return e},e.difference=function(n,...t){const e=a(t);return n.filter((n=>!l(e,n)))},e.remove_at=function(n,t){const e=s(n);return e.splice(t,1),e},e.remove_by=function(n,t){for(let e=0;e2*a;)n-=2*a;return n}function c(n,t){return u(n-t)}function f(){return Math.random()}function i(n){switch(n){case\"deg\":return a/180;case\"rad\":return 1;case\"grad\":return a/200;case\"turn\":return 2*a}}r.angle_norm=u,r.angle_dist=c,r.angle_between=function(n,t,r,e=!1){const o=c(t,r);if(0==o)return!1;if(o==2*a)return!0;const f=u(n),i=c(t,f)<=o&&c(f,r)<=o;return e?!i:i},r.random=f,r.randomIn=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},r.atan2=function(n,t){return Math.atan2(t[1]-n[1],t[0]-n[0])},r.radians=function(n){return n*(a/180)},r.degrees=function(n){return n/(a/180)},r.resolve_angle=function(n,t){return-i(t)*n},r.to_radians_coeff=i,r.rnorm=function(n,t){let r,e;for(;r=f(),e=f(),e=(2*e-1)*Math.sqrt(1/Math.E*2),!(-4*r*r*Math.log(r)>=e*e););let o=e/r;return o=n+t*o,o},r.clamp=function(n,t,r){return nr?r:n},r.log=function(n,t=Math.E){return Math.log(n)/Math.log(t)},r.float32_epsilon=1.1920928955078125e-7},\n", - " function _(r,n,e,o,s){o();class t extends Error{}e.AssertionError=t,t.__name__=\"AssertionError\",e.assert=function(r,n){if(!(!0===r||!1!==r&&r()))throw new t(null!=n?n:\"Assertion failed\")},e.unreachable=function(){throw new Error(\"unreachable code\")}},\n", - " function _(n,t,e,r,o){r();const i=n(10);function l(n,t,e,...r){const o=n.length;t<0&&(t+=o),t<0?t=0:t>o&&(t=o),null==e||e>o-t?e=o-t:e<0&&(e=0);const i=o-e+r.length,l=new n.constructor(i);let u=0;for(;u0?0:r-1;for(;o>=0&&ot[t.length-1])return t.length;let e=0,r=t.length-1;for(;r-e!=1;){const o=e+Math.floor((r-e)/2);n>=t[o]?e=o:r=o}return e}e.is_empty=function(n){return 0==n.length},e.copy=function(n){return Array.isArray(n)?n.slice():new n.constructor(n)},e.splice=l,e.head=u,e.insert=function(n,t,e){return l(n,e,0,t)},e.append=function(n,t){return l(n,n.length,0,t)},e.prepend=function(n,t){return l(n,0,0,t)},e.indexOf=function(n,t){for(let e=0,r=n.length;ee&&(e=t);return e},e.minmax=function(n){let t,e=1/0,r=-1/0;for(let o=0,i=n.length;or&&(r=t));return[e,r]},e.minmax2=function(n,t){let e,r,o=1/0,i=-1/0,l=1/0,u=-1/0;const c=Math.min(n.length,t.length);for(let f=0;fi&&(i=e),ru&&(u=r));return[o,i,l,u]},e.min_by=function(n,t){if(0==n.length)throw new Error(\"min_by() called with an empty array\");let e=n[0],r=t(e);for(let o=1,i=n.length;or&&(e=i,r=l)}return e},e.sum=function(n){let t=0;for(let e=0,r=n.length;et[r]=n+e),0),t},e.every=function(n,t){for(let e=0,r=n.length;e(n-t)/r))}},\n", - " function _(t,e,n,c,o){c();const s=t(9),{hasOwnProperty:r}=Object.prototype;function i(t){return Object.keys(t).length}function u(t){return 0==i(t)}n.keys=Object.keys,n.values=Object.values,n.entries=Object.entries,n.extend=Object.assign,n.clone=function(t){return Object.assign({},t)},n.merge=function(t,e){const n=Object.create(Object.prototype),c=(0,s.concat)([Object.keys(t),Object.keys(e)]);for(const o of c){const c=r.call(t,o)?t[o]:[],i=r.call(e,o)?e[o]:[];n[o]=(0,s.union)(c,i)}return n},n.size=i,n.is_empty=u,n.isEmpty=u,n.to_object=function(t){const e={};for(const[n,c]of t)e[n]=c;return e}},\n", - " function _(e,t,s,n,r){n();const i=e(1);var o;const c=e(15),a=e(17),_=(0,i.__importStar)(e(18)),h=(0,i.__importStar)(e(21)),u=e(34),l=e(13),f=e(8),p=e(26),d=e(30),g=e(35),y=e(26),v=e(36),m=e(37),b=(0,i.__importStar)(e(21));class w extends((0,c.Signalable)()){constructor(e={}){var t,s;super(),this._subtype=void 0,this.document=null,this.destroyed=new c.Signal0(this,\"destroyed\"),this.change=new c.Signal0(this,\"change\"),this.transformchange=new c.Signal0(this,\"transformchange\"),this.exprchange=new c.Signal0(this,\"exprchange\"),this.properties={},this._watchers=new WeakMap,this._pending=!1,this._changing=!1;const n=e instanceof Map?e.get.bind(e):t=>e[t];this.id=null!==(t=n(\"id\"))&&void 0!==t?t:(0,u.uniqueId)();for(const[e,{type:t,default_value:s,options:r}]of(0,l.entries)(this._props)){let i;t instanceof _.PropertyAlias?Object.defineProperty(this.properties,e,{get:()=>this.properties[t.attr],configurable:!1,enumerable:!1}):(i=t instanceof h.Kind?new _.PrimitiveProperty(this,e,t,s,n(e),r):new t(this,e,h.Any,s,n(e),r),this.properties[e]=i)}null!==(s=n(\"__deferred__\"))&&void 0!==s&&s||(this.finalize(),this.connect_signals())}get is_syncable(){return!0}set type(e){console.warn(\"prototype.type = 'ModelName' is deprecated, use static __name__ instead\"),this.constructor.__name__=e}get type(){return this.constructor.__qualified__}static get __qualified__(){const{__module__:e,__name__:t}=this;return null!=e?`${e}.${t}`:t}static get[Symbol.toStringTag](){return this.__name__}static _fix_default(e,t){if(void 0===e||(0,f.isFunction)(e))return e;if((0,f.isPrimitive)(e))return()=>e;{const t=new m.Cloner;return()=>t.clone(e)}}static define(e){for(const[t,s]of(0,l.entries)((0,f.isFunction)(e)?e(b):e)){if(null!=this.prototype._props[t])throw new Error(`attempted to redefine property '${this.prototype.type}.${t}'`);if(null!=this.prototype[t])throw new Error(`attempted to redefine attribute '${this.prototype.type}.${t}'`);Object.defineProperty(this.prototype,t,{get(){return this.properties[t].get_value()},set(e){return this.setv({[t]:e}),this},configurable:!1,enumerable:!0});const[e,n,r={}]=s,i={type:e,default_value:this._fix_default(n,t),options:r},o=Object.assign({},this.prototype._props);o[t]=i,this.prototype._props=o}}static internal(e){const t={};for(const[s,n]of(0,l.entries)((0,f.isFunction)(e)?e(b):e)){const[e,r,i={}]=n;t[s]=[e,r,Object.assign(Object.assign({},i),{internal:!0})]}this.define(t)}static mixins(e){function t(e,t){const s={};for(const[n,r]of(0,l.entries)(t))s[e+n]=r;return s}const s={},n=[];for(const r of(0,f.isArray)(e)?e:[e])if((0,f.isArray)(r)){const[e,i]=r;(0,l.extend)(s,t(e,i)),n.push([e,i])}else{const e=r;(0,l.extend)(s,e),n.push([\"\",e])}this.define(s),this.prototype._mixins=[...this.prototype._mixins,...n]}static override(e){for(const[t,s]of(0,l.entries)(e)){const e=this._fix_default(s,t),n=this.prototype._props[t];if(null==n)throw new Error(`attempted to override nonexistent '${this.prototype.type}.${t}'`);const r=Object.assign({},this.prototype._props);r[t]=Object.assign(Object.assign({},n),{default_value:e}),this.prototype._props=r}}toString(){return`${this.type}(${this.id})`}property(e){const t=this.properties[e];if(null!=t)return t;throw new Error(`unknown property ${this.type}.${e}`)}get attributes(){const e={};for(const t of this)e[t.attr]=t.get_value();return e}[m.clone](e){const t=new Map;for(const s of this)s.dirty&&t.set(s.attr,e.clone(s.get_value()));return new this.constructor(t)}[y.equals](e,t){for(const s of this){const n=e.property(s.attr);if(!t.eq(s.get_value(),n.get_value()))return!1}return!0}[v.pretty](e){const t=e.token,s=[];for(const n of this)if(n.dirty){const r=n.get_value();s.push(`${n.attr}${t(\":\")} ${e.to_string(r)}`)}return`${this.constructor.__qualified__}${t(\"(\")}${t(\"{\")}${s.join(`${t(\",\")} `)}${t(\"}\")}${t(\")\")}`}[d.serialize](e){const t=this.ref();e.add_ref(this,t);const s=this.struct();for(const t of this)t.syncable&&(e.include_defaults||t.dirty)&&(s.attributes[t.attr]=e.to_serializable(t.get_value()));return e.add_def(this,s),t}finalize(){for(const e of this){if(!(e instanceof _.VectorSpec||e instanceof _.ScalarSpec))continue;const t=e.get_value();if(null!=t){const{transform:e,expr:s}=t;null!=e&&this.connect(e.change,(()=>this.transformchange.emit())),null!=s&&this.connect(s.change,(()=>this.exprchange.emit()))}}this.initialize()}initialize(){}connect_signals(){}disconnect_signals(){c.Signal.disconnectReceiver(this)}destroy(){this.disconnect_signals(),this.destroyed.emit()}clone(){return(new m.Cloner).clone(this)}changed_for(e){const t=this._watchers.get(e);return this._watchers.set(e,!1),null==t||t}_setv(e,t){const s=t.check_eq,n=[],r=this._changing;this._changing=!0;for(const[t,r]of e)!1!==s&&(0,p.is_equal)(t.get_value(),r)||(t.set_value(r),n.push(t));n.length>0&&(this._watchers=new WeakMap,this._pending=!0);for(const e of n)e.change.emit();if(!r){if(!t.no_change)for(;this._pending;)this._pending=!1,this.change.emit();this._pending=!1,this._changing=!1}}setv(e,t={}){const s=(0,l.entries)(e);if(0==s.length)return;if(!0===t.silent){this._watchers=new WeakMap;for(const[e,t]of s)this.properties[e].set_value(t);return}const n=new Map,r=new Map;for(const[e,t]of s){const s=this.properties[e];n.set(s,t),r.set(s,s.get_value())}this._setv(n,t);const{document:i}=this;if(null!=i){const e=[];for(const[t,s]of r)e.push([t,s,t.get_value()]);for(const[,t,s]of e)if(this._needs_invalidate(t,s)){i._invalidate_all_models();break}this._push_changes(e,t)}}getv(e){return this.property(e).get_value()}ref(){return{id:this.id}}struct(){const e={type:this.type,id:this.id,attributes:{}};return null!=this._subtype&&(e.subtype=this._subtype),e}set_subtype(e){this._subtype=e}*[Symbol.iterator](){yield*(0,l.values)(this.properties)}*syncable_properties(){for(const e of this)e.syncable&&(yield e)}serializable_attributes(){const e={};for(const t of this.syncable_properties())e[t.attr]=t.get_value();return e}static _json_record_references(e,t,s,n){const{recursive:r}=n;if((0,a.is_ref)(t)){const n=e.get_model_by_id(t.id);null==n||s.has(n)||w._value_record_references(n,s,{recursive:r})}else if((0,f.isArray)(t))for(const n of t)w._json_record_references(e,n,s,{recursive:r});else if((0,f.isPlainObject)(t))for(const n of(0,l.values)(t))w._json_record_references(e,n,s,{recursive:r})}static _value_record_references(e,t,s){const{recursive:n}=s;if(e instanceof w){if(!t.has(e)&&(t.add(e),n))for(const s of e.syncable_properties()){const e=s.get_value();w._value_record_references(e,t,{recursive:n})}}else if((0,f.isArray)(e))for(const s of e)w._value_record_references(s,t,{recursive:n});else if((0,f.isPlainObject)(e))for(const s of(0,l.values)(e))w._value_record_references(s,t,{recursive:n})}references(){const e=new Set;return w._value_record_references(this,e,{recursive:!0}),e}_doc_attached(){}_doc_detached(){}attach_document(e){if(null!=this.document&&this.document!=e)throw new Error(\"models must be owned by only a single document\");this.document=e,this._doc_attached()}detach_document(){this._doc_detached(),this.document=null}_needs_invalidate(e,t){const s=new Set;w._value_record_references(t,s,{recursive:!1});const n=new Set;w._value_record_references(e,n,{recursive:!1});for(const e of s)if(!n.has(e))return!0;for(const e of n)if(!s.has(e))return!0;return!1}_push_changes(e,t={}){if(!this.is_syncable)return;const{document:s}=this;if(null==s)return;const{setter_id:n}=t,r=[];for(const[t,i,o]of e)t.syncable&&r.push(new g.ModelChangedEvent(s,this,t.attr,i,o,n));if(0!=r.length){let e;1==r.length?[e]=r:e=new g.DocumentEventBatch(s,r,n),s._trigger_on_change(e)}}on_change(e,t){for(const s of(0,f.isArray)(e)?e:[e])this.connect(s.change,t)}}s.HasProps=w,(o=w).prototype._props={},o.prototype._mixins=[]},\n", - " function _(n,t,e,l,s){l();const i=n(16),o=n(9);class c{constructor(n,t){this.sender=n,this.name=t}connect(n,t=null){u.has(this.sender)||u.set(this.sender,[]);const e=u.get(this.sender);if(null!=g(e,this,n,t))return!1;const l=null!=t?t:n;a.has(l)||a.set(l,[]);const s=a.get(l),i={signal:this,slot:n,context:t};return e.push(i),s.push(i),!0}disconnect(n,t=null){const e=u.get(this.sender);if(null==e||0===e.length)return!1;const l=g(e,this,n,t);if(null==l)return!1;const s=null!=t?t:n,i=a.get(s);return l.signal=null,d(e),d(i),!0}emit(n){var t;const e=null!==(t=u.get(this.sender))&&void 0!==t?t:[];for(const{signal:t,slot:l,context:s}of e)t===this&&l.call(s,n,this.sender)}}e.Signal=c,c.__name__=\"Signal\";class r extends c{emit(){super.emit(void 0)}}e.Signal0=r,r.__name__=\"Signal0\",function(n){function t(n,t){const e=u.get(n);if(null==e||0===e.length)return;const l=a.get(t);if(null!=l&&0!==l.length){for(const t of l){if(null==t.signal)return;t.signal.sender===n&&(t.signal=null)}d(e),d(l)}}function e(n){var t;const e=u.get(n);if(null!=e&&0!==e.length){for(const n of e){if(null==n.signal)return;const e=null!==(t=n.context)&&void 0!==t?t:n.slot;n.signal=null,d(a.get(e))}d(e)}}function l(n,t,e){const l=a.get(n);if(null!=l&&0!==l.length){for(const n of l){if(null==n.signal)return;if(null!=t&&n.slot!=t)continue;const l=n.signal.sender;null!=e&&e.has(l)||(n.signal=null,d(u.get(l)))}d(l)}}function s(n){const t=u.get(n);if(null!=t&&0!==t.length){for(const n of t)n.signal=null;d(t)}const e=a.get(n);if(null!=e&&0!==e.length){for(const n of e)n.signal=null;d(e)}}n.disconnect_between=t,n.disconnect_sender=e,n.disconnect_receiver=l,n.disconnect_all=s,n.disconnectBetween=t,n.disconnectSender=e,n.disconnectReceiver=l,n.disconnectAll=s}(c||(e.Signal=c={})),e.Signalable=function(){return class{connect(n,t){return n.connect(t,this)}disconnect(n,t){return n.disconnect(t,this)}}};const u=new WeakMap,a=new WeakMap;function g(n,t,e,l){return(0,o.find)(n,(n=>n.signal===t&&n.slot===e&&n.context===l))}const f=new Set;function d(n){0===f.size&&(async()=>{await(0,i.defer)(),function(){for(const n of f)(0,o.remove_by)(n,(n=>null==n.signal));f.clear()}()})(),f.add(n)}},\n", - " function _(e,n,t,s,o){s();const r=new MessageChannel,a=new Map;r.port1.onmessage=e=>{const n=e.data,t=a.get(n);if(null!=t)try{t()}finally{a.delete(n)}};let i=1;t.defer=function(){return new Promise((e=>{const n=i++;a.set(n,e),r.port2.postMessage(n)}))},t.wait=function(e){return new Promise((n=>setTimeout(n,e)))}},\n", - " function _(n,t,i,e,c){e();const r=n(8),s=n(13);i.is_ref=function(n){if((0,r.isPlainObject)(n)){const t=(0,s.keys)(n);return 1==t.length&&\"id\"==t[0]}return!1}},\n", - " function _(e,t,n,r,a){r(),n.YCoordinateSeqSeqSeqSpec=n.XCoordinateSeqSeqSeqSpec=n.YCoordinateSeqSpec=n.XCoordinateSeqSpec=n.YCoordinateSpec=n.XCoordinateSpec=n.CoordinateSeqSeqSeqSpec=n.CoordinateSeqSpec=n.CoordinateSpec=n.BaseCoordinateSpec=n.NumberUnitsSpec=n.UnitsSpec=n.DataSpec=n.VectorSpec=n.TextBaselineScalar=n.TextAlignScalar=n.FontStyleScalar=n.FontSizeScalar=n.FontScalar=n.LineDashScalar=n.LineCapScalar=n.LineJoinScalar=n.ArrayScalar=n.NullStringScalar=n.StringScalar=n.NumberScalar=n.ColorScalar=n.AnyScalar=n.ScalarSpec=n.VerticalAlign=n.UpdateMode=n.TooltipAttachment=n.TickLabelOrientation=n.TextureRepetition=n.TextBaseline=n.TextAlign=n.TapBehavior=n.StepMode=n.StartEnd=n.SpatialUnits=n.Sort=n.SizingMode=n.Side=n.RoundingFunction=n.ResetPolicy=n.RenderMode=n.RenderLevel=n.RadiusDimension=n.PointPolicy=n.Place=void 0,n.TextBaselineSpec=n.TextAlignSpec=n.FontStyleSpec=n.FontSizeSpec=n.FontSpec=n.LineDashSpec=n.LineCapSpec=n.LineJoinSpec=n.MarkerSpec=n.ArraySpec=n.NullStringSpec=n.StringSpec=n.AnySpec=n.NDArraySpec=n.ColorSpec=n.ScreenSizeSpec=n.NumberSpec=n.IntSpec=n.BooleanSpec=n.NullDistanceSpec=n.DistanceSpec=n.AngleSpec=void 0;const i=e(1),s=e(15),l=e(19),o=(0,i.__importStar)(e(20)),c=e(24),_=e(9),u=e(12),d=e(10),S=e(22),p=e(27),m=e(8),h=e(28),v=e(29),y=e(33);function x(e){try{return JSON.stringify(e)}catch(t){return e.toString()}}function g(e){return(0,m.isPlainObject)(e)&&(void 0===e.value?0:1)+(void 0===e.field?0:1)+(void 0===e.expr?0:1)==1}a(\"Uniform\",y.Uniform),a(\"UniformScalar\",y.UniformScalar),a(\"UniformVector\",y.UniformVector),n.isSpec=g;class f{constructor(e,t,n,r,a,i={}){var l;let o;if(this.obj=e,this.attr=t,this.kind=n,this.default_value=r,this._dirty=!1,this.change=new s.Signal0(this.obj,\"change\"),this.internal=null!==(l=i.internal)&&void 0!==l&&l,this.convert=i.convert,this.on_update=i.on_update,void 0!==a)o=a,this._dirty=!0;else{const t=this._default_override();if(void 0!==t)o=t;else{if(void 0===r)return void(this.spec={value:null});o=r(e)}}this._update(o)}get is_value(){return void 0!==this.spec.value}get syncable(){return!this.internal}get_value(){return this.spec.value}set_value(e){this._update(e),this._dirty=!0}_default_override(){}get dirty(){return this._dirty}_update(e){var t;if(this.validate(e),null!=this.convert){const t=this.convert(e);void 0!==t&&(e=t)}this.spec={value:e},null===(t=this.on_update)||void 0===t||t.call(this,e,this.obj)}toString(){return`Prop(${this.obj}.${this.attr}, spec: ${x(this.spec)})`}normalize(e){return e}validate(e){if(!this.valid(e))throw new Error(`${this.obj}.${this.attr} given invalid value: ${x(e)}`)}valid(e){return this.kind.valid(e)}_value(e=!0){if(!this.is_value)throw new Error(\"attempted to retrieve property value for property without value specification\");let t=this.normalize([this.spec.value])[0];return null!=this.spec.transform&&e&&(t=this.spec.transform.compute(t)),t}}n.Property=f,f.__name__=\"Property\";class A{constructor(e){this.attr=e}}n.PropertyAlias=A,A.__name__=\"PropertyAlias\",n.Alias=function(e){return new A(e)};class C extends f{}n.PrimitiveProperty=C,C.__name__=\"PrimitiveProperty\";class T extends f{}n.Any=T,T.__name__=\"Any\";class L extends f{valid(e){return(0,m.isArray)(e)||(0,m.isTypedArray)(e)}}n.Array=L,L.__name__=\"Array\";class w extends f{valid(e){return(0,m.isBoolean)(e)}}n.Boolean=w,w.__name__=\"Boolean\";class P extends f{valid(e){return(0,S.is_Color)(e)}}n.Color=P,P.__name__=\"Color\";class b extends f{}n.Instance=b,b.__name__=\"Instance\";class q extends f{valid(e){return(0,m.isNumber)(e)}}n.Number=q,q.__name__=\"Number\";class N extends q{valid(e){return(0,m.isNumber)(e)&&(0|e)==e}}n.Int=N,N.__name__=\"Int\";class z extends q{}n.Angle=z,z.__name__=\"Angle\";class B extends q{valid(e){return(0,m.isNumber)(e)&&0<=e&&e<=1}}n.Percent=B,B.__name__=\"Percent\";class F extends f{valid(e){return(0,m.isString)(e)}}n.String=F,F.__name__=\"String\";class D extends f{valid(e){return null===e||(0,m.isString)(e)}}n.NullString=D,D.__name__=\"NullString\";class U extends F{}n.FontSize=U,U.__name__=\"FontSize\";class M extends F{_default_override(){return h.settings.dev?\"Bokeh\":void 0}}n.Font=M,M.__name__=\"Font\";class R extends f{valid(e){return(0,m.isString)(e)&&(0,_.includes)(this.enum_values,e)}}function k(e){return class extends R{get enum_values(){return[...e]}}}n.EnumProperty=R,R.__name__=\"EnumProperty\",n.Enum=k;class O extends R{get enum_values(){return[...o.Direction]}normalize(e){const t=new Uint8Array(e.length);for(let n=0;n=0}}n.ScreenSizeSpec=fe,fe.__name__=\"ScreenSizeSpec\";class Ae extends ne{materialize(e){return(0,S.encode_rgba)((0,S.color2rgba)(e))}v_materialize(e){if(!(0,v.is_NDArray)(e)){const t=e.length,n=new c.RGBAArray(4*t);let r=0;for(const t of e){const[e,a,i,s]=(0,S.color2rgba)(t);n[r++]=e,n[r++]=a,n[r++]=i,n[r++]=s}return new c.ColorArray(n.buffer)}if(\"uint32\"==e.dtype&&1==e.dimension)return(0,p.to_big_endian)(e);if(\"uint8\"==e.dtype&&1==e.dimension){const[t]=e.shape,n=new c.RGBAArray(4*t);let r=0;for(const t of e)n[r++]=t,n[r++]=t,n[r++]=t,n[r++]=255;return new c.ColorArray(n.buffer)}if(\"uint8\"==e.dtype&&2==e.dimension){const[t,n]=e.shape;if(4==n)return new c.ColorArray(e.buffer);if(3==n){const r=new c.RGBAArray(4*t);for(let a=0,i=0;a0){let o=r[e];return null==o&&(r[e]=o=new v(e,l)),o}throw new TypeError(\"Logger.get() expects a non-empty string name and an optional log-level\")}get level(){return this.get_level()}get_level(){return this._log_level}set_level(e){if(e instanceof i)this._log_level=e;else{if(!(0,s.isString)(e)||null==v.log_levels[e])throw new Error(\"Logger.set_level() expects a log-level object or a string name of a log-level\");this._log_level=v.log_levels[e]}const l=`[${this._name}]`;for(const[e,o]of(0,g.entries)(v.log_levels))o.level\",\"*\"),t.HTTPMethod=(0,a.Enum)(\"POST\",\"GET\"),t.HexTileOrientation=(0,a.Enum)(\"pointytop\",\"flattop\"),t.HoverMode=(0,a.Enum)(\"mouse\",\"hline\",\"vline\"),t.LatLon=(0,a.Enum)(\"lat\",\"lon\"),t.LegendClickPolicy=(0,a.Enum)(\"none\",\"hide\",\"mute\"),t.LegendLocation=t.Anchor,t.LineCap=(0,a.Enum)(\"butt\",\"round\",\"square\"),t.LineJoin=(0,a.Enum)(\"miter\",\"round\",\"bevel\"),t.LineDash=(0,a.Enum)(\"solid\",\"dashed\",\"dotted\",\"dotdash\",\"dashdot\"),t.LinePolicy=(0,a.Enum)(\"prev\",\"next\",\"nearest\",\"interp\",\"none\"),t.Location=(0,a.Enum)(\"above\",\"below\",\"left\",\"right\"),t.Logo=(0,a.Enum)(\"normal\",\"grey\"),t.MarkerType=(0,a.Enum)(\"asterisk\",\"circle\",\"circle_cross\",\"circle_dot\",\"circle_x\",\"circle_y\",\"cross\",\"dash\",\"diamond\",\"diamond_cross\",\"diamond_dot\",\"dot\",\"hex\",\"hex_dot\",\"inverted_triangle\",\"plus\",\"square\",\"square_cross\",\"square_dot\",\"square_pin\",\"square_x\",\"star\",\"star_dot\",\"triangle\",\"triangle_dot\",\"triangle_pin\",\"x\",\"y\"),t.MutedPolicy=(0,a.Enum)(\"show\",\"ignore\"),t.Orientation=(0,a.Enum)(\"vertical\",\"horizontal\"),t.OutputBackend=(0,a.Enum)(\"canvas\",\"svg\",\"webgl\"),t.PaddingUnits=(0,a.Enum)(\"percent\",\"absolute\"),t.Place=(0,a.Enum)(\"above\",\"below\",\"left\",\"right\",\"center\"),t.PointPolicy=(0,a.Enum)(\"snap_to_data\",\"follow_mouse\",\"none\"),t.RadiusDimension=(0,a.Enum)(\"x\",\"y\",\"max\",\"min\"),t.RenderLevel=(0,a.Enum)(\"image\",\"underlay\",\"glyph\",\"guide\",\"annotation\",\"overlay\"),t.RenderMode=(0,a.Enum)(\"canvas\",\"css\"),t.ResetPolicy=(0,a.Enum)(\"standard\",\"event_only\"),t.RoundingFunction=(0,a.Enum)(\"round\",\"nearest\",\"floor\",\"rounddown\",\"ceil\",\"roundup\"),t.SelectionMode=(0,a.Enum)(\"replace\",\"append\",\"intersect\",\"subtract\"),t.Side=(0,a.Enum)(\"above\",\"below\",\"left\",\"right\"),t.SizingMode=(0,a.Enum)(\"stretch_width\",\"stretch_height\",\"stretch_both\",\"scale_width\",\"scale_height\",\"scale_both\",\"fixed\"),t.Sort=(0,a.Enum)(\"ascending\",\"descending\"),t.SpatialUnits=(0,a.Enum)(\"screen\",\"data\"),t.StartEnd=(0,a.Enum)(\"start\",\"end\"),t.StepMode=(0,a.Enum)(\"after\",\"before\",\"center\"),t.TapBehavior=(0,a.Enum)(\"select\",\"inspect\"),t.TextAlign=(0,a.Enum)(\"left\",\"right\",\"center\"),t.TextBaseline=(0,a.Enum)(\"top\",\"middle\",\"bottom\",\"alphabetic\",\"hanging\",\"ideographic\"),t.TextureRepetition=(0,a.Enum)(\"repeat\",\"repeat_x\",\"repeat_y\",\"no_repeat\"),t.TickLabelOrientation=(0,a.Enum)(\"vertical\",\"horizontal\",\"parallel\",\"normal\"),t.TooltipAttachment=(0,a.Enum)(\"horizontal\",\"vertical\",\"left\",\"right\",\"above\",\"below\"),t.UpdateMode=(0,a.Enum)(\"replace\",\"append\"),t.VerticalAlign=(0,a.Enum)(\"top\",\"middle\",\"bottom\")},\n", - " function _(e,n,t,s,r){s();const i=(0,e(1).__importStar)(e(8)),a=e(22),l=e(13),_=window.Map,{hasOwnProperty:u}=Object.prototype;class d{}t.Kind=d,d.__name__=\"Kind\",function(e){class n extends d{valid(e){return!0}}n.__name__=\"Any\",e.Any=n;class t extends d{valid(e){return!0}}t.__name__=\"Unknown\",e.Unknown=t;class s extends d{valid(e){return i.isBoolean(e)}}s.__name__=\"Boolean\",e.Boolean=s;class r extends d{constructor(e){super(),this.obj_type=e}valid(e){return!0}}r.__name__=\"Ref\",e.Ref=r;class c extends d{valid(e){return!0}}c.__name__=\"AnyRef\",e.AnyRef=c;class o extends d{valid(e){return i.isNumber(e)}}o.__name__=\"Number\",e.Number=o;class p extends o{valid(e){return super.valid(e)&&i.isInteger(e)}}p.__name__=\"Int\",e.Int=p;class y extends o{valid(e){return super.valid(e)&&0<=e&&e<=1}}y.__name__=\"Percent\",e.Percent=y;class m extends d{constructor(e){super(),this.types=e,this.types=e}valid(e){return this.types.some((n=>n.valid(e)))}}m.__name__=\"Or\",e.Or=m;class v extends d{constructor(e){super(),this.types=e,this.types=e}valid(e){if(!i.isArray(e))return!1;for(let n=0;nthis.item_type.valid(e)))}}f.__name__=\"Array\",e.Array=f;class K extends d{valid(e){return null===e}}K.__name__=\"Null\",e.Null=K;class b extends d{constructor(e){super(),this.base_type=e}valid(e){return null===e||this.base_type.valid(e)}}b.__name__=\"Nullable\",e.Nullable=b;class A extends d{constructor(e){super(),this.base_type=e}valid(e){return void 0===e||this.base_type.valid(e)}}A.__name__=\"Opt\",e.Opt=A;class x extends d{valid(e){return i.isString(e)}}x.__name__=\"String\",e.String=x;class S extends d{constructor(e){super(),this.values=new Set(e)}valid(e){return this.values.has(e)}*[Symbol.iterator](){yield*this.values}}S.__name__=\"Enum\",e.Enum=S;class N extends d{constructor(e){super(),this.item_type=e}valid(e){if(!i.isPlainObject(e))return!1;for(const n in e)if(u.call(e,n)){const t=e[n];if(!this.item_type.valid(t))return!1}return!0}}N.__name__=\"Dict\",e.Dict=N;class O extends d{constructor(e,n){super(),this.key_type=e,this.item_type=n}valid(e){if(!(e instanceof _))return!1;for(const[n,t]of e.entries())if(!this.key_type.valid(n)||!this.item_type.valid(t))return!1;return!0}}O.__name__=\"Map\",e.Map=O;class g extends d{valid(e){return(0,a.is_Color)(e)}}g.__name__=\"Color\",e.Color=g;class P extends d{valid(e){return i.isFunction(e)}}P.__name__=\"Function\",e.Function=P}(t.Kinds||(t.Kinds={})),t.Any=new t.Kinds.Any,t.Unknown=new t.Kinds.Unknown,t.Boolean=new t.Kinds.Boolean,t.Number=new t.Kinds.Number,t.Int=new t.Kinds.Int,t.String=new t.Kinds.String,t.Null=new t.Kinds.Null;t.Nullable=e=>new t.Kinds.Nullable(e);t.Opt=e=>new t.Kinds.Opt(e);t.Or=(...e)=>new t.Kinds.Or(e);t.Tuple=(...e)=>new t.Kinds.Tuple(e);t.Struct=e=>new t.Kinds.Struct(e),t.Arrayable=new t.Kinds.Arrayable;t.Array=e=>new t.Kinds.Array(e);t.Dict=e=>new t.Kinds.Dict(e);t.Map=(e,n)=>new t.Kinds.Map(e,n);t.Enum=(...e)=>new t.Kinds.Enum(e);t.Ref=e=>new t.Kinds.Ref(e);t.AnyRef=()=>new t.Kinds.AnyRef;t.Function=()=>new t.Kinds.Function,t.Percent=new t.Kinds.Percent,t.Alpha=t.Percent,t.Color=new t.Kinds.Color,t.Auto=(0,t.Enum)(\"auto\"),t.FontSize=t.String,t.Font=t.String,t.Angle=t.Number},\n", - " function _(n,t,r,e,s){e();const u=n(23),c=n(10),l=n(8),{round:i}=Math;function o(n){return(0,c.clamp)(i(n),0,255)}function a(){return[0,0,0,0]}function f(n){return[n>>24&255,n>>16&255,n>>8&255,255&n]}function d(n,t){var r;let e,s,u,c;return null==n?[e,s,u,c]=[0,0,0,0]:(0,l.isInteger)(n)?[e,s,u,c]=f(n):(0,l.isString)(n)?[e,s,u,c]=null!==(r=_(n))&&void 0!==r?r:[0,0,0,0]:([e,s,u,c=1]=n,c=o(255*c)),255==c&&null!=t&&(c=o(255*t)),[e,s,u,c]}r.transparent=a,r.encode_rgba=function([n,t,r,e]){return n<<24|t<<16|r<<8|e},r.decode_rgba=f,r.compose_alpha=function(n,t){return 255==(255&n)?4294967040&n|o(255*t):n},r.color2rgba=d;const h={0:\"0\",1:\"1\",2:\"2\",3:\"3\",4:\"4\",5:\"5\",6:\"6\",7:\"7\",8:\"8\",9:\"9\",10:\"a\",11:\"b\",12:\"c\",13:\"d\",14:\"e\",15:\"f\"};function g(n){return h[n>>4]+h[15&n]}r.color2css=function(n,t){const[r,e,s,u]=d(n,t);return`rgba(${r}, ${e}, ${s}, ${u/255})`},r.color2hex=function(n,t){const[r,e,s,u]=d(n,t),c=`#${g(r)}${g(e)}${g(s)}`;return 255==u?c:`${c}${g(u)}`},r.color2hexrgb=function(n){const[t,r,e]=d(n);return`#${g(t)}${g(r)}${g(e)}`};const b=/^rgba?\\(\\s*([^\\s,]+?)\\s+([^\\s,]+?)\\s+([^\\s,]+?)(?:\\s*\\/\\s*([^\\s,]+?))?\\s*\\)$/,$=/^rgba?\\(\\s*([^\\s,]+?)\\s*,\\s*([^\\s,]+?)\\s*,\\s*([^\\s,]+?)(?:\\s*,\\s*([^\\s,]+?))?\\s*\\)$/,m=(()=>{const n=document.createElement(\"canvas\");n.width=1,n.height=1;const t=n.getContext(\"2d\"),r=t.createLinearGradient(0,0,1,1);return n=>{t.fillStyle=r,t.fillStyle=n;const e=t.fillStyle;return e!=r?e:null}})();function _(n){var t;if(!(n=n.trim().toLowerCase()))return null;if(\"transparent\"==n)return[0,0,0,0];if((0,u.is_named_color)(n))return f(u.named_colors[n]);if(\"#\"==n[0]){const t=Number(`0x${n.substr(1)}`);if(isNaN(t))return null;switch(n.length-1){case 3:{const n=t>>8&15,r=t>>4&15,e=t>>0&15;return[n<<4|n,r<<4|r,e<<4|e,255]}case 4:{const n=t>>12&15,r=t>>8&15,e=t>>4&15,s=t>>0&15;return[n<<4|n,r<<4|r,e<<4|e,s<<4|s]}case 6:return[t>>16&255,t>>8&255,t>>0&255,255];case 8:return[t>>24&255,t>>16&255,t>>8&255,t>>0&255]}}else if(n.startsWith(\"rgb\")){const r=null!==(t=n.match(b))&&void 0!==t?t:n.match($);if(null!=r){let[,n,t,e,s=\"1\"]=r;const u=n.endsWith(\"%\"),c=t.endsWith(\"%\"),l=e.endsWith(\"%\"),i=s.endsWith(\"%\");if(!(u&&c&&l)&&(u||c||l))return null;u&&(n=n.slice(0,-1)),c&&(t=t.slice(0,-1)),l&&(e=e.slice(0,-1)),i&&(s=s.slice(0,-1));let a=Number(n),f=Number(t),d=Number(e),h=Number(s);return isNaN(a+f+d+h)?null:(u&&(a=a/100*255),c&&(f=f/100*255),l&&(d=d/100*255),h=255*(i?h/100:h),a=o(a),f=o(f),d=o(d),h=o(h),[a,f,d,h])}}else{const t=m(n);if(null!=t)return _(t)}return null}r.css4_parse=_,r.is_Color=function(n){return!!(0,l.isInteger)(n)||(!(!(0,l.isString)(n)||null==_(n))||!(!(0,l.isArray)(n)||3!=n.length&&4!=n.length))},r.is_dark=function([n,t,r]){return 1-(.299*n+.587*t+.114*r)/255>=.6}},\n", - " function _(e,r,l,a,i){a();l.named_colors={aliceblue:4042850303,antiquewhite:4209760255,aqua:16777215,aquamarine:2147472639,azure:4043309055,beige:4126530815,bisque:4293182719,black:255,blanchedalmond:4293643775,blue:65535,blueviolet:2318131967,brown:2771004159,burlywood:3736635391,cadetblue:1604231423,chartreuse:2147418367,chocolate:3530104575,coral:4286533887,cornflowerblue:1687547391,cornsilk:4294499583,crimson:3692313855,cyan:16777215,darkblue:35839,darkcyan:9145343,darkgoldenrod:3095792639,darkgray:2846468607,darkgreen:6553855,darkgrey:2846468607,darkkhaki:3182914559,darkmagenta:2332068863,darkolivegreen:1433087999,darkorange:4287365375,darkorchid:2570243327,darkred:2332033279,darksalmon:3918953215,darkseagreen:2411499519,darkslateblue:1211993087,darkslategray:793726975,darkslategrey:793726975,darkturquoise:13554175,darkviolet:2483082239,deeppink:4279538687,deepskyblue:12582911,dimgray:1768516095,dimgrey:1768516095,dodgerblue:512819199,firebrick:2988581631,floralwhite:4294635775,forestgreen:579543807,fuchsia:4278255615,gainsboro:3705462015,ghostwhite:4177068031,gold:4292280575,goldenrod:3668254975,gray:2155905279,green:8388863,greenyellow:2919182335,grey:2155905279,honeydew:4043305215,hotpink:4285117695,indianred:3445382399,indigo:1258324735,ivory:4294963455,khaki:4041641215,lavender:3873897215,lavenderblush:4293981695,lawngreen:2096890111,lemonchiffon:4294626815,lightblue:2916673279,lightcoral:4034953471,lightcyan:3774873599,lightgoldenrodyellow:4210742015,lightgray:3553874943,lightgreen:2431553791,lightgrey:3553874943,lightpink:4290167295,lightsalmon:4288707327,lightseagreen:548580095,lightskyblue:2278488831,lightslategray:2005441023,lightslategrey:2005441023,lightsteelblue:2965692159,lightyellow:4294959359,lime:16711935,limegreen:852308735,linen:4210091775,magenta:4278255615,maroon:2147483903,mediumaquamarine:1724754687,mediumblue:52735,mediumorchid:3126187007,mediumpurple:2473647103,mediumseagreen:1018393087,mediumslateblue:2070474495,mediumspringgreen:16423679,mediumturquoise:1221709055,mediumvioletred:3340076543,midnightblue:421097727,mintcream:4127193855,mistyrose:4293190143,moccasin:4293178879,navajowhite:4292783615,navy:33023,oldlace:4260751103,olive:2155872511,olivedrab:1804477439,orange:4289003775,orangered:4282712319,orchid:3664828159,palegoldenrod:4008225535,palegreen:2566625535,paleturquoise:2951671551,palevioletred:3681588223,papayawhip:4293907967,peachpuff:4292524543,peru:3448061951,pink:4290825215,plum:3718307327,powderblue:2967529215,purple:2147516671,rebeccapurple:1714657791,red:4278190335,rosybrown:3163525119,royalblue:1097458175,saddlebrown:2336560127,salmon:4202722047,sandybrown:4104413439,seagreen:780883967,seashell:4294307583,sienna:2689740287,silver:3233857791,skyblue:2278484991,slateblue:1784335871,slategray:1887473919,slategrey:1887473919,snow:4294638335,springgreen:16744447,steelblue:1182971135,tan:3535047935,teal:8421631,thistle:3636451583,tomato:4284696575,turquoise:1088475391,violet:4001558271,wheat:4125012991,white:4294967295,whitesmoke:4126537215,yellow:4294902015,yellowgreen:2597139199},l.is_named_color=function(e){return e in l.named_colors}},\n", - " function _(r,t,n,a,o){a(),n.GeneratorFunction=Object.getPrototypeOf((function*(){})).constructor,n.ColorArray=Uint32Array,n.RGBAArray=Uint8ClampedArray,n.infer_type=function(r,t){return r instanceof Float64Array||r instanceof Array||t instanceof Float64Array||t instanceof Array?Float64Array:Float32Array},n.ScreenArray=Float32Array,n.to_screen=function(r){return r instanceof Float32Array?r:Float32Array.from(r)},o(\"Indices\",r(25).BitSet)},\n", - " function _(t,s,r,e,i){var n;e();const o=t(26),a=t(11);class _{constructor(t,s=0){this.size=t,this[n]=\"BitSet\",this._count=null,this._nwords=Math.ceil(t/32),0==s||1==s?(this._array=new Uint32Array(this._nwords),1==s&&this._array.fill(4294967295)):((0,a.assert)(s.length==this._nwords,\"Initializer size mismatch\"),this._array=s)}clone(){return new _(this.size,new Uint32Array(this._array))}[(n=Symbol.toStringTag,o.equals)](t,s){if(!s.eq(this.size,t.size))return!1;const{_nwords:r}=this,e=this.size%r,i=0==e?r:r-1;for(let s=0;s>>5,r=31&t;return!!(this._array[s]>>r&1)}set(t,s=!0){this._check_bounds(t),this._count=null;const r=t>>>5,e=31&t;s?this._array[r]|=1<>>t&1&&(e+=1)}return e}*ones(){const{_array:t,_nwords:s,size:r}=this;for(let e=0,i=0;i>>t&1&&(yield e);else e+=32}}*zeros(){const{_array:t,_nwords:s,size:r}=this;for(let e=0,i=0;i>>t&1||(yield e);else e+=32}}_check_size(t){(0,a.assert)(this.size==t.size,\"Size mismatch\")}add(t){this._check_size(t);for(let s=0;s{if(a(t)&&a(e))return t[r.equals](e,this);switch(n){case\"[object Array]\":case\"[object Uint8Array]\":case\"[object Int8Array]\":case\"[object Uint16Array]\":case\"[object Int16Array]\":case\"[object Uint32Array]\":case\"[object Int32Array]\":case\"[object Float32Array]\":case\"[object Float64Array]\":return this.arrays(t,e);case\"[object Map]\":return this.maps(t,e);case\"[object Set]\":return this.sets(t,e);case\"[object Object]\":if(t.constructor==e.constructor&&(null==t.constructor||t.constructor===Object))return this.objects(t,e);case\"[object Function]\":if(t.constructor==e.constructor&&t.constructor===Function)return this.eq(`${t}`,`${e}`)}if(t instanceof Node)return this.nodes(t,e);throw Error(`can't compare objects of type ${n}`)})();return s.pop(),o.pop(),u}numbers(t,e){return Object.is(t,e)}arrays(t,e){const{length:r}=t;if(r!=e.length)return!1;for(let n=0;n{const n=navigator.userAgent;return n.includes(\"MSIE\")||n.includes(\"Trident\")||n.includes(\"Edge\")})(),e.is_mobile=\"undefined\"!=typeof window&&(\"ontouchstart\"in window||navigator.maxTouchPoints>0),e.is_little_endian=(()=>{const n=new ArrayBuffer(4),i=new Uint8Array(n);new Uint32Array(n)[1]=168496141;let e=!0;return 10==i[4]&&11==i[5]&&12==i[6]&&13==i[7]&&(e=!1),e})(),e.BYTE_ORDER=e.is_little_endian?\"little\":\"big\",e.to_big_endian=function(n){if(e.is_little_endian){const i=new Uint32Array(n.length),e=new DataView(i.buffer);let t=0;for(const i of n)e.setUint32(t,i),t+=4;return i}return n}},\n", - " function _(e,t,r,s,_){s();class i{constructor(){this._dev=!1,this._wireframe=!1,this._force_webgl=!1}set dev(e){this._dev=e}get dev(){return this._dev}set wireframe(e){this._wireframe=e}get wireframe(){return this._wireframe}set force_webgl(e){this._force_webgl=e}get force_webgl(){return this._force_webgl}}r.Settings=i,i.__name__=\"Settings\",r.settings=new i},\n", - " function _(e,s,t,i,r){var a,n,l,h,u,o,p,c;i();const y=e(8),_=e(11),A=e(26),q=e(30),d=e(31),z=Symbol(\"__ndarray__\");class D extends Uint8Array{constructor(e,s){super(e),this[a]=!0,this.dtype=\"uint8\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>D.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>D.prototype[q.serialize].call(this,e))}[(a=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Uint8NDArray=D,D.__name__=\"Uint8NDArray\";class N extends Int8Array{constructor(e,s){super(e),this[n]=!0,this.dtype=\"int8\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>N.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>N.prototype[q.serialize].call(this,e))}[(n=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Int8NDArray=N,N.__name__=\"Int8NDArray\";class f extends Uint16Array{constructor(e,s){super(e),this[l]=!0,this.dtype=\"uint16\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>f.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>f.prototype[q.serialize].call(this,e))}[(l=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Uint16NDArray=f,f.__name__=\"Uint16NDArray\";class m extends Int16Array{constructor(e,s){super(e),this[h]=!0,this.dtype=\"int16\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>m.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>m.prototype[q.serialize].call(this,e))}[(h=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Int16NDArray=m,m.__name__=\"Int16NDArray\";class g extends Uint32Array{constructor(e,s){super(e),this[u]=!0,this.dtype=\"uint32\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>g.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>g.prototype[q.serialize].call(this,e))}[(u=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Uint32NDArray=g,g.__name__=\"Uint32NDArray\";class I extends Int32Array{constructor(e,s){super(e),this[o]=!0,this.dtype=\"int32\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>I.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>I.prototype[q.serialize].call(this,e))}[(o=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Int32NDArray=I,I.__name__=\"Int32NDArray\";class U extends Float32Array{constructor(e,s){super(e),this[p]=!0,this.dtype=\"float32\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>U.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>U.prototype[q.serialize].call(this,e))}[(p=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}t.Float32NDArray=U,U.__name__=\"Float32NDArray\";class w extends Float64Array{constructor(e,s){super(e),this[c]=!0,this.dtype=\"float64\",this.shape=null!=s?s:x(e)?e.shape:[this.length],this.dimension=this.shape.length,null==this[A.equals]&&(this[A.equals]=(e,s)=>w.prototype[A.equals].call(this,e,s)),null==this[q.serialize]&&(this[q.serialize]=e=>w.prototype[q.serialize].call(this,e))}[(c=z,A.equals)](e,s){return s.eq(this.shape,e.shape)&&s.arrays(this,e)}[q.serialize](e){return(0,d.encode_NDArray)(this)}}function x(e){return(0,y.isObject)(e)&&void 0!==e[z]}t.Float64NDArray=w,w.__name__=\"Float64NDArray\",t.is_NDArray=x,t.ndarray=function(e,s={}){let{dtype:t}=s;null==t&&(t=e instanceof ArrayBuffer||(0,y.isArray)(e)?\"float64\":(()=>{switch(!0){case e instanceof Uint8Array:return\"uint8\";case e instanceof Int8Array:return\"int8\";case e instanceof Uint16Array:return\"uint16\";case e instanceof Int16Array:return\"int16\";case e instanceof Uint32Array:return\"uint32\";case e instanceof Int32Array:return\"int32\";case e instanceof Float32Array:return\"float32\";case e instanceof Float64Array:return\"float64\";default:(0,_.unreachable)()}})());const{shape:i}=s;switch(t){case\"uint8\":return new D(e,i);case\"int8\":return new N(e,i);case\"uint16\":return new f(e,i);case\"int16\":return new m(e,i);case\"uint32\":return new g(e,i);case\"int32\":return new I(e,i);case\"float32\":return new U(e,i);case\"float64\":return new w(e,i)}}},\n", - " function _(e,r,t,i,s){i();const n=e(11),a=e(13),l=e(8);t.serialize=Symbol(\"serialize\");class o extends Error{}t.SerializationError=o,o.__name__=\"SerializationError\";class f{constructor(e){var r;this._references=new Map,this._definitions=new Map,this._refmap=new Map,this.include_defaults=null===(r=null==e?void 0:e.include_defaults)||void 0===r||r}get_ref(e){return this._references.get(e)}add_ref(e,r){(0,n.assert)(!this._references.has(e)),this._references.set(e,r)}add_def(e,r){const t=this.get_ref(e);(0,n.assert)(null!=t),this._definitions.set(e,r),this._refmap.set(t,r)}get objects(){return new Set(this._references.keys())}get references(){return new Set(this._references.values())}get definitions(){return new Set(this._definitions.values())}resolve_ref(e){return this._refmap.get(e)}remove_ref(e){return this._references.delete(e)}remove_def(e){return this._definitions.delete(e)}to_serializable(e){const r=this.get_ref(e);if(null!=r)return r;if(function(e){return(0,l.isObject)(e)&&void 0!==e[t.serialize]}(e))return e[t.serialize](this);if((0,l.isArray)(e)||(0,l.isTypedArray)(e)){const r=e.length,t=new Array(r);for(let i=0;i(0,s.buffer_to_base64)(_.buffer)};return Object.assign({__ndarray__:e},r)}}},\n", - " function _(t,n,e,r,o){r(),e.buffer_to_base64=function(t){const n=new Uint8Array(t),e=Array.from(n).map((t=>String.fromCharCode(t)));return btoa(e.join(\"\"))},e.base64_to_buffer=function(t){const n=atob(t),e=n.length,r=new Uint8Array(e);for(let t=0,o=e;t\"'`])/g,(t=>{switch(t){case\"&\":return\"&\";case\"<\":return\"<\";case\">\":return\">\";case'\"':return\""\";case\"'\":return\"'\";case\"`\":return\"`\";default:return t}}))},r.unescape=function(t){return t.replace(/&(amp|lt|gt|quot|#x27|#x60);/g,((t,e)=>{switch(e){case\"amp\":return\"&\";case\"lt\":return\"<\";case\"gt\":return\">\";case\"quot\":return'\"';case\"#x27\":return\"'\";case\"#x60\":return\"`\";default:return e}}))},r.use_strict=function(t){return`'use strict';\\n${t}`},r.to_fixed=function(t,e){return t.toFixed(e).replace(/(\\.[0-9]*?)0+$/,\"$1\").replace(/\\.$/,\"\")}},\n", - " function _(e,t,s,n,o){n();const i=e(30);class r{constructor(e){this.document=e}}s.DocumentEvent=r,r.__name__=\"DocumentEvent\";class a extends r{constructor(e,t,s){super(e),this.events=t,this.setter_id=s}}s.DocumentEventBatch=a,a.__name__=\"DocumentEventBatch\";class d extends r{}s.DocumentChangedEvent=d,d.__name__=\"DocumentChangedEvent\";class l extends d{constructor(e,t,s){super(e),this.msg_type=t,this.msg_data=s}[i.serialize](e){const t=this.msg_data,s=e.to_serializable(t);return{kind:\"MessageSent\",msg_type:this.msg_type,msg_data:s}}}s.MessageSentEvent=l,l.__name__=\"MessageSentEvent\";class _ extends d{constructor(e,t,s,n,o,i,r){super(e),this.model=t,this.attr=s,this.old=n,this.new_=o,this.setter_id=i,this.hint=r}[i.serialize](e){if(null!=this.hint)return e.to_serializable(this.hint);const t=this.new_,s=e.to_serializable(t);return this.model!=t&&e.remove_def(this.model),{kind:\"ModelChanged\",model:this.model.ref(),attr:this.attr,new:s}}}s.ModelChangedEvent=_,_.__name__=\"ModelChangedEvent\";class c extends d{constructor(e,t,s){super(e),this.column_source=t,this.patches=s}[i.serialize](e){return{kind:\"ColumnsPatched\",column_source:this.column_source,patches:this.patches}}}s.ColumnsPatchedEvent=c,c.__name__=\"ColumnsPatchedEvent\";class h extends d{constructor(e,t,s,n){super(e),this.column_source=t,this.data=s,this.rollover=n}[i.serialize](e){return{kind:\"ColumnsStreamed\",column_source:this.column_source,data:this.data,rollover:this.rollover}}}s.ColumnsStreamedEvent=h,h.__name__=\"ColumnsStreamedEvent\";class m extends d{constructor(e,t,s){super(e),this.title=t,this.setter_id=s}[i.serialize](e){return{kind:\"TitleChanged\",title:this.title}}}s.TitleChangedEvent=m,m.__name__=\"TitleChangedEvent\";class u extends d{constructor(e,t,s){super(e),this.model=t,this.setter_id=s}[i.serialize](e){return{kind:\"RootAdded\",model:e.to_serializable(this.model)}}}s.RootAddedEvent=u,u.__name__=\"RootAddedEvent\";class v extends d{constructor(e,t,s){super(e),this.model=t,this.setter_id=s}[i.serialize](e){return{kind:\"RootRemoved\",model:this.model.ref()}}}s.RootRemovedEvent=v,v.__name__=\"RootRemovedEvent\"},\n", - " function _(t,i,r,n,s){n();const e=t(8),o=t(13);r.pretty=Symbol(\"pretty\");class c{constructor(t){this.visited=new Set,this.precision=null==t?void 0:t.precision}to_string(t){if((0,e.isObject)(t)){if(this.visited.has(t))return\"\";this.visited.add(t)}return function(t){return(0,e.isObject)(t)&&void 0!==t[r.pretty]}(t)?t[r.pretty](this):(0,e.isBoolean)(t)?this.boolean(t):(0,e.isNumber)(t)?this.number(t):(0,e.isString)(t)?this.string(t):(0,e.isArray)(t)?this.array(t):(0,e.isIterable)(t)?this.iterable(t):(0,e.isPlainObject)(t)?this.object(t):(0,e.isSymbol)(t)?this.symbol(t):`${t}`}token(t){return t}boolean(t){return`${t}`}number(t){return null!=this.precision?t.toFixed(this.precision):`${t}`}string(t){return`\"${t.replace(/'/g,\"\\\\'\")}\"`}symbol(t){return t.toString()}array(t){const i=this.token,r=[];for(const i of t)r.push(this.to_string(i));return`${i(\"[\")}${r.join(`${i(\",\")} `)}${i(\"]\")}`}iterable(t){var i;const r=this.token,n=null!==(i=Object(t)[Symbol.toStringTag])&&void 0!==i?i:\"Object\",s=this.array(t);return`${n}${r(\"(\")}${s}${r(\")\")}`}object(t){const i=this.token,r=[];for(const[n,s]of(0,o.entries)(t))r.push(`${n}${i(\":\")} ${this.to_string(s)}`);return`${i(\"{\")}${r.join(`${i(\",\")} `)}${i(\"}\")}`}}r.Printer=c,c.__name__=\"Printer\",r.to_string=function(t,i){return new c(i).to_string(t)}},\n", - " function _(n,o,r,e,t){e();const l=n(13),i=n(8);function c(n){return(0,i.isObject)(n)&&void 0!==n[r.clone]}r.clone=Symbol(\"clone\"),r.is_Cloneable=c;class s extends Error{}r.CloningError=s,s.__name__=\"CloningError\";class a{constructor(){}clone(n){if(c(n))return n[r.clone](this);if((0,i.isArray)(n)){const o=n.length,r=new Array(o);for(let e=0;e{null!=this.layout&&(this.layout.visible=this.model.visible,this.plot_view.request_layout())}))}get needs_clip(){return null==this.layout}serializable_state(){const t=super.serializable_state();return null==this.layout?t:Object.assign(Object.assign({},t),{bbox:this.layout.bbox.box})}}i.AnnotationView=r,r.__name__=\"AnnotationView\";class a extends l.Renderer{constructor(t){super(t)}}i.Annotation=a,o=a,a.__name__=\"Annotation\",o.override({level:\"annotation\"})},\n", - " function _(e,i,t,n,s){n();const r=e(1);var o,a;const _=e(42),l=(0,r.__importStar)(e(45)),d=e(20),h=e(53),u=e(54);class c extends h.Model{constructor(e){super(e)}}t.RendererGroup=c,o=c,c.__name__=\"RendererGroup\",o.define((({Boolean:e})=>({visible:[e,!0]})));class p extends _.View{get coordinates(){const{_coordinates:e}=this;return null!=e?e:this._coordinates=this._initialize_coordinates()}initialize(){super.initialize(),this.visuals=new l.Visuals(this),this.needs_webgl_blit=!1}connect_signals(){super.connect_signals();const{x_range_name:e,y_range_name:i}=this.model.properties;this.on_change([e,i],(()=>this._initialize_coordinates()));const{group:t}=this.model;null!=t&&this.on_change(t.properties.visible,(()=>{this.model.visible=t.visible}))}_initialize_coordinates(){const{coordinates:e}=this.model,{frame:i}=this.plot_view;if(null!=e)return e.get_transform(i);{const{x_range_name:e,y_range_name:t}=this.model,n=i.x_scales.get(e),s=i.y_scales.get(t);return new u.CoordinateTransform(n,s)}}get plot_view(){return this.parent}get plot_model(){return this.parent.model}get layer(){const{overlays:e,primary:i}=this.canvas;return\"overlay\"==this.model.level?e:i}get canvas(){return this.plot_view.canvas_view}request_render(){this.request_paint()}request_paint(){this.plot_view.request_paint(this)}request_layout(){this.plot_view.request_layout()}notify_finished(){this.plot_view.notify_finished()}notify_finished_after_paint(){this.plot_view.notify_finished_after_paint()}get needs_clip(){return!1}get has_webgl(){return!1}render(){this.model.visible&&this._render(),this._has_finished=!0}renderer_view(e){}}t.RendererView=p,p.__name__=\"RendererView\";class g extends h.Model{constructor(e){super(e)}}t.Renderer=g,a=g,g.__name__=\"Renderer\",a.define((({Boolean:e,String:i,Ref:t,Nullable:n})=>({group:[n(t(c)),null],level:[d.RenderLevel,\"image\"],visible:[e,!0],x_range_name:[i,\"default\"],y_range_name:[i,\"default\"],coordinates:[n(t(u.CoordinateMapping)),null]})))},\n", - " function _(t,e,s,i,n){i();const o=t(1),h=t(15),r=t(43),l=t(8),_=(0,o.__importDefault)(t(44));class d{constructor(t){this.removed=new h.Signal0(this,\"removed\"),this._ready=Promise.resolve(void 0),this._slots=new WeakMap,this._idle_notified=!1;const{model:e,parent:s}=t;this.model=e,this.parent=s,this.root=null==s?this:s.root,this.removed.emit()}get ready(){return this._ready}connect(t,e){let s=this._slots.get(e);return null==s&&(s=(t,s)=>{const i=Promise.resolve(e.call(this,t,s));this._ready=this._ready.then((()=>i))},this._slots.set(e,s)),t.connect(s,this)}disconnect(t,e){return t.disconnect(e,this)}initialize(){this._has_finished=!1,this.is_root&&(this._stylesheet=r.stylesheet);for(const t of this.styles())this.stylesheet.append(t)}async lazy_initialize(){}remove(){this.disconnect_signals(),this.removed.emit()}toString(){return`${this.model.type}View(${this.model.id})`}serializable_state(){return{type:this.model.type}}get is_root(){return null==this.parent}has_finished(){return this._has_finished}get is_idle(){return this.has_finished()}connect_signals(){}disconnect_signals(){h.Signal.disconnect_receiver(this)}on_change(t,e){for(const s of(0,l.isArray)(t)?t:[t])this.connect(s.change,e)}cursor(t,e){return null}get stylesheet(){return this.is_root?this._stylesheet:this.root.stylesheet}styles(){return[_.default]}notify_finished(){this.is_root?!this._idle_notified&&this.has_finished()&&null!=this.model.document&&(this._idle_notified=!0,this.model.document.notify_idle(this.model)):this.root.notify_finished()}}s.View=d,d.__name__=\"View\"},\n", - " function _(t,e,n,i,o){i();const s=t(8),l=t(13),r=t=>(e={},...n)=>{const i=document.createElement(t);i.classList.add(\"bk\"),(0,s.isPlainObject)(e)||(n=[e,...n],e={});for(let[t,n]of(0,l.entries)(e))if(null!=n&&(!(0,s.isBoolean)(n)||n))if(\"class\"===t&&((0,s.isString)(n)&&(n=n.split(/\\s+/)),(0,s.isArray)(n)))for(const t of n)null!=t&&i.classList.add(t);else if(\"style\"===t&&(0,s.isPlainObject)(n))for(const[t,e]of(0,l.entries)(n))i.style[t]=e;else if(\"data\"===t&&(0,s.isPlainObject)(n))for(const[t,e]of(0,l.entries)(n))i.dataset[t]=e;else i.setAttribute(t,n);function o(t){if((0,s.isString)(t))i.appendChild(document.createTextNode(t));else if(t instanceof Node)i.appendChild(t);else if(t instanceof NodeList||t instanceof HTMLCollection)for(const e of t)i.appendChild(e);else if(null!=t&&!1!==t)throw new Error(`expected a DOM element, string, false or null, got ${JSON.stringify(t)}`)}for(const t of n)if((0,s.isArray)(t))for(const e of t)o(e);else o(t);return i};function a(t){const e=t.parentNode;null!=e&&e.removeChild(t)}function c(t,...e){const n=t.firstChild;for(const i of e)t.insertBefore(i,n)}function d(t,e){var n,i,o;const s=Element.prototype;return(null!==(o=null!==(i=null!==(n=s.matches)&&void 0!==n?n:s.webkitMatchesSelector)&&void 0!==i?i:s.mozMatchesSelector)&&void 0!==o?o:s.msMatchesSelector).call(t,e)}function h(t){return parseFloat(t)||0}function f(t){const e=getComputedStyle(t);return{border:{top:h(e.borderTopWidth),bottom:h(e.borderBottomWidth),left:h(e.borderLeftWidth),right:h(e.borderRightWidth)},margin:{top:h(e.marginTop),bottom:h(e.marginBottom),left:h(e.marginLeft),right:h(e.marginRight)},padding:{top:h(e.paddingTop),bottom:h(e.paddingBottom),left:h(e.paddingLeft),right:h(e.paddingRight)}}}function u(t){const e=t.getBoundingClientRect();return{width:Math.ceil(e.width),height:Math.ceil(e.height)}}n.createElement=function(t,e,...n){return r(t)(e,...n)},n.div=r(\"div\"),n.span=r(\"span\"),n.canvas=r(\"canvas\"),n.link=r(\"link\"),n.style=r(\"style\"),n.a=r(\"a\"),n.p=r(\"p\"),n.i=r(\"i\"),n.pre=r(\"pre\"),n.button=r(\"button\"),n.label=r(\"label\"),n.input=r(\"input\"),n.select=r(\"select\"),n.option=r(\"option\"),n.optgroup=r(\"optgroup\"),n.textarea=r(\"textarea\"),n.createSVGElement=function(t,e,...n){const i=document.createElementNS(\"http://www.w3.org/2000/svg\",t);for(const[t,n]of(0,l.entries)(null!=e?e:{}))null==n||(0,s.isBoolean)(n)&&!n||i.setAttribute(t,n);function o(t){if((0,s.isString)(t))i.appendChild(document.createTextNode(t));else if(t instanceof Node)i.appendChild(t);else if(t instanceof NodeList||t instanceof HTMLCollection)for(const e of t)i.appendChild(e);else if(null!=t&&!1!==t)throw new Error(`expected a DOM element, string, false or null, got ${JSON.stringify(t)}`)}for(const t of n)if((0,s.isArray)(t))for(const e of t)o(e);else o(t);return i},n.nbsp=function(){return document.createTextNode(\"\\xa0\")},n.append=function(t,...e){for(const n of e)t.appendChild(n)},n.remove=a,n.removeElement=a,n.replaceWith=function(t,e){const n=t.parentNode;null!=n&&n.replaceChild(e,t)},n.prepend=c,n.empty=function(t,e=!1){let n;for(;n=t.firstChild;)t.removeChild(n);if(e&&t instanceof Element)for(const e of t.attributes)t.removeAttributeNode(e)},n.display=function(t){t.style.display=\"\"},n.undisplay=function(t){t.style.display=\"none\"},n.show=function(t){t.style.visibility=\"\"},n.hide=function(t){t.style.visibility=\"hidden\"},n.offset=function(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset-document.documentElement.clientTop,left:e.left+window.pageXOffset-document.documentElement.clientLeft}},n.matches=d,n.parent=function(t,e){let n=t;for(;n=n.parentElement;)if(d(n,e))return n;return null},n.extents=f,n.size=u,n.scroll_size=function(t){return{width:Math.ceil(t.scrollWidth),height:Math.ceil(t.scrollHeight)}},n.outer_size=function(t){const{margin:{left:e,right:n,top:i,bottom:o}}=f(t),{width:s,height:l}=u(t);return{width:Math.ceil(s+e+n),height:Math.ceil(l+i+o)}},n.content_size=function(t){const{left:e,top:n}=t.getBoundingClientRect(),{padding:i}=f(t);let o=0,s=0;for(const l of t.children){const t=l.getBoundingClientRect();o=Math.max(o,Math.ceil(t.left-e-i.left+t.width)),s=Math.max(s,Math.ceil(t.top-n-i.top+t.height))}return{width:o,height:s}},n.position=function(t,e,n){const{style:i}=t;if(i.left=`${e.x}px`,i.top=`${e.y}px`,i.width=`${e.width}px`,i.height=`${e.height}px`,null==n)i.margin=\"\";else{const{top:t,right:e,bottom:o,left:s}=n;i.margin=`${t}px ${e}px ${o}px ${s}px`}},n.children=function(t){return Array.from(t.children)};class p{constructor(t){this.el=t,this.classList=t.classList}get values(){const t=[];for(let e=0;e{document.addEventListener(\"DOMContentLoaded\",(()=>t()),{once:!0})}))}},\n", - " function _(o,i,t,e,r){e(),t.root=\"bk-root\",t.default=\".bk-root{position:relative;width:auto;height:auto;box-sizing:border-box;font-family:Helvetica, Arial, sans-serif;font-size:13px;}.bk-root .bk,.bk-root .bk:before,.bk-root .bk:after{box-sizing:inherit;margin:0;border:0;padding:0;background-image:none;font-family:inherit;font-size:100%;line-height:1.42857143;}.bk-root pre.bk{font-family:Courier, monospace;}\"},\n", - " function _(e,t,r,a,c){a();const n=e(1),l=e(46);c(\"Line\",l.Line),c(\"LineScalar\",l.LineScalar),c(\"LineVector\",l.LineVector);const i=e(49);c(\"Fill\",i.Fill),c(\"FillScalar\",i.FillScalar),c(\"FillVector\",i.FillVector);const s=e(50);c(\"Text\",s.Text),c(\"TextScalar\",s.TextScalar),c(\"TextVector\",s.TextVector);const o=e(51);c(\"Hatch\",o.Hatch),c(\"HatchScalar\",o.HatchScalar),c(\"HatchVector\",o.HatchVector);const u=(0,n.__importStar)(e(48)),V=e(47);c(\"VisualProperties\",V.VisualProperties),c(\"VisualUniforms\",V.VisualUniforms);class h{constructor(e){this._visuals=[];for(const[t,r]of e.model._mixins){const a=(()=>{switch(r){case u.Line:return new l.Line(e,t);case u.LineScalar:return new l.LineScalar(e,t);case u.LineVector:return new l.LineVector(e,t);case u.Fill:return new i.Fill(e,t);case u.FillScalar:return new i.FillScalar(e,t);case u.FillVector:return new i.FillVector(e,t);case u.Text:return new s.Text(e,t);case u.TextScalar:return new s.TextScalar(e,t);case u.TextVector:return new s.TextVector(e,t);case u.Hatch:return new o.Hatch(e,t);case u.HatchScalar:return new o.HatchScalar(e,t);case u.HatchVector:return new o.HatchVector(e,t);default:throw new Error(\"unknown visual\")}})();a instanceof V.VisualProperties&&a.update(),this._visuals.push(a),Object.defineProperty(this,t+a.type,{get:()=>a,configurable:!1,enumerable:!0})}}*[Symbol.iterator](){yield*this._visuals}}r.Visuals=h,h.__name__=\"Visuals\"},\n", - " function _(e,t,i,l,s){l();const a=e(1),n=e(47),h=(0,a.__importStar)(e(48)),o=e(22),_=e(8);function r(e){if((0,_.isArray)(e))return e;switch(e){case\"solid\":return[];case\"dashed\":return[6];case\"dotted\":return[2,4];case\"dotdash\":return[2,4,6,4];case\"dashdot\":return[6,4,2,4];default:return e.split(\" \").map(Number).filter(_.isInteger)}}i.resolve_line_dash=r;class u extends n.VisualProperties{get doit(){const e=this.line_color.get_value(),t=this.line_alpha.get_value(),i=this.line_width.get_value();return!(null==e||0==t||0==i)}apply(e){const{doit:t}=this;return t&&(this.set_value(e),e.stroke()),t}values(){return{color:this.line_color.get_value(),alpha:this.line_alpha.get_value(),width:this.line_width.get_value(),join:this.line_join.get_value(),cap:this.line_cap.get_value(),dash:this.line_dash.get_value(),offset:this.line_dash_offset.get_value()}}set_value(e){const t=this.line_color.get_value(),i=this.line_alpha.get_value();e.strokeStyle=(0,o.color2css)(t,i),e.lineWidth=this.line_width.get_value(),e.lineJoin=this.line_join.get_value(),e.lineCap=this.line_cap.get_value(),e.lineDash=r(this.line_dash.get_value()),e.lineDashOffset=this.line_dash_offset.get_value()}}i.Line=u,u.__name__=\"Line\";class c extends n.VisualUniforms{get doit(){const e=this.line_color.value,t=this.line_alpha.value,i=this.line_width.value;return!(0==e||0==t||0==i)}apply(e){const{doit:t}=this;return t&&(this.set_value(e),e.stroke()),t}values(){return{color:this.line_color.value,alpha:this.line_alpha.value,width:this.line_width.value,join:this.line_join.value,cap:this.line_cap.value,dash:this.line_dash.value,offset:this.line_dash_offset.value}}set_value(e){const t=this.line_color.value,i=this.line_alpha.value;e.strokeStyle=(0,o.color2css)(t,i),e.lineWidth=this.line_width.value,e.lineJoin=this.line_join.value,e.lineCap=this.line_cap.value,e.lineDash=r(this.line_dash.value),e.lineDashOffset=this.line_dash_offset.value}}i.LineScalar=c,c.__name__=\"LineScalar\";class d extends n.VisualUniforms{get doit(){const{line_color:e}=this;if(e.is_Scalar()&&0==e.value)return!1;const{line_alpha:t}=this;if(t.is_Scalar()&&0==t.value)return!1;const{line_width:i}=this;return!i.is_Scalar()||0!=i.value}apply(e,t){const{doit:i}=this;return i&&(this.set_vectorize(e,t),e.stroke()),i}values(e){return{color:this.line_color.get(e),alpha:this.line_alpha.get(e),width:this.line_width.get(e),join:this.line_join.get(e),cap:this.line_cap.get(e),dash:this.line_dash.get(e),offset:this.line_dash_offset.get(e)}}set_vectorize(e,t){const i=this.line_color.get(t),l=this.line_alpha.get(t),s=this.line_width.get(t),a=this.line_join.get(t),n=this.line_cap.get(t),h=this.line_dash.get(t),_=this.line_dash_offset.get(t);e.strokeStyle=(0,o.color2css)(i,l),e.lineWidth=s,e.lineJoin=a,e.lineCap=n,e.lineDash=r(h),e.lineDashOffset=_}}i.LineVector=d,d.__name__=\"LineVector\",u.prototype.type=\"line\",u.prototype.attrs=Object.keys(h.Line),c.prototype.type=\"line\",c.prototype.attrs=Object.keys(h.LineScalar),d.prototype.type=\"line\",d.prototype.attrs=Object.keys(h.LineVector)},\n", - " function _(t,s,o,i,r){i();class e{constructor(t,s=\"\"){this.obj=t,this.prefix=s;const o=this;this._props=[];for(const i of this.attrs){const r=t.model.properties[s+i];r.change.connect((()=>this.update())),o[i]=r,this._props.push(r)}}*[Symbol.iterator](){yield*this._props}update(){}}o.VisualProperties=e,e.__name__=\"VisualProperties\";class p{constructor(t,s=\"\"){this.obj=t,this.prefix=s;for(const o of this.attrs)Object.defineProperty(this,o,{get:()=>t[s+o]})}*[Symbol.iterator](){for(const t of this.attrs)yield this.obj.model.properties[this.prefix+t]}update(){}}o.VisualUniforms=p,p.__name__=\"VisualUniforms\"},\n", - " function _(e,l,t,a,c){a();const r=e(1),o=(0,r.__importStar)(e(18)),n=e(20),i=(0,r.__importStar)(e(21)),_=e(13);t.Line={line_color:[i.Nullable(i.Color),\"black\"],line_alpha:[i.Alpha,1],line_width:[i.Number,1],line_join:[n.LineJoin,\"bevel\"],line_cap:[n.LineCap,\"butt\"],line_dash:[i.Or(n.LineDash,i.Array(i.Number)),[]],line_dash_offset:[i.Number,0]},t.Fill={fill_color:[i.Nullable(i.Color),\"gray\"],fill_alpha:[i.Alpha,1]},t.Hatch={hatch_color:[i.Nullable(i.Color),\"black\"],hatch_alpha:[i.Alpha,1],hatch_scale:[i.Number,12],hatch_pattern:[i.Nullable(i.Or(n.HatchPatternType,i.String)),null],hatch_weight:[i.Number,1],hatch_extra:[i.Dict(i.AnyRef()),{}]},t.Text={text_color:[i.Nullable(i.Color),\"#444444\"],text_alpha:[i.Alpha,1],text_font:[o.Font,\"helvetica\"],text_font_size:[i.FontSize,\"16px\"],text_font_style:[n.FontStyle,\"normal\"],text_align:[n.TextAlign,\"left\"],text_baseline:[n.TextBaseline,\"bottom\"],text_line_height:[i.Number,1.2]},t.LineScalar={line_color:[o.ColorScalar,\"black\"],line_alpha:[o.NumberScalar,1],line_width:[o.NumberScalar,1],line_join:[o.LineJoinScalar,\"bevel\"],line_cap:[o.LineCapScalar,\"butt\"],line_dash:[o.LineDashScalar,[]],line_dash_offset:[o.NumberScalar,0]},t.FillScalar={fill_color:[o.ColorScalar,\"gray\"],fill_alpha:[o.NumberScalar,1]},t.HatchScalar={hatch_color:[o.ColorScalar,\"black\"],hatch_alpha:[o.NumberScalar,1],hatch_scale:[o.NumberScalar,12],hatch_pattern:[o.NullStringScalar,null],hatch_weight:[o.NumberScalar,1],hatch_extra:[o.AnyScalar,{}]},t.TextScalar={text_color:[o.ColorScalar,\"#444444\"],text_alpha:[o.NumberScalar,1],text_font:[o.FontScalar,\"helvetica\"],text_font_size:[o.FontSizeScalar,\"16px\"],text_font_style:[o.FontStyleScalar,\"normal\"],text_align:[o.TextAlignScalar,\"left\"],text_baseline:[o.TextBaselineScalar,\"bottom\"],text_line_height:[o.NumberScalar,1.2]},t.LineVector={line_color:[o.ColorSpec,\"black\"],line_alpha:[o.NumberSpec,1],line_width:[o.NumberSpec,1],line_join:[o.LineJoinSpec,\"bevel\"],line_cap:[o.LineCapSpec,\"butt\"],line_dash:[o.LineDashSpec,[]],line_dash_offset:[o.NumberSpec,0]},t.FillVector={fill_color:[o.ColorSpec,\"gray\"],fill_alpha:[o.NumberSpec,1]},t.HatchVector={hatch_color:[o.ColorSpec,\"black\"],hatch_alpha:[o.NumberSpec,1],hatch_scale:[o.NumberSpec,12],hatch_pattern:[o.NullStringSpec,null],hatch_weight:[o.NumberSpec,1],hatch_extra:[o.AnyScalar,{}]},t.TextVector={text_color:[o.ColorSpec,\"#444444\"],text_alpha:[o.NumberSpec,1],text_font:[o.FontSpec,\"helvetica\"],text_font_size:[o.FontSizeSpec,\"16px\"],text_font_style:[o.FontStyleSpec,\"normal\"],text_align:[o.TextAlignSpec,\"left\"],text_baseline:[o.TextBaselineSpec,\"bottom\"],text_line_height:[o.NumberSpec,1.2]},t.attrs_of=function(e,l,t,a=!1){const c={};for(const r of(0,_.keys)(t)){const t=`${l}${r}`,o=e[t];c[a?t:r]=o}return c}},\n", - " function _(l,t,e,i,s){i();const a=l(1),o=l(47),r=(0,a.__importStar)(l(48)),_=l(22);class c extends o.VisualProperties{get doit(){const l=this.fill_color.get_value(),t=this.fill_alpha.get_value();return!(null==l||0==t)}apply(l,t){const{doit:e}=this;return e&&(this.set_value(l),l.fill(t)),e}values(){return{color:this.fill_color.get_value(),alpha:this.fill_alpha.get_value()}}set_value(l){const t=this.fill_color.get_value(),e=this.fill_alpha.get_value();l.fillStyle=(0,_.color2css)(t,e)}}e.Fill=c,c.__name__=\"Fill\";class h extends o.VisualUniforms{get doit(){const l=this.fill_color.value,t=this.fill_alpha.value;return!(0==l||0==t)}apply(l,t){const{doit:e}=this;return e&&(this.set_value(l),l.fill(t)),e}values(){return{color:this.fill_color.value,alpha:this.fill_alpha.value}}set_value(l){const t=this.fill_color.value,e=this.fill_alpha.value;l.fillStyle=(0,_.color2css)(t,e)}}e.FillScalar=h,h.__name__=\"FillScalar\";class u extends o.VisualUniforms{get doit(){const{fill_color:l}=this;if(l.is_Scalar()&&0==l.value)return!1;const{fill_alpha:t}=this;return!t.is_Scalar()||0!=t.value}apply(l,t,e){const{doit:i}=this;return i&&(this.set_vectorize(l,t),l.fill(e)),i}values(l){return{color:this.fill_color.get(l),alpha:this.fill_alpha.get(l)}}set_vectorize(l,t){const e=this.fill_color.get(t),i=this.fill_alpha.get(t);l.fillStyle=(0,_.color2css)(e,i)}}e.FillVector=u,u.__name__=\"FillVector\",c.prototype.type=\"fill\",c.prototype.attrs=Object.keys(r.Fill),h.prototype.type=\"fill\",h.prototype.attrs=Object.keys(r.FillScalar),u.prototype.type=\"fill\",u.prototype.attrs=Object.keys(r.FillVector)},\n", - " function _(t,e,l,s,_){s();const i=t(1),a=t(47),o=(0,i.__importStar)(t(48)),n=t(22);class h extends a.VisualProperties{get doit(){const t=this.text_color.get_value(),e=this.text_alpha.get_value();return!(null==t||0==e)}values(){return{color:this.text_color.get_value(),alpha:this.text_alpha.get_value(),font:this.text_font.get_value(),font_size:this.text_font_size.get_value(),font_style:this.text_font_style.get_value(),align:this.text_align.get_value(),baseline:this.text_baseline.get_value(),line_height:this.text_line_height.get_value()}}set_value(t){const e=this.text_color.get_value(),l=this.text_alpha.get_value();t.fillStyle=(0,n.color2css)(e,l),t.font=this.font_value(),t.textAlign=this.text_align.get_value(),t.textBaseline=this.text_baseline.get_value()}font_value(){return`${this.text_font_style.get_value()} ${this.text_font_size.get_value()} ${this.text_font.get_value()}`}}l.Text=h,h.__name__=\"Text\";class x extends a.VisualUniforms{get doit(){const t=this.text_color.value,e=this.text_alpha.value;return!(0==t||0==e)}values(){return{color:this.text_color.value,alpha:this.text_alpha.value,font:this.text_font.value,font_size:this.text_font_size.value,font_style:this.text_font_style.value,align:this.text_align.value,baseline:this.text_baseline.value,line_height:this.text_line_height.value}}set_value(t){const e=this.text_color.value,l=this.text_alpha.value,s=this.font_value(),_=this.text_align.value,i=this.text_baseline.value;t.fillStyle=(0,n.color2css)(e,l),t.font=s,t.textAlign=_,t.textBaseline=i}font_value(){return`${this.text_font_style.value} ${this.text_font_size.value} ${this.text_font.value}`}}l.TextScalar=x,x.__name__=\"TextScalar\";class u extends a.VisualUniforms{values(t){return{color:this.text_color.get(t),alpha:this.text_alpha.get(t),font:this.text_font.get(t),font_size:this.text_font_size.get(t),font_style:this.text_font_style.get(t),align:this.text_align.get(t),baseline:this.text_baseline.get(t),line_height:this.text_line_height.get(t)}}get doit(){const{text_color:t}=this;if(t.is_Scalar()&&0==t.value)return!1;const{text_alpha:e}=this;return!e.is_Scalar()||0!=e.value}set_vectorize(t,e){const l=this.text_color.get(e),s=this.text_alpha.get(e),_=this.font_value(e),i=this.text_align.get(e),a=this.text_baseline.get(e);t.fillStyle=(0,n.color2css)(l,s),t.font=_,t.textAlign=i,t.textBaseline=a}font_value(t){return`${this.text_font_style.get(t)} ${this.text_font_size.get(t)} ${this.text_font.get(t)}`}}l.TextVector=u,u.__name__=\"TextVector\",h.prototype.type=\"text\",h.prototype.attrs=Object.keys(o.Text),x.prototype.type=\"text\",x.prototype.attrs=Object.keys(o.TextScalar),u.prototype.type=\"text\",u.prototype.attrs=Object.keys(o.TextVector)},\n", - " function _(t,e,a,r,i){r();const h=t(1),s=t(47),n=t(52),c=(0,h.__importStar)(t(18)),_=(0,h.__importStar)(t(48));class l extends s.VisualProperties{constructor(){super(...arguments),this._update_iteration=0}update(){if(this._update_iteration++,this._hatch_image=null,!this.doit)return;const t=this.hatch_color.get_value(),e=this.hatch_alpha.get_value(),a=this.hatch_scale.get_value(),r=this.hatch_pattern.get_value(),i=this.hatch_weight.get_value(),h=t=>{this._hatch_image=t},s=this.hatch_extra.get_value()[r];if(null!=s){const r=s.get_pattern(t,e,a,i);if(r instanceof Promise){const{_update_iteration:t}=this;r.then((e=>{this._update_iteration==t&&(h(e),this.obj.request_render())}))}else h(r)}else{const s=this.obj.canvas.create_layer(),c=(0,n.get_pattern)(s,r,t,e,a,i);h(c)}}get doit(){const t=this.hatch_color.get_value(),e=this.hatch_alpha.get_value(),a=this.hatch_pattern.get_value();return!(null==t||0==e||\" \"==a||\"blank\"==a||null==a)}apply(t,e){const{doit:a}=this;return a&&(this.set_value(t),t.layer.undo_transform((()=>t.fill(e)))),a}set_value(t){const e=this.pattern(t);t.fillStyle=null!=e?e:\"transparent\"}pattern(t){const e=this._hatch_image;return null==e?null:t.createPattern(e,this.repetition())}repetition(){const t=this.hatch_pattern.get_value(),e=this.hatch_extra.get_value()[t];if(null==e)return\"repeat\";switch(e.repetition){case\"repeat\":return\"repeat\";case\"repeat_x\":return\"repeat-x\";case\"repeat_y\":return\"repeat-y\";case\"no_repeat\":return\"no-repeat\"}}}a.Hatch=l,l.__name__=\"Hatch\";class o extends s.VisualUniforms{constructor(){super(...arguments),this._static_doit=!1,this._update_iteration=0}_compute_static_doit(){const t=this.hatch_color.value,e=this.hatch_alpha.value,a=this.hatch_pattern.value;return!(null==t||0==e||\" \"==a||\"blank\"==a||null==a)}update(){this._update_iteration++;const t=this.hatch_color.length;if(this._hatch_image=new c.UniformScalar(null,t),this._static_doit=this._compute_static_doit(),!this._static_doit)return;const e=this.hatch_color.value,a=this.hatch_alpha.value,r=this.hatch_scale.value,i=this.hatch_pattern.value,h=this.hatch_weight.value,s=e=>{this._hatch_image=new c.UniformScalar(e,t)},_=this.hatch_extra.value[i];if(null!=_){const t=_.get_pattern(e,a,r,h);if(t instanceof Promise){const{_update_iteration:e}=this;t.then((t=>{this._update_iteration==e&&(s(t),this.obj.request_render())}))}else s(t)}else{const t=this.obj.canvas.create_layer(),c=(0,n.get_pattern)(t,i,e,a,r,h);s(c)}}get doit(){return this._static_doit}apply(t,e){const{doit:a}=this;return a&&(this.set_value(t),t.layer.undo_transform((()=>t.fill(e)))),a}set_value(t){var e;t.fillStyle=null!==(e=this.pattern(t))&&void 0!==e?e:\"transparent\"}pattern(t){const e=this._hatch_image.value;return null==e?null:t.createPattern(e,this.repetition())}repetition(){const t=this.hatch_pattern.value,e=this.hatch_extra.value[t];if(null==e)return\"repeat\";switch(e.repetition){case\"repeat\":return\"repeat\";case\"repeat_x\":return\"repeat-x\";case\"repeat_y\":return\"repeat-y\";case\"no_repeat\":return\"no-repeat\"}}}a.HatchScalar=o,o.__name__=\"HatchScalar\";class u extends s.VisualUniforms{constructor(){super(...arguments),this._static_doit=!1,this._update_iteration=0}_compute_static_doit(){const{hatch_color:t}=this;if(t.is_Scalar()&&0==t.value)return!1;const{hatch_alpha:e}=this;if(e.is_Scalar()&&0==e.value)return!1;const{hatch_pattern:a}=this;if(a.is_Scalar()){const t=a.value;if(\" \"==t||\"blank\"==t||null==t)return!1}return!0}update(){this._update_iteration++;const t=this.hatch_color.length;if(this._hatch_image=new c.UniformScalar(null,t),this._static_doit=this._compute_static_doit(),!this._static_doit)return;const e=(t,e,a,r,i,h)=>{const s=this.hatch_extra.value[t];if(null!=s){const t=s.get_pattern(e,a,r,i);if(t instanceof Promise){const{_update_iteration:e}=this;t.then((t=>{this._update_iteration==e&&(h(t),this.obj.request_render())}))}else h(t)}else{const s=this.obj.canvas.create_layer(),c=(0,n.get_pattern)(s,t,e,a,r,i);h(c)}};if(this.hatch_color.is_Scalar()&&this.hatch_alpha.is_Scalar()&&this.hatch_scale.is_Scalar()&&this.hatch_pattern.is_Scalar()&&this.hatch_weight.is_Scalar()){const a=this.hatch_color.value,r=this.hatch_alpha.value,i=this.hatch_scale.value;e(this.hatch_pattern.value,a,r,i,this.hatch_weight.value,(e=>{this._hatch_image=new c.UniformScalar(e,t)}))}else{const a=new Array(t);a.fill(null),this._hatch_image=new c.UniformVector(a);for(let r=0;r{a[r]=t}))}}}get doit(){return this._static_doit}apply(t,e,a){const{doit:r}=this;return r&&(this.set_vectorize(t,e),t.layer.undo_transform((()=>t.fill(a)))),r}set_vectorize(t,e){var a;t.fillStyle=null!==(a=this.pattern(t,e))&&void 0!==a?a:\"transparent\"}pattern(t,e){const a=this._hatch_image.get(e);return null==a?null:t.createPattern(a,this.repetition(e))}repetition(t){const e=this.hatch_pattern.get(t),a=this.hatch_extra.value[e];if(null==a)return\"repeat\";switch(a.repetition){case\"repeat\":return\"repeat\";case\"repeat_x\":return\"repeat-x\";case\"repeat_y\":return\"repeat-y\";case\"no_repeat\":return\"no-repeat\"}}}a.HatchVector=u,u.__name__=\"HatchVector\",l.prototype.type=\"hatch\",l.prototype.attrs=Object.keys(_.Hatch),o.prototype.type=\"hatch\",o.prototype.attrs=Object.keys(_.HatchScalar),u.prototype.type=\"hatch\",u.prototype.attrs=Object.keys(_.HatchVector)},\n", - " function _(e,o,a,s,r){s();const i=e(22);function l(e,o,a){e.moveTo(0,a+.5),e.lineTo(o,a+.5),e.stroke()}function n(e,o,a){e.moveTo(a+.5,0),e.lineTo(a+.5,o),e.stroke()}function t(e,o){e.moveTo(0,o),e.lineTo(o,0),e.stroke(),e.moveTo(0,0),e.lineTo(o,o),e.stroke()}a.hatch_aliases={\" \":\"blank\",\".\":\"dot\",o:\"ring\",\"-\":\"horizontal_line\",\"|\":\"vertical_line\",\"+\":\"cross\",'\"':\"horizontal_dash\",\":\":\"vertical_dash\",\"@\":\"spiral\",\"/\":\"right_diagonal_line\",\"\\\\\":\"left_diagonal_line\",x:\"diagonal_cross\",\",\":\"right_diagonal_dash\",\"`\":\"left_diagonal_dash\",v:\"horizontal_wave\",\">\":\"vertical_wave\",\"*\":\"criss_cross\"},a.get_pattern=function(e,o,s,r,c,k){return e.resize(c,c),e.prepare(),function(e,o,s,r,c,k){var _;const T=c,v=T/2,h=v/2,d=(0,i.color2css)(s,r);switch(e.strokeStyle=d,e.fillStyle=d,e.lineCap=\"square\",e.lineWidth=k,null!==(_=a.hatch_aliases[o])&&void 0!==_?_:o){case\"blank\":break;case\"dot\":e.arc(v,v,v/2,0,2*Math.PI,!0),e.fill();break;case\"ring\":e.arc(v,v,v/2,0,2*Math.PI,!0),e.stroke();break;case\"horizontal_line\":l(e,T,v);break;case\"vertical_line\":n(e,T,v);break;case\"cross\":l(e,T,v),n(e,T,v);break;case\"horizontal_dash\":l(e,v,v);break;case\"vertical_dash\":n(e,v,v);break;case\"spiral\":{const o=T/30;e.moveTo(v,v);for(let a=0;a<360;a++){const s=.1*a,r=v+o*s*Math.cos(s),i=v+o*s*Math.sin(s);e.lineTo(r,i)}e.stroke();break}case\"right_diagonal_line\":e.moveTo(.5-h,T),e.lineTo(h+.5,0),e.stroke(),e.moveTo(h+.5,T),e.lineTo(3*h+.5,0),e.stroke(),e.moveTo(3*h+.5,T),e.lineTo(5*h+.5,0),e.stroke(),e.stroke();break;case\"left_diagonal_line\":e.moveTo(h+.5,T),e.lineTo(.5-h,0),e.stroke(),e.moveTo(3*h+.5,T),e.lineTo(h+.5,0),e.stroke(),e.moveTo(5*h+.5,T),e.lineTo(3*h+.5,0),e.stroke(),e.stroke();break;case\"diagonal_cross\":t(e,T);break;case\"right_diagonal_dash\":e.moveTo(h+.5,3*h+.5),e.lineTo(3*h+.5,h+.5),e.stroke();break;case\"left_diagonal_dash\":e.moveTo(h+.5,h+.5),e.lineTo(3*h+.5,3*h+.5),e.stroke();break;case\"horizontal_wave\":e.moveTo(0,h),e.lineTo(v,3*h),e.lineTo(T,h),e.stroke();break;case\"vertical_wave\":e.moveTo(h,0),e.lineTo(3*h,v),e.lineTo(h,T),e.stroke();break;case\"criss_cross\":t(e,T),l(e,T,v),n(e,T,v)}}(e.ctx,o,s,r,c,k),e.canvas}},\n", - " function _(e,t,s,n,c){var a;n();const i=e(14),r=e(8),l=e(13),o=e(26),_=e(19);class h extends i.HasProps{constructor(e){super(e)}get is_syncable(){return this.syncable}[o.equals](e,t){return t.eq(this.id,e.id)&&super[o.equals](e,t)}initialize(){super.initialize(),this._js_callbacks=new Map}connect_signals(){super.connect_signals(),this._update_property_callbacks(),this.connect(this.properties.js_property_callbacks.change,(()=>this._update_property_callbacks())),this.connect(this.properties.js_event_callbacks.change,(()=>this._update_event_callbacks())),this.connect(this.properties.subscribed_events.change,(()=>this._update_event_callbacks()))}_process_event(e){var t;for(const s of null!==(t=this.js_event_callbacks[e.event_name])&&void 0!==t?t:[])s.execute(e);null!=this.document&&this.subscribed_events.some((t=>t==e.event_name))&&this.document.event_manager.send_event(e)}trigger_event(e){null!=this.document&&(e.origin=this,this.document.event_manager.trigger(e))}_update_event_callbacks(){null!=this.document?this.document.event_manager.subscribed_models.add(this):_.logger.warn(\"WARNING: Document not defined for updating event callbacks\")}_update_property_callbacks(){const e=e=>{const[t,s=null]=e.split(\":\");return null!=s?this.properties[s][t]:this[t]};for(const[t,s]of this._js_callbacks){const n=e(t);for(const e of s)this.disconnect(n,e)}this._js_callbacks.clear();for(const[t,s]of(0,l.entries)(this.js_property_callbacks)){const n=s.map((e=>()=>e.execute(this)));this._js_callbacks.set(t,n);const c=e(t);for(const e of n)this.connect(c,e)}}_doc_attached(){(0,l.isEmpty)(this.js_event_callbacks)&&0==this.subscribed_events.length||this._update_event_callbacks()}_doc_detached(){this.document.event_manager.subscribed_models.delete(this)}select(e){if((0,r.isString)(e))return[...this.references()].filter((t=>t instanceof h&&t.name===e));if(e.prototype instanceof i.HasProps)return[...this.references()].filter((t=>t instanceof e));throw new Error(\"invalid selector\")}select_one(e){const t=this.select(e);switch(t.length){case 0:return null;case 1:return t[0];default:throw new Error(\"found more than one object matching given selector\")}}}s.Model=h,a=h,h.__name__=\"Model\",a.define((({Any:e,Unknown:t,Boolean:s,String:n,Array:c,Dict:a,Nullable:i})=>({tags:[c(t),[]],name:[i(n),null],js_property_callbacks:[a(c(e)),{}],js_event_callbacks:[a(c(e)),{}],subscribed_events:[c(n),[]],syncable:[s,!0]})))},\n", - " function _(e,t,s,a,r){var c,n;a();const _=e(12),o=e(53),i=e(55),l=e(59),u=e(61),g=e(62),h=e(57),p=e(63),m=e(67);class x{constructor(e,t){this.x_scale=e,this.y_scale=t,this.x_source=this.x_scale.source_range,this.y_source=this.y_scale.source_range,this.ranges=[this.x_source,this.y_source],this.scales=[this.x_scale,this.y_scale]}map_to_screen(e,t){return[this.x_scale.v_compute(e),this.y_scale.v_compute(t)]}map_from_screen(e,t){return[this.x_scale.v_invert(e),this.y_scale.v_invert(t)]}}s.CoordinateTransform=x,x.__name__=\"CoordinateTransform\";class y extends o.Model{constructor(e){super(e)}get x_ranges(){return new Map([[\"default\",this.x_source]])}get y_ranges(){return new Map([[\"default\",this.y_source]])}_get_scale(e,t,s){if(e instanceof m.FactorRange!=t instanceof g.CategoricalScale)throw new Error(`Range ${e.type} is incompatible is Scale ${t.type}`);t instanceof u.LogScale&&e instanceof p.DataRange1d&&(e.scale_hint=\"log\");const a=t.clone();return a.setv({source_range:e,target_range:s}),a}get_transform(e){const{x_source:t,x_scale:s,x_target:a}=this,r=this._get_scale(t,s,a),{y_source:c,y_scale:n,y_target:_}=this,o=this._get_scale(c,n,_),i=new v({source_scale:r,source_range:r.source_range,target_scale:e.x_scale,target_range:e.x_target}),l=new v({source_scale:o,source_range:o.source_range,target_scale:e.y_scale,target_range:e.y_target});return new x(i,l)}}s.CoordinateMapping=y,c=y,y.__name__=\"CoordinateMapping\",c.define((({Ref:e})=>({x_source:[e(h.Range),()=>new p.DataRange1d],y_source:[e(h.Range),()=>new p.DataRange1d],x_scale:[e(i.Scale),()=>new l.LinearScale],y_scale:[e(i.Scale),()=>new l.LinearScale],x_target:[e(h.Range)],y_target:[e(h.Range)]})));class v extends i.Scale{constructor(e){super(e)}get s_compute(){const e=this.source_scale.s_compute,t=this.target_scale.s_compute;return s=>t(e(s))}get s_invert(){const e=this.source_scale.s_invert,t=this.target_scale.s_invert;return s=>e(t(s))}compute(e){return this.s_compute(e)}v_compute(e){const{s_compute:t}=this;return(0,_.map)(e,t)}invert(e){return this.s_invert(e)}v_invert(e){const{s_invert:t}=this;return(0,_.map)(e,t)}}s.CompositeScale=v,n=v,v.__name__=\"CompositeScale\",n.internal((({Ref:e})=>({source_scale:[e(i.Scale)],target_scale:[e(i.Scale)]})))},\n", - " function _(e,t,r,n,s){var _;n();const a=e(56),c=e(57),o=e(58),i=e(24);class u extends a.Transform{constructor(e){super(e)}compute(e){return this.s_compute(e)}v_compute(e){const t=new i.ScreenArray(e.length),{s_compute:r}=this;for(let n=0;n({source_range:[e(c.Range)],target_range:[e(o.Range1d)]})))},\n", - " function _(n,s,o,r,c){r();const e=n(53);class t extends e.Model{constructor(n){super(n)}}o.Transform=t,t.__name__=\"Transform\"},\n", - " function _(e,t,n,i,s){var r;i();const a=e(53);class l extends a.Model{constructor(e){super(e),this.have_updated_interactively=!1}get is_reversed(){return this.start>this.end}get is_valid(){return isFinite(this.min)&&isFinite(this.max)}get span(){return Math.abs(this.end-this.start)}}n.Range=l,r=l,l.__name__=\"Range\",r.define((({Number:e,Tuple:t,Or:n,Auto:i,Nullable:s})=>({bounds:[s(n(t(s(e),s(e)),i)),null],min_interval:[s(e),null],max_interval:[s(e),null]}))),r.internal((({Array:e,AnyRef:t})=>({plots:[e(t()),[]]})))},\n", - " function _(t,e,s,n,r){var a;n();const i=t(57);class _ extends i.Range{constructor(t){super(t)}_set_auto_bounds(){if(\"auto\"==this.bounds){const t=Math.min(this._reset_start,this._reset_end),e=Math.max(this._reset_start,this._reset_end);this.setv({bounds:[t,e]},{silent:!0})}}initialize(){super.initialize(),this._set_auto_bounds()}get min(){return Math.min(this.start,this.end)}get max(){return Math.max(this.start,this.end)}reset(){this._set_auto_bounds();const{_reset_start:t,_reset_end:e}=this;this.start!=t||this.end!=e?this.setv({start:t,end:e}):this.change.emit()}map(t){return new _({start:t(this.start),end:t(this.end)})}widen(t){let{start:e,end:s}=this;return this.is_reversed?(e+=t,s-=t):(e-=t,s+=t),new _({start:e,end:s})}}s.Range1d=_,a=_,_.__name__=\"Range1d\",a.define((({Number:t,Nullable:e})=>({start:[t,0],end:[t,1],reset_start:[e(t),null,{on_update(t,e){e._reset_start=null!=t?t:e.start}}],reset_end:[e(t),null,{on_update(t,e){e._reset_end=null!=t?t:e.end}}]})))},\n", - " function _(t,e,n,r,s){r();const a=t(60);class _ extends a.ContinuousScale{constructor(t){super(t)}get s_compute(){const[t,e]=this._linear_compute_state();return n=>t*n+e}get s_invert(){const[t,e]=this._linear_compute_state();return n=>(n-e)/t}_linear_compute_state(){const t=this.source_range.start,e=this.source_range.end,n=this.target_range.start,r=(this.target_range.end-n)/(e-t);return[r,-r*t+n]}}n.LinearScale=_,_.__name__=\"LinearScale\"},\n", - " function _(n,c,o,s,e){s();const t=n(55);class u extends t.Scale{constructor(n){super(n)}}o.ContinuousScale=u,u.__name__=\"ContinuousScale\"},\n", - " function _(t,e,a,o,s){o();const r=t(60);class n extends r.ContinuousScale{constructor(t){super(t)}get s_compute(){const[t,e,a,o]=this._compute_state();return s=>{if(0==a)return 0;{const r=(Math.log(s)-o)/a;return isFinite(r)?r*t+e:NaN}}}get s_invert(){const[t,e,a,o]=this._compute_state();return s=>{const r=(s-e)/t;return Math.exp(a*r+o)}}_get_safe_factor(t,e){let a=t<0?0:t,o=e<0?0:e;if(a==o)if(0==a)[a,o]=[1,10];else{const t=Math.log(a)/Math.log(10);a=10**Math.floor(t),o=Math.ceil(t)!=Math.floor(t)?10**Math.ceil(t):10**(Math.ceil(t)+1)}return[a,o]}_compute_state(){const t=this.source_range.start,e=this.source_range.end,a=this.target_range.start,o=this.target_range.end-a,[s,r]=this._get_safe_factor(t,e);let n,c;0==s?(n=Math.log(r),c=0):(n=Math.log(r)-Math.log(s),c=Math.log(s));return[o,a,n,c]}}a.LogScale=n,n.__name__=\"LogScale\"},\n", - " function _(t,e,c,a,s){a();const n=t(55),r=t(59),{_linear_compute_state:o}=r.LinearScale.prototype;class l extends n.Scale{constructor(t){super(t)}get s_compute(){const[t,e]=o.call(this),c=this.source_range;return a=>t*c.synthetic(a)+e}get s_invert(){const[t,e]=o.call(this);return c=>(c-e)/t}}c.CategoricalScale=l,l.__name__=\"CategoricalScale\"},\n", - " function _(t,i,n,e,a){e();const s=t(1);var l;const _=t(64),o=t(20),r=t(9),h=t(19),d=(0,s.__importStar)(t(65)),u=t(66);class g extends _.DataRange{constructor(t){super(t),this.have_updated_interactively=!1}initialize(){super.initialize(),this._initial_start=this.start,this._initial_end=this.end,this._initial_range_padding=this.range_padding,this._initial_range_padding_units=this.range_padding_units,this._initial_follow=this.follow,this._initial_follow_interval=this.follow_interval,this._initial_default_span=this.default_span,this._plot_bounds=new Map}get min(){return Math.min(this.start,this.end)}get max(){return Math.max(this.start,this.end)}computed_renderers(){const{renderers:t,names:i}=this,n=(0,r.concat)(this.plots.map((t=>t.data_renderers)));return(0,u.compute_renderers)(0==t.length?\"auto\":t,n,i)}_compute_plot_bounds(t,i){let n=d.empty();for(const e of t){const t=i.get(e);null==t||!e.visible&&this.only_visible||(n=d.union(n,t))}return n}adjust_bounds_for_aspect(t,i){const n=d.empty();let e=t.x1-t.x0;e<=0&&(e=1);let a=t.y1-t.y0;a<=0&&(a=1);const s=.5*(t.x1+t.x0),l=.5*(t.y1+t.y0);return el&&(\"start\"==this.follow?a=e+s*l:\"end\"==this.follow&&(e=a-s*l)),[e,a]}update(t,i,n,e){if(this.have_updated_interactively)return;const a=this.computed_renderers();let s=this._compute_plot_bounds(a,t);null!=e&&(s=this.adjust_bounds_for_aspect(s,e)),this._plot_bounds.set(n,s);const[l,_]=this._compute_min_max(this._plot_bounds.entries(),i);let[o,r]=this._compute_range(l,_);null!=this._initial_start&&(\"log\"==this.scale_hint?this._initial_start>0&&(o=this._initial_start):o=this._initial_start),null!=this._initial_end&&(\"log\"==this.scale_hint?this._initial_end>0&&(r=this._initial_end):r=this._initial_end);let h=!1;\"auto\"==this.bounds&&(this.setv({bounds:[o,r]},{silent:!0}),h=!0);const[d,u]=[this.start,this.end];if(o!=d||r!=u){const t={};o!=d&&(t.start=o),r!=u&&(t.end=r),this.setv(t),h=!1}h&&this.change.emit()}reset(){this.have_updated_interactively=!1,this.setv({range_padding:this._initial_range_padding,range_padding_units:this._initial_range_padding_units,follow:this._initial_follow,follow_interval:this._initial_follow_interval,default_span:this._initial_default_span},{silent:!0}),this.change.emit()}}n.DataRange1d=g,l=g,g.__name__=\"DataRange1d\",l.define((({Boolean:t,Number:i,Nullable:n})=>({start:[i],end:[i],range_padding:[i,.1],range_padding_units:[o.PaddingUnits,\"percent\"],flipped:[t,!1],follow:[n(o.StartEnd),null],follow_interval:[n(i),null],default_span:[i,2],only_visible:[t,!1]}))),l.internal((({Enum:t})=>({scale_hint:[t(\"log\",\"auto\"),\"auto\"]})))},\n", - " function _(e,n,a,r,s){var t;r();const c=e(57);class _ extends c.Range{constructor(e){super(e)}}a.DataRange=_,t=_,_.__name__=\"DataRange\",t.define((({String:e,Array:n,AnyRef:a})=>({names:[n(e),[]],renderers:[n(a()),[]]})))},\n", - " function _(t,i,e,h,r){h();const s=t(24),n=t(26),{min:x,max:y}=Math;e.empty=function(){return{x0:1/0,y0:1/0,x1:-1/0,y1:-1/0}},e.positive_x=function(){return{x0:Number.MIN_VALUE,y0:-1/0,x1:1/0,y1:1/0}},e.positive_y=function(){return{x0:-1/0,y0:Number.MIN_VALUE,x1:1/0,y1:1/0}},e.union=function(t,i){return{x0:x(t.x0,i.x0),x1:y(t.x1,i.x1),y0:x(t.y0,i.y0),y1:y(t.y1,i.y1)}};class o{constructor(t){if(null==t)this.x0=0,this.y0=0,this.x1=0,this.y1=0;else if(\"x0\"in t){const{x0:i,y0:e,x1:h,y1:r}=t;if(!(i<=h&&e<=r))throw new Error(`invalid bbox {x0: ${i}, y0: ${e}, x1: ${h}, y1: ${r}}`);this.x0=i,this.y0=e,this.x1=h,this.y1=r}else if(\"x\"in t){const{x:i,y:e,width:h,height:r}=t;if(!(h>=0&&r>=0))throw new Error(`invalid bbox {x: ${i}, y: ${e}, width: ${h}, height: ${r}}`);this.x0=i,this.y0=e,this.x1=i+h,this.y1=e+r}else{let i,e,h,r;if(\"width\"in t)if(\"left\"in t)i=t.left,e=i+t.width;else if(\"right\"in t)e=t.right,i=e-t.width;else{const h=t.width/2;i=t.hcenter-h,e=t.hcenter+h}else i=t.left,e=t.right;if(\"height\"in t)if(\"top\"in t)h=t.top,r=h+t.height;else if(\"bottom\"in t)r=t.bottom,h=r-t.height;else{const i=t.height/2;h=t.vcenter-i,r=t.vcenter+i}else h=t.top,r=t.bottom;if(!(i<=e&&h<=r))throw new Error(`invalid bbox {left: ${i}, top: ${h}, right: ${e}, bottom: ${r}}`);this.x0=i,this.y0=h,this.x1=e,this.y1=r}}static from_rect({left:t,right:i,top:e,bottom:h}){return new o({x0:Math.min(t,i),y0:Math.min(e,h),x1:Math.max(t,i),y1:Math.max(e,h)})}equals(t){return this.x0==t.x0&&this.y0==t.y0&&this.x1==t.x1&&this.y1==t.y1}[n.equals](t,i){return i.eq(this.x0,t.x0)&&i.eq(this.y0,t.y0)&&i.eq(this.x1,t.x1)&&i.eq(this.y1,t.y1)}toString(){return`BBox({left: ${this.left}, top: ${this.top}, width: ${this.width}, height: ${this.height}})`}get left(){return this.x0}get top(){return this.y0}get right(){return this.x1}get bottom(){return this.y1}get p0(){return[this.x0,this.y0]}get p1(){return[this.x1,this.y1]}get x(){return this.x0}get y(){return this.y0}get width(){return this.x1-this.x0}get height(){return this.y1-this.y0}get size(){return{width:this.width,height:this.height}}get rect(){const{x0:t,y0:i,x1:e,y1:h}=this;return{p0:{x:t,y:i},p1:{x:e,y:i},p2:{x:e,y:h},p3:{x:t,y:h}}}get box(){const{x:t,y:i,width:e,height:h}=this;return{x:t,y:i,width:e,height:h}}get h_range(){return{start:this.x0,end:this.x1}}get v_range(){return{start:this.y0,end:this.y1}}get ranges(){return[this.h_range,this.v_range]}get aspect(){return this.width/this.height}get hcenter(){return(this.left+this.right)/2}get vcenter(){return(this.top+this.bottom)/2}get area(){return this.width*this.height}relative(){const{width:t,height:i}=this;return new o({x:0,y:0,width:t,height:i})}translate(t,i){const{x:e,y:h,width:r,height:s}=this;return new o({x:t+e,y:i+h,width:r,height:s})}relativize(t,i){return[t-this.x,i-this.y]}contains(t,i){return this.x0<=t&&t<=this.x1&&this.y0<=i&&i<=this.y1}clip(t,i){return tthis.x1&&(t=this.x1),ithis.y1&&(i=this.y1),[t,i]}grow_by(t){return new o({left:this.left-t,right:this.right+t,top:this.top-t,bottom:this.bottom+t})}shrink_by(t){return new o({left:this.left+t,right:this.right-t,top:this.top+t,bottom:this.bottom-t})}union(t){return new o({x0:x(this.x0,t.x0),y0:x(this.y0,t.y0),x1:y(this.x1,t.x1),y1:y(this.y1,t.y1)})}intersection(t){return this.intersects(t)?new o({x0:y(this.x0,t.x0),y0:y(this.y0,t.y0),x1:x(this.x1,t.x1),y1:x(this.y1,t.y1)}):null}intersects(t){return!(t.x1this.x1||t.y1this.y1)}get xview(){return{compute:t=>this.left+t,v_compute:t=>{const i=new s.ScreenArray(t.length),e=this.left;for(let h=0;hthis.bottom-t,v_compute:t=>{const i=new s.ScreenArray(t.length),e=this.bottom;for(let h=0;h0&&(r=r.filter((n=>(0,l.includes)(t,n.name)))),r}},\n", - " function _(t,n,e,i,s){var r;i();const a=t(57),o=t(20),g=t(21),p=t(24),c=t(9),l=t(8),u=t(11);function h(t,n,e=0){const i=new Map;for(let s=0;sa.get(t).value)));r.set(t,{value:l/s,mapping:a}),o+=s+n+p}return[r,(a.size-1)*n+g]}function _(t,n,e,i,s=0){var r;const a=new Map,o=new Map;for(const[n,e,i]of t){const t=null!==(r=o.get(n))&&void 0!==r?r:[];o.set(n,[...t,[e,i]])}let g=s,p=0;for(const[t,s]of o){const r=s.length,[o,l]=d(s,e,i,g);p+=l;const u=(0,c.sum)(s.map((([t])=>o.get(t).value)));a.set(t,{value:u/r,mapping:o}),g+=r+n+l}return[a,(o.size-1)*n+p]}e.Factor=(0,g.Or)(g.String,(0,g.Tuple)(g.String,g.String),(0,g.Tuple)(g.String,g.String,g.String)),e.FactorSeq=(0,g.Or)((0,g.Array)(g.String),(0,g.Array)((0,g.Tuple)(g.String,g.String)),(0,g.Array)((0,g.Tuple)(g.String,g.String,g.String))),e.map_one_level=h,e.map_two_levels=d,e.map_three_levels=_;class f extends a.Range{constructor(t){super(t)}get min(){return this.start}get max(){return this.end}initialize(){super.initialize(),this._init(!0)}connect_signals(){super.connect_signals(),this.connect(this.properties.factors.change,(()=>this.reset())),this.connect(this.properties.factor_padding.change,(()=>this.reset())),this.connect(this.properties.group_padding.change,(()=>this.reset())),this.connect(this.properties.subgroup_padding.change,(()=>this.reset())),this.connect(this.properties.range_padding.change,(()=>this.reset())),this.connect(this.properties.range_padding_units.change,(()=>this.reset()))}reset(){this._init(!1),this.change.emit()}_lookup(t){switch(t.length){case 1:{const[n]=t,e=this._mapping.get(n);return null!=e?e.value:NaN}case 2:{const[n,e]=t,i=this._mapping.get(n);if(null!=i){const t=i.mapping.get(e);if(null!=t)return t.value}return NaN}case 3:{const[n,e,i]=t,s=this._mapping.get(n);if(null!=s){const t=s.mapping.get(e);if(null!=t){const n=t.mapping.get(i);if(null!=n)return n.value}}return NaN}default:(0,u.unreachable)()}}synthetic(t){if((0,l.isNumber)(t))return t;if((0,l.isString)(t))return this._lookup([t]);let n=0;const e=t[t.length-1];return(0,l.isNumber)(e)&&(n=e,t=t.slice(0,-1)),this._lookup(t)+n}v_synthetic(t){const n=t.length,e=new p.ScreenArray(n);for(let i=0;i{if((0,c.every)(this.factors,l.isString)){const t=this.factors,[n,e]=h(t,this.factor_padding);return{levels:1,mapping:n,tops:null,mids:null,inside_padding:e}}if((0,c.every)(this.factors,(t=>(0,l.isArray)(t)&&2==t.length&&(0,l.isString)(t[0])&&(0,l.isString)(t[1])))){const t=this.factors,[n,e]=d(t,this.group_padding,this.factor_padding),i=[...n.keys()];return{levels:2,mapping:n,tops:i,mids:null,inside_padding:e}}if((0,c.every)(this.factors,(t=>(0,l.isArray)(t)&&3==t.length&&(0,l.isString)(t[0])&&(0,l.isString)(t[1])&&(0,l.isString)(t[2])))){const t=this.factors,[n,e]=_(t,this.group_padding,this.subgroup_padding,this.factor_padding),i=[...n.keys()],s=[];for(const[t,e]of n)for(const n of e.mapping.keys())s.push([t,n]);return{levels:3,mapping:n,tops:i,mids:s,inside_padding:e}}(0,u.unreachable)()})();this._mapping=e,this.tops=i,this.mids=s;let a=0,o=this.factors.length+r;if(\"percent\"==this.range_padding_units){const t=(o-a)*this.range_padding/2;a-=t,o+=t}else a-=this.range_padding,o+=this.range_padding;this.setv({start:a,end:o,levels:n},{silent:t}),\"auto\"==this.bounds&&this.setv({bounds:[a,o]},{silent:!0})}}e.FactorRange=f,r=f,f.__name__=\"FactorRange\",r.define((({Number:t})=>({factors:[e.FactorSeq,[]],factor_padding:[t,0],subgroup_padding:[t,.8],group_padding:[t,1.4],range_padding:[t,0],range_padding_units:[o.PaddingUnits,\"percent\"],start:[t],end:[t]}))),r.internal((({Number:t,String:n,Array:e,Tuple:i,Nullable:s})=>({levels:[t],mids:[s(e(i(n,n))),null],tops:[s(e(n)),null]})))},\n", - " function _(t,e,s,a,i){a();const n=t(1);var _;const r=t(69),o=t(112),l=t(48),d=t(20),h=t(24),c=t(113),u=(0,n.__importStar)(t(18)),v=t(10);class p extends r.DataAnnotationView{async lazy_initialize(){await super.lazy_initialize();const{start:t,end:e}=this.model;null!=t&&(this.start=await(0,c.build_view)(t,{parent:this})),null!=e&&(this.end=await(0,c.build_view)(e,{parent:this}))}set_data(t){var e,s;super.set_data(t),null===(e=this.start)||void 0===e||e.set_data(t),null===(s=this.end)||void 0===s||s.set_data(t)}remove(){var t,e;null===(t=this.start)||void 0===t||t.remove(),null===(e=this.end)||void 0===e||e.remove(),super.remove()}map_data(){const{frame:t}=this.plot_view;\"data\"==this.model.start_units?(this._sx_start=this.coordinates.x_scale.v_compute(this._x_start),this._sy_start=this.coordinates.y_scale.v_compute(this._y_start)):(this._sx_start=t.bbox.xview.v_compute(this._x_start),this._sy_start=t.bbox.yview.v_compute(this._y_start)),\"data\"==this.model.end_units?(this._sx_end=this.coordinates.x_scale.v_compute(this._x_end),this._sy_end=this.coordinates.y_scale.v_compute(this._y_end)):(this._sx_end=t.bbox.xview.v_compute(this._x_end),this._sy_end=t.bbox.yview.v_compute(this._y_end));const{_sx_start:e,_sy_start:s,_sx_end:a,_sy_end:i}=this,n=e.length,_=this._angles=new h.ScreenArray(n);for(let t=0;t({x_start:[u.XCoordinateSpec,{field:\"x_start\"}],y_start:[u.YCoordinateSpec,{field:\"y_start\"}],start_units:[d.SpatialUnits,\"data\"],start:[e(t(o.ArrowHead)),null],x_end:[u.XCoordinateSpec,{field:\"x_end\"}],y_end:[u.YCoordinateSpec,{field:\"y_end\"}],end_units:[d.SpatialUnits,\"data\"],end:[e(t(o.ArrowHead)),()=>new o.OpenHead]})))},\n", - " function _(t,e,n,s,a){s();const o=t(1);var i;const c=t(40),r=t(70),_=t(75),l=t(78),h=(0,o.__importStar)(t(18));class d extends c.AnnotationView{constructor(){super(...arguments),this._initial_set_data=!1}connect_signals(){super.connect_signals();const t=()=>{this.set_data(this.model.source),this._rerender()};this.connect(this.model.change,t),this.connect(this.model.source.streaming,t),this.connect(this.model.source.patching,t),this.connect(this.model.source.change,t)}_rerender(){this.request_render()}set_data(t){const e=this;for(const n of this.model)if(n instanceof h.VectorSpec||n instanceof h.ScalarSpec)if(n instanceof h.BaseCoordinateSpec){const s=n.array(t);e[`_${n.attr}`]=s}else{const s=n.uniform(t);e[`${n.attr}`]=s}this.plot_model.use_map&&(null!=e._x&&l.inplace.project_xy(e._x,e._y),null!=e._xs&&l.inplace.project_xsys(e._xs,e._ys));for(const t of this.visuals)t.update()}_render(){this._initial_set_data||(this.set_data(this.model.source),this._initial_set_data=!0),this.map_data(),this.paint(this.layer.ctx)}}n.DataAnnotationView=d,d.__name__=\"DataAnnotationView\";class u extends c.Annotation{constructor(t){super(t)}}n.DataAnnotation=u,i=u,u.__name__=\"DataAnnotation\",i.define((({Ref:t})=>({source:[t(r.ColumnarDataSource),()=>new _.ColumnDataSource]})))},\n", - " function _(t,e,n,s,a){var i;s();const r=t(71),l=t(15),c=t(19),o=t(73),h=t(8),u=t(9),g=t(13),d=t(72),_=t(74),m=t(29);class w extends r.DataSource{constructor(t){super(t),this.selection_manager=new o.SelectionManager(this)}get_array(t){let e=this.data[t];return null==e?this.data[t]=e=[]:(0,h.isArray)(e)||(this.data[t]=e=Array.from(e)),e}initialize(){super.initialize(),this._select=new l.Signal0(this,\"select\"),this.inspect=new l.Signal(this,\"inspect\"),this.streaming=new l.Signal0(this,\"streaming\"),this.patching=new l.Signal(this,\"patching\")}get_column(t){const e=this.data[t];return null!=e?e:null}columns(){return(0,g.keys)(this.data)}get_length(t=!0){const e=(0,u.uniq)((0,g.values)(this.data).map((t=>(0,m.is_NDArray)(t)?t.shape[0]:t.length)));switch(e.length){case 0:return null;case 1:return e[0];default:{const n=\"data source has columns of inconsistent lengths\";if(t)return c.logger.warn(n),e.sort()[0];throw new Error(n)}}}get length(){var t;return null!==(t=this.get_length())&&void 0!==t?t:0}clear(){const t={};for(const e of this.columns())t[e]=new this.data[e].constructor(0);this.data=t}}n.ColumnarDataSource=w,i=w,w.__name__=\"ColumnarDataSource\",i.define((({Ref:t})=>({selection_policy:[t(_.SelectionPolicy),()=>new _.UnionRenderers]}))),i.internal((({AnyRef:t})=>({inspected:[t(),()=>new d.Selection]})))},\n", - " function _(e,c,n,t,o){var a;t();const s=e(53),r=e(72);class l extends s.Model{constructor(e){super(e)}}n.DataSource=l,a=l,l.__name__=\"DataSource\",a.define((({Ref:e})=>({selected:[e(r.Selection),()=>new r.Selection]})))},\n", - " function _(i,e,s,t,n){var l;t();const c=i(53),d=i(9),h=i(13);class _ extends c.Model{constructor(i){super(i)}get_view(){return this.view}get selected_glyph(){return this.selected_glyphs.length>0?this.selected_glyphs[0]:null}add_to_selected_glyphs(i){this.selected_glyphs.push(i)}update(i,e=!0,s=\"replace\"){switch(s){case\"replace\":this.indices=i.indices,this.line_indices=i.line_indices,this.multiline_indices=i.multiline_indices,this.image_indices=i.image_indices,this.view=i.view,this.selected_glyphs=i.selected_glyphs;break;case\"append\":this.update_through_union(i);break;case\"intersect\":this.update_through_intersection(i);break;case\"subtract\":this.update_through_subtraction(i)}}clear(){this.indices=[],this.line_indices=[],this.multiline_indices={},this.image_indices=[],this.view=null,this.selected_glyphs=[]}map(i){return new _(Object.assign(Object.assign({},this.attributes),{indices:this.indices.map(i),multiline_indices:(0,h.to_object)((0,h.entries)(this.multiline_indices).map((([e,s])=>[i(Number(e)),s]))),image_indices:this.image_indices.map((e=>Object.assign(Object.assign({},e),{index:i(e.index)})))}))}is_empty(){return 0==this.indices.length&&0==this.line_indices.length&&0==this.image_indices.length}update_through_union(i){this.indices=(0,d.union)(this.indices,i.indices),this.selected_glyphs=(0,d.union)(i.selected_glyphs,this.selected_glyphs),this.line_indices=(0,d.union)(i.line_indices,this.line_indices),this.view=i.view,this.multiline_indices=(0,h.merge)(i.multiline_indices,this.multiline_indices)}update_through_intersection(i){this.indices=(0,d.intersection)(this.indices,i.indices),this.selected_glyphs=(0,d.union)(i.selected_glyphs,this.selected_glyphs),this.line_indices=(0,d.union)(i.line_indices,this.line_indices),this.view=i.view,this.multiline_indices=(0,h.merge)(i.multiline_indices,this.multiline_indices)}update_through_subtraction(i){this.indices=(0,d.difference)(this.indices,i.indices),this.selected_glyphs=(0,d.union)(i.selected_glyphs,this.selected_glyphs),this.line_indices=(0,d.union)(i.line_indices,this.line_indices),this.view=i.view,this.multiline_indices=(0,h.merge)(i.multiline_indices,this.multiline_indices)}}s.Selection=_,l=_,_.__name__=\"Selection\",l.define((({Int:i,Array:e,Dict:s})=>({indices:[e(i),[]],line_indices:[e(i),[]],multiline_indices:[s(e(i)),{}]}))),l.internal((({Int:i,Array:e,AnyRef:s,Struct:t,Nullable:n})=>({selected_glyphs:[e(s()),[]],view:[n(s()),null],image_indices:[e(t({index:i,dim1:i,dim2:i,flat_index:i})),[]]})))},\n", - " function _(e,t,o,s,c){s();const n=e(72);function i(e){return\"GlyphRenderer\"==e.model.type}function l(e){return\"GraphRenderer\"==e.model.type}class r{constructor(e){this.source=e,this.inspectors=new Map}select(e,t,o,s=\"replace\"){const c=[],n=[];for(const t of e)i(t)?c.push(t):l(t)&&n.push(t);let r=!1;for(const e of n){const c=e.model.selection_policy.hit_test(t,e);r=r||e.model.selection_policy.do_selection(c,e.model,o,s)}if(c.length>0){const e=this.source.selection_policy.hit_test(t,c);r=r||this.source.selection_policy.do_selection(e,this.source,o,s)}return r}inspect(e,t){let o=!1;if(i(e)){const s=e.hit_test(t);if(null!=s){o=!s.is_empty();const c=this.get_or_create_inspector(e.model);c.update(s,!0,\"replace\"),this.source.setv({inspected:c},{silent:!0}),this.source.inspect.emit([e.model,{geometry:t}])}}else if(l(e)){const s=e.model.inspection_policy.hit_test(t,e);o=o||e.model.inspection_policy.do_inspection(s,t,e,!1,\"replace\")}return o}clear(e){this.source.selected.clear(),null!=e&&this.get_or_create_inspector(e.model).clear()}get_or_create_inspector(e){let t=this.inspectors.get(e);return null==t&&(t=new n.Selection,this.inspectors.set(e,t)),t}}o.SelectionManager=r,r.__name__=\"SelectionManager\"},\n", - " function _(e,t,n,s,o){s();const r=e(53);class c extends r.Model{do_selection(e,t,n,s){return null!=e&&(t.selected.update(e,n,s),t._select.emit(),!t.selected.is_empty())}}n.SelectionPolicy=c,c.__name__=\"SelectionPolicy\";class l extends c{hit_test(e,t){const n=[];for(const s of t){const t=s.hit_test(e);null!=t&&n.push(t)}if(n.length>0){const e=n[0];for(const t of n)e.update_through_intersection(t);return e}return null}}n.IntersectRenderers=l,l.__name__=\"IntersectRenderers\";class _ extends c{hit_test(e,t){const n=[];for(const s of t){const t=s.hit_test(e);null!=t&&n.push(t)}if(n.length>0){const e=n[0];for(const t of n)e.update_through_union(t);return e}return null}}n.UnionRenderers=_,_.__name__=\"UnionRenderers\"},\n", - " function _(t,n,e,s,o){s();const r=t(1);var l;const c=t(70),i=t(8),a=t(13),u=(0,r.__importStar)(t(76)),h=t(77),d=t(35);function f(t,n,e){if((0,i.isArray)(t)){const s=t.concat(n);return null!=e&&s.length>e?s.slice(-e):s}if((0,i.isTypedArray)(t)){const s=t.length+n.length;if(null!=e&&s>e){const o=s-e,r=t.length;let l;t.length({data:[t(n),{}]})))},\n", - " function _(t,n,o,e,c){e(),o.concat=function(t,...n){let o=t.length;for(const t of n)o+=t.length;const e=new t.constructor(o);e.set(t,0);let c=t.length;for(const t of n)e.set(t,c),c+=t.length;return e}},\n", - " function _(n,o,t,e,f){function c(...n){const o=new Set;for(const t of n)for(const n of t)o.add(n);return o}e(),t.union=c,t.intersection=function(n,...o){const t=new Set;n:for(const e of n){for(const n of o)if(!n.has(e))continue n;t.add(e)}return t},t.difference=function(n,...o){const t=new Set(n);for(const n of c(...o))t.delete(n);return t}},\n", - " function _(n,t,e,o,r){o();const c=n(1),l=(0,c.__importDefault)(n(79)),i=(0,c.__importDefault)(n(80)),u=n(24),a=new i.default(\"GOOGLE\"),s=new i.default(\"WGS84\"),f=(0,l.default)(s,a);e.wgs84_mercator={compute:(n,t)=>isFinite(n)&&isFinite(t)?f.forward([n,t]):[NaN,NaN],invert:(n,t)=>isFinite(n)&&isFinite(t)?f.inverse([n,t]):[NaN,NaN]};const _={lon:[-20026376.39,20026376.39],lat:[-20048966.1,20048966.1]},p={lon:[-180,180],lat:[-85.06,85.06]},{min:g,max:h}=Math;function m(n,t){const o=g(n.length,t.length),r=(0,u.infer_type)(n,t),c=new r(o),l=new r(o);return e.inplace.project_xy(n,t,c,l),[c,l]}e.clip_mercator=function(n,t,e){const[o,r]=_[e];return[h(n,o),g(t,r)]},e.in_bounds=function(n,t){const[e,o]=p[t];return e2?void 0!==e.name&&\"geocent\"===e.name||void 0!==n.name&&\"geocent\"===n.name?\"number\"==typeof o.z?[o.x,o.y,o.z].concat(t.splice(3)):[o.x,o.y,t[2]].concat(t.splice(3)):[o.x,o.y].concat(t.splice(2)):[o.x,o.y]):(a=(0,c.default)(e,n,t,r),2===(i=Object.keys(t)).length||i.forEach((function(r){if(void 0!==e.name&&\"geocent\"===e.name||void 0!==n.name&&\"geocent\"===n.name){if(\"x\"===r||\"y\"===r||\"z\"===r)return}else if(\"x\"===r||\"y\"===r)return;a[r]=t[r]})),a)}function l(e){return e instanceof i.default?e:e.oProj?e.oProj:(0,i.default)(e)}t.default=function(e,n,t){e=l(e);var r,o=!1;return void 0===n?(n=e,e=u,o=!0):(void 0!==n.x||Array.isArray(n))&&(t=n,n=e,e=u,o=!0),n=l(n),t?f(e,n,t):(r={forward:function(t,r){return f(e,n,t,r)},inverse:function(t,r){return f(n,e,t,r)}},o&&(r.oProj=n),r)}},\n", - " function _(t,e,a,s,i){s();const l=t(1),u=(0,l.__importDefault)(t(81)),r=(0,l.__importDefault)(t(92)),d=(0,l.__importDefault)(t(93)),o=t(101),f=(0,l.__importDefault)(t(103)),p=(0,l.__importDefault)(t(104)),m=(0,l.__importDefault)(t(88)),n=t(105);function h(t,e){if(!(this instanceof h))return new h(t);e=e||function(t){if(t)throw t};var a=(0,u.default)(t);if(\"object\"==typeof a){var s=h.projections.get(a.projName);if(s){if(a.datumCode&&\"none\"!==a.datumCode){var i=(0,m.default)(f.default,a.datumCode);i&&(a.datum_params=a.datum_params||(i.towgs84?i.towgs84.split(\",\"):null),a.ellps=i.ellipse,a.datumName=i.datumName?i.datumName:a.datumCode)}a.k0=a.k0||1,a.axis=a.axis||\"enu\",a.ellps=a.ellps||\"wgs84\",a.lat1=a.lat1||a.lat0;var l=(0,o.sphere)(a.a,a.b,a.rf,a.ellps,a.sphere),d=(0,o.eccentricity)(l.a,l.b,l.rf,a.R_A),_=(0,n.getNadgrids)(a.nadgrids),c=a.datum||(0,p.default)(a.datumCode,a.datum_params,l.a,l.b,d.es,d.ep2,_);(0,r.default)(this,a),(0,r.default)(this,s),this.a=l.a,this.b=l.b,this.rf=l.rf,this.sphere=l.sphere,this.es=d.es,this.e=d.e,this.ep2=d.ep2,this.datum=c,this.init(),e(null,this)}else e(t)}else e(t)}h.projections=d.default,h.projections.start(),a.default=h},\n", - " function _(t,r,n,u,e){u();const f=t(1),i=(0,f.__importDefault)(t(82)),a=(0,f.__importDefault)(t(89)),o=(0,f.__importDefault)(t(84)),l=(0,f.__importDefault)(t(88));var C=[\"PROJECTEDCRS\",\"PROJCRS\",\"GEOGCS\",\"GEOCCS\",\"PROJCS\",\"LOCAL_CS\",\"GEODCRS\",\"GEODETICCRS\",\"GEODETICDATUM\",\"ENGCRS\",\"ENGINEERINGCRS\"];var d=[\"3857\",\"900913\",\"3785\",\"102113\"];n.default=function(t){if(!function(t){return\"string\"==typeof t}(t))return t;if(function(t){return t in i.default}(t))return i.default[t];if(function(t){return C.some((function(r){return t.indexOf(r)>-1}))}(t)){var r=(0,a.default)(t);if(function(t){var r=(0,l.default)(t,\"authority\");if(r){var n=(0,l.default)(r,\"epsg\");return n&&d.indexOf(n)>-1}}(r))return i.default[\"EPSG:3857\"];var n=function(t){var r=(0,l.default)(t,\"extension\");if(r)return(0,l.default)(r,\"proj4\")}(r);return n?(0,o.default)(n):r}return function(t){return\"+\"===t[0]}(t)?(0,o.default)(t):void 0}},\n", - " function _(t,r,i,e,n){e();const f=t(1),a=(0,f.__importDefault)(t(83)),l=(0,f.__importDefault)(t(84)),u=(0,f.__importDefault)(t(89));function o(t){var r=this;if(2===arguments.length){var i=arguments[1];\"string\"==typeof i?\"+\"===i.charAt(0)?o[t]=(0,l.default)(arguments[1]):o[t]=(0,u.default)(arguments[1]):o[t]=i}else if(1===arguments.length){if(Array.isArray(t))return t.map((function(t){Array.isArray(t)?o.apply(r,t):o(t)}));if(\"string\"==typeof t){if(t in o)return o[t]}else\"EPSG\"in t?o[\"EPSG:\"+t.EPSG]=t:\"ESRI\"in t?o[\"ESRI:\"+t.ESRI]=t:\"IAU2000\"in t?o[\"IAU2000:\"+t.IAU2000]=t:console.log(t);return}}(0,a.default)(o),i.default=o},\n", - " function _(t,l,G,S,e){S(),G.default=function(t){t(\"EPSG:4326\",\"+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees\"),t(\"EPSG:4269\",\"+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees\"),t(\"EPSG:3857\",\"+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs\"),t.WGS84=t[\"EPSG:4326\"],t[\"EPSG:3785\"]=t[\"EPSG:3857\"],t.GOOGLE=t[\"EPSG:3857\"],t[\"EPSG:900913\"]=t[\"EPSG:3857\"],t[\"EPSG:102113\"]=t[\"EPSG:3857\"]}},\n", - " function _(t,n,o,a,u){a();const e=t(1),r=t(85),i=(0,e.__importDefault)(t(86)),f=(0,e.__importDefault)(t(87)),l=(0,e.__importDefault)(t(88));o.default=function(t){var n,o,a,u={},e=t.split(\"+\").map((function(t){return t.trim()})).filter((function(t){return t})).reduce((function(t,n){var o=n.split(\"=\");return o.push(!0),t[o[0].toLowerCase()]=o[1],t}),{}),c={proj:\"projName\",datum:\"datumCode\",rf:function(t){u.rf=parseFloat(t)},lat_0:function(t){u.lat0=t*r.D2R},lat_1:function(t){u.lat1=t*r.D2R},lat_2:function(t){u.lat2=t*r.D2R},lat_ts:function(t){u.lat_ts=t*r.D2R},lon_0:function(t){u.long0=t*r.D2R},lon_1:function(t){u.long1=t*r.D2R},lon_2:function(t){u.long2=t*r.D2R},alpha:function(t){u.alpha=parseFloat(t)*r.D2R},gamma:function(t){u.rectified_grid_angle=parseFloat(t)},lonc:function(t){u.longc=t*r.D2R},x_0:function(t){u.x0=parseFloat(t)},y_0:function(t){u.y0=parseFloat(t)},k_0:function(t){u.k0=parseFloat(t)},k:function(t){u.k0=parseFloat(t)},a:function(t){u.a=parseFloat(t)},b:function(t){u.b=parseFloat(t)},r_a:function(){u.R_A=!0},zone:function(t){u.zone=parseInt(t,10)},south:function(){u.utmSouth=!0},towgs84:function(t){u.datum_params=t.split(\",\").map((function(t){return parseFloat(t)}))},to_meter:function(t){u.to_meter=parseFloat(t)},units:function(t){u.units=t;var n=(0,l.default)(f.default,t);n&&(u.to_meter=n.to_meter)},from_greenwich:function(t){u.from_greenwich=t*r.D2R},pm:function(t){var n=(0,l.default)(i.default,t);u.from_greenwich=(n||parseFloat(t))*r.D2R},nadgrids:function(t){\"@null\"===t?u.datumCode=\"none\":u.nadgrids=t},axis:function(t){var n=\"ewnsud\";3===t.length&&-1!==n.indexOf(t.substr(0,1))&&-1!==n.indexOf(t.substr(1,1))&&-1!==n.indexOf(t.substr(2,1))&&(u.axis=t)},approx:function(){u.approx=!0}};for(n in e)o=e[n],n in c?\"function\"==typeof(a=c[n])?a(o):u[a]=o:u[n]=o;return\"string\"==typeof u.datumCode&&\"WGS84\"!==u.datumCode&&(u.datumCode=u.datumCode.toLowerCase()),u}},\n", - " function _(S,_,P,R,I){R(),P.PJD_3PARAM=1,P.PJD_7PARAM=2,P.PJD_GRIDSHIFT=3,P.PJD_WGS84=4,P.PJD_NODATUM=5,P.SRS_WGS84_SEMIMAJOR=6378137,P.SRS_WGS84_SEMIMINOR=6356752.314,P.SRS_WGS84_ESQUARED=.0066943799901413165,P.SEC_TO_RAD=484813681109536e-20,P.HALF_PI=Math.PI/2,P.SIXTH=.16666666666666666,P.RA4=.04722222222222222,P.RA6=.022156084656084655,P.EPSLN=1e-10,P.D2R=.017453292519943295,P.R2D=57.29577951308232,P.FORTPI=Math.PI/4,P.TWO_PI=2*Math.PI,P.SPI=3.14159265359},\n", - " function _(o,r,a,e,s){e();var n={};a.default=n,n.greenwich=0,n.lisbon=-9.131906111111,n.paris=2.337229166667,n.bogota=-74.080916666667,n.madrid=-3.687938888889,n.rome=12.452333333333,n.bern=7.439583333333,n.jakarta=106.807719444444,n.ferro=-17.666666666667,n.brussels=4.367975,n.stockholm=18.058277777778,n.athens=23.7163375,n.oslo=10.722916666667},\n", - " function _(t,e,f,o,u){o(),f.default={ft:{to_meter:.3048},\"us-ft\":{to_meter:1200/3937}}},\n", - " function _(e,r,t,a,n){a();var o=/[\\s_\\-\\/\\(\\)]/g;t.default=function(e,r){if(e[r])return e[r];for(var t,a=Object.keys(e),n=r.toLowerCase().replace(o,\"\"),f=-1;++f0?90:-90),e.lat_ts=e.lat1)}(n),n}},\n", - " function _(t,e,r,i,s){i(),r.default=function(t){return new d(t).output()};var h=/\\s/,o=/[A-Za-z]/,n=/[A-Za-z84]/,a=/[,\\]]/,u=/[\\d\\.E\\-\\+]/;function d(t){if(\"string\"!=typeof t)throw new Error(\"not a string\");this.text=t.trim(),this.level=0,this.place=0,this.root=null,this.stack=[],this.currentObject=null,this.state=1}d.prototype.readCharicter=function(){var t=this.text[this.place++];if(4!==this.state)for(;h.test(t);){if(this.place>=this.text.length)return;t=this.text[this.place++]}switch(this.state){case 1:return this.neutral(t);case 2:return this.keyword(t);case 4:return this.quoted(t);case 5:return this.afterquote(t);case 3:return this.number(t);case-1:return}},d.prototype.afterquote=function(t){if('\"'===t)return this.word+='\"',void(this.state=4);if(a.test(t))return this.word=this.word.trim(),void this.afterItem(t);throw new Error(\"havn't handled \\\"\"+t+'\" in afterquote yet, index '+this.place)},d.prototype.afterItem=function(t){return\",\"===t?(null!==this.word&&this.currentObject.push(this.word),this.word=null,void(this.state=1)):\"]\"===t?(this.level--,null!==this.word&&(this.currentObject.push(this.word),this.word=null),this.state=1,this.currentObject=this.stack.pop(),void(this.currentObject||(this.state=-1))):void 0},d.prototype.number=function(t){if(!u.test(t)){if(a.test(t))return this.word=parseFloat(this.word),void this.afterItem(t);throw new Error(\"havn't handled \\\"\"+t+'\" in number yet, index '+this.place)}this.word+=t},d.prototype.quoted=function(t){'\"'!==t?this.word+=t:this.state=5},d.prototype.keyword=function(t){if(n.test(t))this.word+=t;else{if(\"[\"===t){var e=[];return e.push(this.word),this.level++,null===this.root?this.root=e:this.currentObject.push(e),this.stack.push(this.currentObject),this.currentObject=e,void(this.state=1)}if(!a.test(t))throw new Error(\"havn't handled \\\"\"+t+'\" in keyword yet, index '+this.place);this.afterItem(t)}},d.prototype.neutral=function(t){if(o.test(t))return this.word=t,void(this.state=2);if('\"'===t)return this.word=\"\",void(this.state=4);if(u.test(t))return this.word=t,void(this.state=3);if(!a.test(t))throw new Error(\"havn't handled \\\"\"+t+'\" in neutral yet, index '+this.place);this.afterItem(t)},d.prototype.output=function(){for(;this.place90&&a*o.R2D<-90&&h*o.R2D>180&&h*o.R2D<-180)return null;if(Math.abs(Math.abs(a)-o.HALF_PI)<=o.EPSLN)return null;if(this.sphere)i=this.x0+this.a*this.k0*(0,n.default)(h-this.long0),s=this.y0+this.a*this.k0*Math.log(Math.tan(o.FORTPI+.5*a));else{var e=Math.sin(a),r=(0,l.default)(this.e,a,e);i=this.x0+this.a*this.k0*(0,n.default)(h-this.long0),s=this.y0-this.a*this.k0*Math.log(r)}return t.x=i,t.y=s,t}function M(t){var i,s,h=t.x-this.x0,a=t.y-this.y0;if(this.sphere)s=o.HALF_PI-2*Math.atan(Math.exp(-a/(this.a*this.k0)));else{var e=Math.exp(-a/(this.a*this.k0));if(-9999===(s=(0,u.default)(this.e,e)))return null}return i=(0,n.default)(this.long0+h/(this.a*this.k0)),t.x=i,t.y=s,t}s.init=f,s.forward=_,s.inverse=M,s.names=[\"Mercator\",\"Popular Visualisation Pseudo Mercator\",\"Mercator_1SP\",\"Mercator_Auxiliary_Sphere\",\"merc\"],s.default={init:f,forward:_,inverse:M,names:s.names}},\n", - " function _(t,n,r,u,a){u(),r.default=function(t,n,r){var u=t*n;return r/Math.sqrt(1-u*u)}},\n", - " function _(t,n,u,a,f){a();const e=t(1),o=t(85),_=(0,e.__importDefault)(t(97));u.default=function(t){return Math.abs(t)<=o.SPI?t:t-(0,_.default)(t)*o.TWO_PI}},\n", - " function _(n,t,u,f,c){f(),u.default=function(n){return n<0?-1:1}},\n", - " function _(t,n,a,o,u){o();const c=t(85);a.default=function(t,n,a){var o=t*a,u=.5*t;return o=Math.pow((1-o)/(1+o),u),Math.tan(.5*(c.HALF_PI-n))/o}},\n", - " function _(t,a,n,r,f){r();const h=t(85);n.default=function(t,a){for(var n,r,f=.5*t,o=h.HALF_PI-2*Math.atan(a),u=0;u<=15;u++)if(n=t*Math.sin(o),o+=r=h.HALF_PI-2*Math.atan(a*Math.pow((1-n)/(1+n),f))-o,Math.abs(r)<=1e-10)return o;return-9999}},\n", - " function _(n,i,e,t,r){function a(){}function f(n){return n}t(),e.init=a,e.forward=f,e.inverse=f,e.names=[\"longlat\",\"identity\"],e.default={init:a,forward:f,inverse:f,names:e.names}},\n", - " function _(t,r,e,a,n){a();const f=t(1),i=t(85),u=(0,f.__importStar)(t(102)),c=(0,f.__importDefault)(t(88));e.eccentricity=function(t,r,e,a){var n=t*t,f=r*r,u=(n-f)/n,c=0;return a?(n=(t*=1-u*(i.SIXTH+u*(i.RA4+u*i.RA6)))*t,u=0):c=Math.sqrt(u),{es:u,e:c,ep2:(n-f)/f}},e.sphere=function(t,r,e,a,n){if(!t){var f=(0,c.default)(u.default,a);f||(f=u.WGS84),t=f.a,r=f.b,e=f.rf}return e&&!r&&(r=(1-1/e)*t),(0===e||Math.abs(t-r)3&&(0===s.datum_params[3]&&0===s.datum_params[4]&&0===s.datum_params[5]&&0===s.datum_params[6]||(s.datum_type=d.PJD_7PARAM,s.datum_params[3]*=d.SEC_TO_RAD,s.datum_params[4]*=d.SEC_TO_RAD,s.datum_params[5]*=d.SEC_TO_RAD,s.datum_params[6]=s.datum_params[6]/1e6+1))),r&&(s.datum_type=d.PJD_GRIDSHIFT,s.grids=r),s.a=_,s.b=t,s.es=u,s.ep2=p,s}},\n", - " function _(t,e,n,r,i){r();var u={};function l(t){if(0===t.length)return null;var e=\"@\"===t[0];return e&&(t=t.slice(1)),\"null\"===t?{name:\"null\",mandatory:!e,grid:null,isNull:!0}:{name:t,mandatory:!e,grid:u[t]||null,isNull:!1}}function o(t){return t/3600*Math.PI/180}function a(t,e,n){return String.fromCharCode.apply(null,new Uint8Array(t.buffer.slice(e,n)))}function d(t){return t.map((function(t){return[o(t.longitudeShift),o(t.latitudeShift)]}))}function g(t,e,n){return{name:a(t,e+8,e+16).trim(),parent:a(t,e+24,e+24+8).trim(),lowerLatitude:t.getFloat64(e+72,n),upperLatitude:t.getFloat64(e+88,n),lowerLongitude:t.getFloat64(e+104,n),upperLongitude:t.getFloat64(e+120,n),latitudeInterval:t.getFloat64(e+136,n),longitudeInterval:t.getFloat64(e+152,n),gridNodeCount:t.getInt32(e+168,n)}}function s(t,e,n,r){for(var i=e+176,u=[],l=0;l1&&console.log(\"Only single NTv2 subgrids are currently supported, subsequent sub grids are ignored\");var l=function(t,e,n){for(var r=176,i=[],u=0;ua.y||f>a.x||N1e-12&&Math.abs(n.y)>1e-12);if(d<0)return console.log(\"Inverse grid shift iterator failed to converge.\"),a;a.x=(0,u.default)(l.x+t.ll[0]),a.y=l.y+t.ll[1]}else isNaN(l.x)||(a.x=r.x+l.x,a.y=r.y+l.y);return a}function f(r,e){var t,a={x:r.x/e.del[0],y:r.y/e.del[1]},i=Math.floor(a.x),l=Math.floor(a.y),n=a.x-1*i,o=a.y-1*l,u={x:Number.NaN,y:Number.NaN};if(i<0||i>=e.lim[0])return u;if(l<0||l>=e.lim[1])return u;t=l*e.lim[0]+i;var d=e.cvs[t][0],s=e.cvs[t][1];t++;var y=e.cvs[t][0],f=e.cvs[t][1];t+=e.lim[0];var x=e.cvs[t][0],m=e.cvs[t][1];t--;var N=e.cvs[t][0],c=e.cvs[t][1],_=n*o,g=n*(1-o),v=(1-n)*(1-o),S=(1-n)*o;return u.x=v*d+g*y+S*N+_*x,u.y=v*s+g*f+S*c+_*m,u}t.default=function(r,e,t){if((0,o.compareDatums)(r,e))return t;if(r.datum_type===n.PJD_NODATUM||e.datum_type===n.PJD_NODATUM)return t;var a=r.a,i=r.es;if(r.datum_type===n.PJD_GRIDSHIFT){if(0!==s(r,!1,t))return;a=n.SRS_WGS84_SEMIMAJOR,i=n.SRS_WGS84_ESQUARED}var l=e.a,u=e.b,y=e.es;if(e.datum_type===n.PJD_GRIDSHIFT&&(l=n.SRS_WGS84_SEMIMAJOR,u=n.SRS_WGS84_SEMIMINOR,y=n.SRS_WGS84_ESQUARED),i===y&&a===l&&!d(r.datum_type)&&!d(e.datum_type))return t;if(t=(0,o.geodeticToGeocentric)(t,i,a),d(r.datum_type)&&(t=(0,o.geocentricToWgs84)(t,r.datum_type,r.datum_params)),d(e.datum_type)&&(t=(0,o.geocentricFromWgs84)(t,e.datum_type,e.datum_params)),t=(0,o.geocentricToGeodetic)(t,y,l,u),e.datum_type===n.PJD_GRIDSHIFT&&0!==s(e,!0,t))return;return t},t.applyGridShift=s},\n", - " function _(a,t,r,m,s){m();const u=a(85);r.compareDatums=function(a,t){return a.datum_type===t.datum_type&&(!(a.a!==t.a||Math.abs(a.es-t.es)>5e-11)&&(a.datum_type===u.PJD_3PARAM?a.datum_params[0]===t.datum_params[0]&&a.datum_params[1]===t.datum_params[1]&&a.datum_params[2]===t.datum_params[2]:a.datum_type!==u.PJD_7PARAM||a.datum_params[0]===t.datum_params[0]&&a.datum_params[1]===t.datum_params[1]&&a.datum_params[2]===t.datum_params[2]&&a.datum_params[3]===t.datum_params[3]&&a.datum_params[4]===t.datum_params[4]&&a.datum_params[5]===t.datum_params[5]&&a.datum_params[6]===t.datum_params[6]))},r.geodeticToGeocentric=function(a,t,r){var m,s,_,e,n=a.x,d=a.y,i=a.z?a.z:0;if(d<-u.HALF_PI&&d>-1.001*u.HALF_PI)d=-u.HALF_PI;else if(d>u.HALF_PI&&d<1.001*u.HALF_PI)d=u.HALF_PI;else{if(d<-u.HALF_PI)return{x:-1/0,y:-1/0,z:a.z};if(d>u.HALF_PI)return{x:1/0,y:1/0,z:a.z}}return n>Math.PI&&(n-=2*Math.PI),s=Math.sin(d),e=Math.cos(d),_=s*s,{x:((m=r/Math.sqrt(1-t*_))+i)*e*Math.cos(n),y:(m+i)*e*Math.sin(n),z:(m*(1-t)+i)*s}},r.geocentricToGeodetic=function(a,t,r,m){var s,_,e,n,d,i,p,P,y,z,M,o,A,c,x,h=1e-12,f=a.x,I=a.y,F=a.z?a.z:0;if(s=Math.sqrt(f*f+I*I),_=Math.sqrt(f*f+I*I+F*F),s/r1e-24&&A<30);return{x:c,y:Math.atan(M/Math.abs(z)),z:x}},r.geocentricToWgs84=function(a,t,r){if(t===u.PJD_3PARAM)return{x:a.x+r[0],y:a.y+r[1],z:a.z+r[2]};if(t===u.PJD_7PARAM){var m=r[0],s=r[1],_=r[2],e=r[3],n=r[4],d=r[5],i=r[6];return{x:i*(a.x-d*a.y+n*a.z)+m,y:i*(d*a.x+a.y-e*a.z)+s,z:i*(-n*a.x+e*a.y+a.z)+_}}},r.geocentricFromWgs84=function(a,t,r){if(t===u.PJD_3PARAM)return{x:a.x-r[0],y:a.y-r[1],z:a.z-r[2]};if(t===u.PJD_7PARAM){var m=r[0],s=r[1],_=r[2],e=r[3],n=r[4],d=r[5],i=r[6],p=(a.x-m)/i,P=(a.y-s)/i,y=(a.z-_)/i;return{x:p+d*P-n*y,y:-d*p+P+e*y,z:n*p-e*P+y}}}},\n", - " function _(e,a,i,r,s){r(),i.default=function(e,a,i){var r,s,n,c=i.x,d=i.y,f=i.z||0,u={};for(n=0;n<3;n++)if(!a||2!==n||void 0!==i.z)switch(0===n?(r=c,s=-1!==\"ew\".indexOf(e.axis[n])?\"x\":\"y\"):1===n?(r=d,s=-1!==\"ns\".indexOf(e.axis[n])?\"y\":\"x\"):(r=f,s=\"z\"),e.axis[n]){case\"e\":u[s]=r;break;case\"w\":u[s]=-r;break;case\"n\":u[s]=r;break;case\"s\":u[s]=-r;break;case\"u\":void 0!==i[s]&&(u.z=r);break;case\"d\":void 0!==i[s]&&(u.z=-r);break;default:return null}return u}},\n", - " function _(n,t,e,u,f){u(),e.default=function(n){var t={x:n[0],y:n[1]};return n.length>2&&(t.z=n[2]),n.length>3&&(t.m=n[3]),t}},\n", - " function _(e,i,n,t,r){function o(e){if(\"function\"==typeof Number.isFinite){if(Number.isFinite(e))return;throw new TypeError(\"coordinates must be finite numbers\")}if(\"number\"!=typeof e||e!=e||!isFinite(e))throw new TypeError(\"coordinates must be finite numbers\")}t(),n.default=function(e){o(e.x),o(e.y)}},\n", - " function _(e,i,s,t,o){t();const n=e(1);var l,a,r,_,c;const d=e(53),v=e(42),u=(0,n.__importStar)(e(45)),h=e(48),m=(0,n.__importStar)(e(18));class T extends v.View{initialize(){super.initialize(),this.visuals=new u.Visuals(this)}request_render(){this.parent.request_render()}get canvas(){return this.parent.canvas}set_data(e){const i=this;for(const s of this.model){if(!(s instanceof m.VectorSpec||s instanceof m.ScalarSpec))continue;const t=s.uniform(e);i[`${s.attr}`]=t}}}s.ArrowHeadView=T,T.__name__=\"ArrowHeadView\";class p extends d.Model{constructor(e){super(e)}}s.ArrowHead=p,l=p,p.__name__=\"ArrowHead\",l.define((()=>({size:[m.NumberSpec,25]})));class V extends T{clip(e,i){this.visuals.line.set_vectorize(e,i);const s=this.size.get(i);e.moveTo(.5*s,s),e.lineTo(.5*s,-2),e.lineTo(-.5*s,-2),e.lineTo(-.5*s,s),e.lineTo(0,0),e.lineTo(.5*s,s)}render(e,i){if(this.visuals.line.doit){this.visuals.line.set_vectorize(e,i);const s=this.size.get(i);e.beginPath(),e.moveTo(.5*s,s),e.lineTo(0,0),e.lineTo(-.5*s,s),e.stroke()}}}s.OpenHeadView=V,V.__name__=\"OpenHeadView\";class f extends p{constructor(e){super(e)}}s.OpenHead=f,a=f,f.__name__=\"OpenHead\",a.prototype.default_view=V,a.mixins(h.LineVector);class w extends T{clip(e,i){this.visuals.line.set_vectorize(e,i);const s=this.size.get(i);e.moveTo(.5*s,s),e.lineTo(.5*s,-2),e.lineTo(-.5*s,-2),e.lineTo(-.5*s,s),e.lineTo(.5*s,s)}render(e,i){this.visuals.fill.doit&&(this.visuals.fill.set_vectorize(e,i),this._normal(e,i),e.fill()),this.visuals.line.doit&&(this.visuals.line.set_vectorize(e,i),this._normal(e,i),e.stroke())}_normal(e,i){const s=this.size.get(i);e.beginPath(),e.moveTo(.5*s,s),e.lineTo(0,0),e.lineTo(-.5*s,s),e.closePath()}}s.NormalHeadView=w,w.__name__=\"NormalHeadView\";class H extends p{constructor(e){super(e)}}s.NormalHead=H,r=H,H.__name__=\"NormalHead\",r.prototype.default_view=w,r.mixins([h.LineVector,h.FillVector]),r.override({fill_color:\"black\"});class z extends T{clip(e,i){this.visuals.line.set_vectorize(e,i);const s=this.size.get(i);e.moveTo(.5*s,s),e.lineTo(.5*s,-2),e.lineTo(-.5*s,-2),e.lineTo(-.5*s,s),e.lineTo(0,.5*s),e.lineTo(.5*s,s)}render(e,i){this.visuals.fill.doit&&(this.visuals.fill.set_vectorize(e,i),this._vee(e,i),e.fill()),this.visuals.line.doit&&(this.visuals.line.set_vectorize(e,i),this._vee(e,i),e.stroke())}_vee(e,i){const s=this.size.get(i);e.beginPath(),e.moveTo(.5*s,s),e.lineTo(0,0),e.lineTo(-.5*s,s),e.lineTo(0,.5*s),e.closePath()}}s.VeeHeadView=z,z.__name__=\"VeeHeadView\";class x extends p{constructor(e){super(e)}}s.VeeHead=x,_=x,x.__name__=\"VeeHead\",_.prototype.default_view=z,_.mixins([h.LineVector,h.FillVector]),_.override({fill_color:\"black\"});class g extends T{render(e,i){if(this.visuals.line.doit){this.visuals.line.set_vectorize(e,i);const s=this.size.get(i);e.beginPath(),e.moveTo(.5*s,0),e.lineTo(-.5*s,0),e.stroke()}}clip(e,i){}}s.TeeHeadView=g,g.__name__=\"TeeHeadView\";class b extends p{constructor(e){super(e)}}s.TeeHead=b,c=b,b.__name__=\"TeeHead\",c.prototype.default_view=g,c.mixins(h.LineVector)},\n", - " function _(n,e,t,i,o){i();const s=n(9);async function c(n,e,t){const i=new n(Object.assign(Object.assign({},t),{model:e}));return i.initialize(),await i.lazy_initialize(),i}t.build_view=async function(n,e={parent:null},t=(n=>n.default_view)){const i=await c(t(n),n,e);return i.connect_signals(),i},t.build_views=async function(n,e,t={parent:null},i=(n=>n.default_view)){const o=(0,s.difference)([...n.keys()],e);for(const e of o)n.get(e).remove(),n.delete(e);const a=[],f=e.filter((e=>!n.has(e)));for(const e of f){const o=await c(i(e),e,t);n.set(e,o),a.push(o)}for(const n of a)n.connect_signals();return a},t.remove_views=function(n){for(const[e,t]of n)t.remove(),n.delete(e)}},\n", - " function _(e,s,_,i,l){i();const t=e(1);var o;const r=e(115),p=(0,t.__importStar)(e(48));class h extends r.UpperLowerView{paint(e){e.beginPath(),e.moveTo(this._lower_sx[0],this._lower_sy[0]);for(let s=0,_=this._lower_sx.length;s<_;s++)e.lineTo(this._lower_sx[s],this._lower_sy[s]);for(let s=this._upper_sx.length-1;s>=0;s--)e.lineTo(this._upper_sx[s],this._upper_sy[s]);e.closePath(),this.visuals.fill.apply(e),e.beginPath(),e.moveTo(this._lower_sx[0],this._lower_sy[0]);for(let s=0,_=this._lower_sx.length;s<_;s++)e.lineTo(this._lower_sx[s],this._lower_sy[s]);this.visuals.line.apply(e),e.beginPath(),e.moveTo(this._upper_sx[0],this._upper_sy[0]);for(let s=0,_=this._upper_sx.length;s<_;s++)e.lineTo(this._upper_sx[s],this._upper_sy[s]);this.visuals.line.apply(e)}}_.BandView=h,h.__name__=\"BandView\";class n extends r.UpperLower{constructor(e){super(e)}}_.Band=n,o=n,n.__name__=\"Band\",o.prototype.default_view=h,o.mixins([p.Line,p.Fill]),o.override({fill_color:\"#fff9ba\",fill_alpha:.4,line_color:\"#cccccc\",line_alpha:.3})},\n", - " function _(e,t,i,s,o){s();const r=e(1);var n;const p=e(69),a=e(20),_=(0,r.__importStar)(e(18));class h extends p.DataAnnotationView{map_data(){const{frame:e}=this.plot_view,t=this.model.dimension,i=this.coordinates.x_scale,s=this.coordinates.y_scale,o=\"height\"==t?s:i,r=\"height\"==t?i:s,n=\"height\"==t?e.bbox.yview:e.bbox.xview,p=\"height\"==t?e.bbox.xview:e.bbox.yview;let a,_,h;a=\"data\"==this.model.properties.lower.units?o.v_compute(this._lower):n.v_compute(this._lower),_=\"data\"==this.model.properties.upper.units?o.v_compute(this._upper):n.v_compute(this._upper),h=\"data\"==this.model.properties.base.units?r.v_compute(this._base):p.v_compute(this._base);const[d,c]=\"height\"==t?[1,0]:[0,1],u=[a,h],l=[_,h];this._lower_sx=u[d],this._lower_sy=u[c],this._upper_sx=l[d],this._upper_sy=l[c]}}i.UpperLowerView=h,h.__name__=\"UpperLowerView\";class d extends _.CoordinateSpec{get dimension(){return\"width\"==this.obj.dimension?\"x\":\"y\"}get units(){var e;return null!==(e=this.spec.units)&&void 0!==e?e:\"data\"}}i.XOrYCoordinateSpec=d,d.__name__=\"XOrYCoordinateSpec\";class c extends p.DataAnnotation{constructor(e){super(e)}}i.UpperLower=c,n=c,c.__name__=\"UpperLower\",n.define((()=>({dimension:[a.Dimension,\"height\"],lower:[d,{field:\"lower\"}],upper:[d,{field:\"upper\"}],base:[d,{field:\"base\"}]})))},\n", - " function _(t,o,i,n,e){n();const s=t(1);var l;const r=t(40),a=(0,s.__importStar)(t(48)),c=t(20),h=t(65);i.EDGE_TOLERANCE=2.5;class b extends r.AnnotationView{constructor(){super(...arguments),this.bbox=new h.BBox}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render()))}_render(){const{left:t,right:o,top:i,bottom:n}=this.model;if(null==t&&null==o&&null==i&&null==n)return;const{frame:e}=this.plot_view,s=this.coordinates.x_scale,l=this.coordinates.y_scale,r=(t,o,i,n,e)=>{let s;return s=null!=t?this.model.screen?t:\"data\"==o?i.compute(t):n.compute(t):e,s};this.bbox=h.BBox.from_rect({left:r(t,this.model.left_units,s,e.bbox.xview,e.bbox.left),right:r(o,this.model.right_units,s,e.bbox.xview,e.bbox.right),top:r(i,this.model.top_units,l,e.bbox.yview,e.bbox.top),bottom:r(n,this.model.bottom_units,l,e.bbox.yview,e.bbox.bottom)}),this._paint_box()}_paint_box(){const{ctx:t}=this.layer;t.save();const{left:o,top:i,width:n,height:e}=this.bbox;t.beginPath(),t.rect(o,i,n,e),this.visuals.fill.apply(t),this.visuals.hatch.apply(t),this.visuals.line.apply(t),t.restore()}interactive_bbox(){const t=this.model.line_width+i.EDGE_TOLERANCE;return this.bbox.grow_by(t)}interactive_hit(t,o){if(null==this.model.in_cursor)return!1;return this.interactive_bbox().contains(t,o)}cursor(t,o){const{left:i,right:n,bottom:e,top:s}=this.bbox;return Math.abs(t-i)<3||Math.abs(t-n)<3?this.model.ew_cursor:Math.abs(o-e)<3||Math.abs(o-s)<3?this.model.ns_cursor:this.bbox.contains(t,o)?this.model.in_cursor:null}}i.BoxAnnotationView=b,b.__name__=\"BoxAnnotationView\";class u extends r.Annotation{constructor(t){super(t)}update({left:t,right:o,top:i,bottom:n}){this.setv({left:t,right:o,top:i,bottom:n,screen:!0})}}i.BoxAnnotation=u,l=u,u.__name__=\"BoxAnnotation\",l.prototype.default_view=b,l.mixins([a.Line,a.Fill,a.Hatch]),l.define((({Number:t,Nullable:o})=>({top:[o(t),null],top_units:[c.SpatialUnits,\"data\"],bottom:[o(t),null],bottom_units:[c.SpatialUnits,\"data\"],left:[o(t),null],left_units:[c.SpatialUnits,\"data\"],right:[o(t),null],right_units:[c.SpatialUnits,\"data\"],render_mode:[c.RenderMode,\"canvas\"]}))),l.internal((({Boolean:t,String:o,Nullable:i})=>({screen:[t,!1],ew_cursor:[i(o),null],ns_cursor:[i(o),null],in_cursor:[i(o),null]}))),l.override({fill_color:\"#fff9ba\",fill_alpha:.4,line_color:\"#cccccc\",line_alpha:.3})},\n", - " function _(t,e,i,o,n){o();const a=t(1);var r;const s=t(40),l=t(118),_=t(126),c=t(127),h=t(130),u=t(168),p=t(131),m=t(192),g=t(132),d=t(173),f=t(172),w=t(196),b=t(204),v=t(206),x=t(133),y=t(20),k=(0,a.__importStar)(t(48)),z=t(9),j=t(207),C=t(208),L=t(211),B=t(123),S=t(11),M=t(113),T=t(65),A=t(8);class O extends s.AnnotationView{get orientation(){return this._orientation}initialize(){super.initialize();const{ticker:t,formatter:e,color_mapper:i}=this.model;this._ticker=\"auto\"!=t?t:(()=>{switch(!0){case i instanceof w.LogColorMapper:return new u.LogTicker;case i instanceof w.ScanningColorMapper:return new u.BinnedTicker({mapper:i});case i instanceof w.CategoricalColorMapper:return new u.CategoricalTicker;default:return new u.BasicTicker}})(),this._formatter=\"auto\"!=e?e:(()=>{switch(!0){case this._ticker instanceof u.LogTicker:return new m.LogTickFormatter;case i instanceof w.CategoricalColorMapper:return new m.CategoricalTickFormatter;default:return new m.BasicTickFormatter}})(),this._major_range=(()=>{if(i instanceof w.CategoricalColorMapper){const{factors:t}=i;return new v.FactorRange({factors:t})}if(i instanceof f.ContinuousColorMapper){const{min:t,max:e}=i.metrics;return new v.Range1d({start:t,end:e})}(0,S.unreachable)()})(),this._major_scale=(()=>{if(i instanceof w.LinearColorMapper)return new b.LinearScale;if(i instanceof w.LogColorMapper)return new b.LogScale;if(i instanceof w.ScanningColorMapper){const{binning:t}=i.metrics;return new b.LinearInterpolationScale({binning:t})}if(i instanceof w.CategoricalColorMapper)return new b.CategoricalScale;(0,S.unreachable)()})(),this._minor_range=new v.Range1d({start:0,end:1}),this._minor_scale=new b.LinearScale;const o=k.attrs_of(this.model,\"major_label_\",k.Text,!0),n=k.attrs_of(this.model,\"major_tick_\",k.Line,!0),a=k.attrs_of(this.model,\"minor_tick_\",k.Line,!0),r=k.attrs_of(this.model,\"title_\",k.Text),s=i instanceof w.CategoricalColorMapper?c.CategoricalAxis:i instanceof w.LogColorMapper?c.LogAxis:c.LinearAxis;this._axis=new s(Object.assign(Object.assign(Object.assign({ticker:this._ticker,formatter:this._formatter,major_tick_in:this.model.major_tick_in,major_tick_out:this.model.major_tick_out,minor_tick_in:this.model.minor_tick_in,minor_tick_out:this.model.minor_tick_out,major_label_standoff:this.model.label_standoff,major_label_overrides:this.model.major_label_overrides,major_label_policy:this.model.major_label_policy,axis_line_color:null},o),n),a));const{title:_}=this.model;_&&(this._title=new l.Title(Object.assign({text:_,standoff:this.model.title_standoff},r)))}async lazy_initialize(){await super.lazy_initialize();const t=this,e={get parent(){return t.parent},get root(){return t.root},get frame(){return t._frame},get canvas_view(){return t.parent.canvas_view},request_layout(){t.parent.request_layout()}};this._axis_view=await(0,M.build_view)(this._axis,{parent:e}),null!=this._title&&(this._title_view=await(0,M.build_view)(this._title,{parent:e}))}remove(){var t;null===(t=this._title_view)||void 0===t||t.remove(),this._axis_view.remove(),super.remove()}connect_signals(){super.connect_signals(),this.connect(this._ticker.change,(()=>this.request_render())),this.connect(this._formatter.change,(()=>this.request_render())),this.connect(this.model.color_mapper.metrics_change,(()=>{const t=this._major_range,e=this._major_scale,{color_mapper:i}=this.model;if(i instanceof f.ContinuousColorMapper&&t instanceof v.Range1d){const{min:e,max:o}=i.metrics;t.setv({start:e,end:o})}if(i instanceof w.ScanningColorMapper&&e instanceof b.LinearInterpolationScale){const{binning:t}=i.metrics;e.binning=t}this._set_canvas_image(),this.plot_view.request_layout()}))}_set_canvas_image(){const{orientation:t}=this,e=(()=>{const{palette:e}=this.model.color_mapper;return\"vertical\"==t?(0,z.reversed)(e):e})(),[i,o]=\"vertical\"==t?[1,e.length]:[e.length,1],n=this._image=document.createElement(\"canvas\");n.width=i,n.height=o;const a=n.getContext(\"2d\"),r=a.getImageData(0,0,i,o),s=new w.LinearColorMapper({palette:e}).rgba_mapper.v_compute((0,z.range)(0,e.length));r.data.set(s),a.putImageData(r,0,0)}update_layout(){const{location:t,width:e,height:i,padding:o,margin:n}=this.model,[a,r]=(()=>{if(!(0,A.isString)(t))return[\"end\",\"start\"];switch(t){case\"top_left\":return[\"start\",\"start\"];case\"top\":case\"top_center\":return[\"start\",\"center\"];case\"top_right\":return[\"start\",\"end\"];case\"bottom_left\":return[\"end\",\"start\"];case\"bottom\":case\"bottom_center\":return[\"end\",\"center\"];case\"bottom_right\":return[\"end\",\"end\"];case\"left\":case\"center_left\":return[\"center\",\"start\"];case\"center\":case\"center_center\":return[\"center\",\"center\"];case\"right\":case\"center_right\":return[\"center\",\"end\"]}})(),s=this._orientation=(()=>{const{orientation:t}=this.model;return\"auto\"==t?null!=this.panel?this.panel.is_horizontal?\"horizontal\":\"vertical\":\"start\"==r||\"end\"==r||\"center\"==r&&\"center\"==a?\"vertical\":\"horizontal\":t})(),l=new C.NodeLayout,c=new C.VStack,h=new C.VStack,u=new C.HStack,p=new C.HStack;l.absolute=!0,c.absolute=!0,h.absolute=!0,u.absolute=!0,p.absolute=!0;const[m,g,d,f]=(()=>\"horizontal\"==s?[this._major_scale,this._minor_scale,this._major_range,this._minor_range]:[this._minor_scale,this._major_scale,this._minor_range,this._major_range])();this._frame=new _.CartesianFrame(m,g,d,f),l.on_resize((t=>this._frame.set_geometry(t)));const w=new L.BorderLayout;this._inner_layout=w,w.absolute=!0,w.center_panel=l,w.top_panel=c,w.bottom_panel=h,w.left_panel=u,w.right_panel=p;const b={left:o,right:o,top:o,bottom:o},v=(()=>{if(null==this.panel){if((0,A.isString)(t))return{left:n,right:n,top:n,bottom:n};{const[e,i]=t;return{left:e,right:n,top:n,bottom:i}}}if(!(0,A.isString)(t)){const[e,i]=t;return w.fixup_geometry=(t,o)=>{const n=t,a=this.layout.bbox,{width:r,height:s}=t;if(t=new T.BBox({left:a.left+e,bottom:a.bottom-i,width:r,height:s}),null!=o){const e=t.left-n.left,i=t.top-n.top,{left:a,top:r,width:s,height:l}=o;o=new T.BBox({left:a+e,top:r+i,width:s,height:l})}return[t,o]},{left:e,right:0,top:0,bottom:i}}w.fixup_geometry=(t,e)=>{const i=t;if(\"horizontal\"==s){const{top:e,width:i,height:o}=t;if(\"end\"==r){const{right:n}=this.layout.bbox;t=new T.BBox({right:n,top:e,width:i,height:o})}else if(\"center\"==r){const{hcenter:n}=this.layout.bbox;t=new T.BBox({hcenter:Math.round(n),top:e,width:i,height:o})}}else{const{left:e,width:i,height:o}=t;if(\"end\"==a){const{bottom:n}=this.layout.bbox;t=new T.BBox({left:e,bottom:n,width:i,height:o})}else if(\"center\"==a){const{vcenter:n}=this.layout.bbox;t=new T.BBox({left:e,vcenter:Math.round(n),width:i,height:o})}}if(null!=e){const o=t.left-i.left,n=t.top-i.top,{left:a,top:r,width:s,height:l}=e;e=new T.BBox({left:a+o,top:r+n,width:s,height:l})}return[t,e]}})();let x,y,k,z;if(w.padding=b,null!=this.panel?(x=\"max\",y=void 0,k=void 0,z=void 0):\"auto\"==(\"horizontal\"==s?e:i)?(x=\"fixed\",y=25*this.model.color_mapper.palette.length,k={percent:.3},z={percent:.8}):(x=\"fit\",y=void 0),\"horizontal\"==s){const t=\"auto\"==e?void 0:e,o=\"auto\"==i?25:i;w.set_sizing({width_policy:x,height_policy:\"min\",width:y,min_width:k,max_width:z,halign:r,valign:a,margin:v}),w.center_panel.set_sizing({width_policy:\"auto\"==e?\"fit\":\"fixed\",height_policy:\"fixed\",width:t,height:o})}else{const t=\"auto\"==e?25:e,o=\"auto\"==i?void 0:i;w.set_sizing({width_policy:\"min\",height_policy:x,height:y,min_height:k,max_height:z,halign:r,valign:a,margin:v}),w.center_panel.set_sizing({width_policy:\"fixed\",height_policy:\"auto\"==i?\"fit\":\"fixed\",width:t,height:o})}c.set_sizing({width_policy:\"fit\",height_policy:\"min\"}),h.set_sizing({width_policy:\"fit\",height_policy:\"min\"}),u.set_sizing({width_policy:\"min\",height_policy:\"fit\"}),p.set_sizing({width_policy:\"min\",height_policy:\"fit\"});const{_title_view:S}=this;null!=S&&(\"horizontal\"==s?(S.panel=new B.Panel(\"above\"),S.update_layout(),c.children.push(S.layout)):(S.panel=new B.Panel(\"left\"),S.update_layout(),u.children.push(S.layout)));const{panel:M}=this,O=null!=M&&s==M.orientation?M.side:\"horizontal\"==s?\"below\":\"right\",R=(()=>{switch(O){case\"above\":return c;case\"below\":return h;case\"left\":return u;case\"right\":return p}})(),{_axis_view:F}=this;if(F.panel=new B.Panel(O),F.update_layout(),R.children.push(F.layout),null!=this.panel){const t=new j.Grid([{layout:w,row:0,col:0}]);t.absolute=!0,\"horizontal\"==s?t.set_sizing({width_policy:\"max\",height_policy:\"min\"}):t.set_sizing({width_policy:\"min\",height_policy:\"max\"}),this.layout=t}else this.layout=this._inner_layout;const{visible:I}=this.model;this.layout.sizing.visible=I,this._set_canvas_image()}_render(){var t;const{ctx:e}=this.layer;e.save(),this._paint_bbox(e,this._inner_layout.bbox),this._paint_image(e,this._inner_layout.center_panel.bbox),null===(t=this._title_view)||void 0===t||t.render(),this._axis_view.render(),e.restore()}_paint_bbox(t,e){const{x:i,y:o}=e;let{width:n,height:a}=e;i+n>=this.parent.canvas_view.bbox.width&&(n-=1),o+a>=this.parent.canvas_view.bbox.height&&(a-=1),t.save(),this.visuals.background_fill.doit&&(this.visuals.background_fill.set_value(t),t.fillRect(i,o,n,a)),this.visuals.border_line.doit&&(this.visuals.border_line.set_value(t),t.strokeRect(i,o,n,a)),t.restore()}_paint_image(t,e){const{x:i,y:o,width:n,height:a}=e;t.save(),t.setImageSmoothingEnabled(!1),t.globalAlpha=this.model.scale_alpha,t.drawImage(this._image,i,o,n,a),this.visuals.bar_line.doit&&(this.visuals.bar_line.set_value(t),t.strokeRect(i,o,n,a)),t.restore()}serializable_state(){const t=super.serializable_state(),{children:e=[]}=t,i=(0,a.__rest)(t,[\"children\"]);return null!=this._title_view&&e.push(this._title_view.serializable_state()),e.push(this._axis_view.serializable_state()),Object.assign(Object.assign({},i),{children:e})}}i.ColorBarView=O,O.__name__=\"ColorBarView\";class R extends s.Annotation{constructor(t){super(t)}}i.ColorBar=R,r=R,R.__name__=\"ColorBar\",r.prototype.default_view=O,r.mixins([[\"major_label_\",k.Text],[\"title_\",k.Text],[\"major_tick_\",k.Line],[\"minor_tick_\",k.Line],[\"border_\",k.Line],[\"bar_\",k.Line],[\"background_\",k.Fill]]),r.define((({Alpha:t,Number:e,String:i,Tuple:o,Dict:n,Or:a,Ref:r,Auto:s,Nullable:l})=>({location:[a(y.Anchor,o(e,e)),\"top_right\"],orientation:[a(y.Orientation,s),\"auto\"],title:[l(i),null],title_standoff:[e,2],width:[a(e,s),\"auto\"],height:[a(e,s),\"auto\"],scale_alpha:[t,1],ticker:[a(r(h.Ticker),s),\"auto\"],formatter:[a(r(p.TickFormatter),s),\"auto\"],major_label_overrides:[n(a(i,r(x.BaseText))),{}],major_label_policy:[r(g.LabelingPolicy),()=>new g.NoOverlap],color_mapper:[r(d.ColorMapper)],label_standoff:[e,5],margin:[e,30],padding:[e,10],major_tick_in:[e,5],major_tick_out:[e,0],minor_tick_in:[e,0],minor_tick_out:[e,0]}))),r.override({background_fill_color:\"#ffffff\",background_fill_alpha:.95,bar_line_color:null,border_line_color:null,major_label_text_font_size:\"11px\",major_tick_line_color:\"#ffffff\",minor_tick_line_color:null,title_text_font_size:\"13px\",title_text_font_style:\"italic\"})},\n", - " function _(t,e,i,s,l){s();const o=t(1);var a;const n=t(119),r=t(20),c=t(120),h=(0,o.__importStar)(t(48));class _ extends n.TextAnnotationView{_get_location(){const t=this.model.offset,e=this.model.standoff/2;let i,s;const{bbox:l}=this.layout;switch(this.panel.side){case\"above\":case\"below\":switch(this.model.vertical_align){case\"top\":s=l.top+e;break;case\"middle\":s=l.vcenter;break;case\"bottom\":s=l.bottom-e}switch(this.model.align){case\"left\":i=l.left+t;break;case\"center\":i=l.hcenter;break;case\"right\":i=l.right-t}break;case\"left\":switch(this.model.vertical_align){case\"top\":i=l.left+e;break;case\"middle\":i=l.hcenter;break;case\"bottom\":i=l.right-e}switch(this.model.align){case\"left\":s=l.bottom-t;break;case\"center\":s=l.vcenter;break;case\"right\":s=l.top+t}break;case\"right\":switch(this.model.vertical_align){case\"top\":i=l.right-e;break;case\"middle\":i=l.hcenter;break;case\"bottom\":i=l.left+e}switch(this.model.align){case\"left\":s=l.top+t;break;case\"center\":s=l.vcenter;break;case\"right\":s=l.bottom-t}}return[i,s]}_render(){const{text:t}=this.model;if(null==t||0==t.length)return;this.model.text_baseline=this.model.vertical_align,this.model.text_align=this.model.align;const[e,i]=this._get_location(),s=this.panel.get_label_angle_heuristic(\"parallel\");(\"canvas\"==this.model.render_mode?this._canvas_text.bind(this):this._css_text.bind(this))(this.layer.ctx,t,e,i,s)}_get_size(){const{text:t}=this.model,e=new c.TextBox({text:t});e.visuals=this.visuals.text.values();const{width:i,height:s}=e.size();return{width:i,height:0==s?0:2+s+this.model.standoff}}}i.TitleView=_,_.__name__=\"TitleView\";class d extends n.TextAnnotation{constructor(t){super(t)}}i.Title=d,a=d,d.__name__=\"Title\",a.prototype.default_view=_,a.mixins([h.Text,[\"border_\",h.Line],[\"background_\",h.Fill]]),a.define((({Number:t,String:e})=>({text:[e,\"\"],vertical_align:[r.VerticalAlign,\"bottom\"],align:[r.TextAlign,\"left\"],offset:[t,0],standoff:[t,10]}))),a.prototype._props.text_align.options.internal=!0,a.prototype._props.text_baseline.options.internal=!0,a.override({text_font_size:\"13px\",text_font_style:\"bold\",text_line_height:1,background_fill_color:null,border_line_color:null})},\n", - " function _(e,t,s,i,l){var n;i();const o=e(40),a=e(43),r=e(20),d=e(120),u=e(123),c=e(11);class h extends o.AnnotationView{update_layout(){const{panel:e}=this;this.layout=null!=e?new u.SideLayout(e,(()=>this.get_size()),!0):void 0}initialize(){super.initialize(),\"css\"==this.model.render_mode&&(this.el=(0,a.div)(),this.plot_view.canvas_view.add_overlay(this.el))}remove(){null!=this.el&&(0,a.remove)(this.el),super.remove()}connect_signals(){super.connect_signals(),\"css\"==this.model.render_mode?this.connect(this.model.change,(()=>this.render())):this.connect(this.model.change,(()=>this.request_render()))}render(){this.model.visible||\"css\"!=this.model.render_mode||(0,a.undisplay)(this.el),super.render()}_canvas_text(e,t,s,i,l){const n=new d.TextBox({text:t});n.angle=l,n.position={sx:s,sy:i},n.visuals=this.visuals.text.values();const{background_fill:o,border_line:a}=this.visuals;if(o.doit||a.doit){const{p0:t,p1:s,p2:i,p3:l}=n.rect();e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(s.x,s.y),e.lineTo(i.x,i.y),e.lineTo(l.x,l.y),e.closePath(),this.visuals.background_fill.apply(e),this.visuals.border_line.apply(e)}this.visuals.text.doit&&n.paint(e)}_css_text(e,t,s,i,l){const{el:n}=this;(0,c.assert)(null!=n),(0,a.undisplay)(n),n.textContent=t,this.visuals.text.set_value(e),n.style.position=\"absolute\",n.style.left=`${s}px`,n.style.top=`${i}px`,n.style.color=e.fillStyle,n.style.font=e.font,n.style.lineHeight=\"normal\",n.style.whiteSpace=\"pre\";const[o,r]=(()=>{switch(this.visuals.text.text_align.get_value()){case\"left\":return[\"left\",\"0%\"];case\"center\":return[\"center\",\"-50%\"];case\"right\":return[\"right\",\"-100%\"]}})(),[d,u]=(()=>{switch(this.visuals.text.text_baseline.get_value()){case\"top\":return[\"top\",\"0%\"];case\"middle\":return[\"center\",\"-50%\"];case\"bottom\":return[\"bottom\",\"-100%\"];default:return[\"center\",\"-50%\"]}})();let h=`translate(${r}, ${u})`;l&&(h+=`rotate(${l}rad)`),n.style.transformOrigin=`${o} ${d}`,n.style.transform=h,this.layout,this.visuals.background_fill.doit&&(this.visuals.background_fill.set_value(e),n.style.backgroundColor=e.fillStyle),this.visuals.border_line.doit&&(this.visuals.border_line.set_value(e),n.style.borderStyle=e.lineDash.length<2?\"solid\":\"dashed\",n.style.borderWidth=`${e.lineWidth}px`,n.style.borderColor=e.strokeStyle),(0,a.display)(n)}}s.TextAnnotationView=h,h.__name__=\"TextAnnotationView\";class _ extends o.Annotation{constructor(e){super(e)}}s.TextAnnotation=_,n=_,_.__name__=\"TextAnnotation\",n.define((()=>({render_mode:[r.RenderMode,\"canvas\"]})))},\n", - " function _(t,e,s,i,n){i();const h=t(65),o=t(121),r=t(9),a=t(8),c=t(122),_=t(22);s.text_width=(()=>{const t=document.createElement(\"canvas\").getContext(\"2d\");let e=\"\";return(s,i)=>(i!=e&&(e=i,t.font=i),t.measureText(s).width)})();class l{constructor(){this._position={sx:0,sy:0},this.font_size_scale=1,this.align=\"left\",this._base_font_size=13,this._x_anchor=\"left\",this._y_anchor=\"center\"}set base_font_size(t){null!=t&&(this._base_font_size=t)}get base_font_size(){return this._base_font_size}set position(t){this._position=t}get position(){return this._position}infer_text_height(){return\"ascent_descent\"}bbox(){const{p0:t,p1:e,p2:s,p3:i}=this.rect(),n=Math.min(t.x,e.x,s.x,i.x),o=Math.min(t.y,e.y,s.y,i.y),r=Math.max(t.x,e.x,s.x,i.x),a=Math.max(t.y,e.y,s.y,i.y);return new h.BBox({left:n,right:r,top:o,bottom:a})}size(){const{width:t,height:e}=this._size(),{angle:s}=this;if(s){const i=Math.cos(Math.abs(s)),n=Math.sin(Math.abs(s));return{width:Math.abs(t*i+e*n),height:Math.abs(t*n+e*i)}}return{width:t,height:e}}rect(){const t=this._rect(),{angle:e}=this;if(e){const{sx:s,sy:i}=this.position,n=new c.AffineTransform;return n.translate(s,i),n.rotate(e),n.translate(-s,-i),n.apply_rect(t)}return t}paint_rect(t){const{p0:e,p1:s,p2:i,p3:n}=this.rect();t.save(),t.strokeStyle=\"red\",t.lineWidth=1,t.beginPath();const{round:h}=Math;t.moveTo(h(e.x),h(e.y)),t.lineTo(h(s.x),h(s.y)),t.lineTo(h(i.x),h(i.y)),t.lineTo(h(n.x),h(n.y)),t.closePath(),t.stroke(),t.restore()}paint_bbox(t){const{x:e,y:s,width:i,height:n}=this.bbox();t.save(),t.strokeStyle=\"blue\",t.lineWidth=1,t.beginPath();const{round:h}=Math;t.moveTo(h(e),h(s)),t.lineTo(h(e),h(s+n)),t.lineTo(h(e+i),h(s+n)),t.lineTo(h(e+i),h(s)),t.closePath(),t.stroke(),t.restore()}}s.GraphicsBox=l,l.__name__=\"GraphicsBox\";class x extends l{constructor({text:t}){super(),this.text=t}set visuals(t){const e=t.color,s=t.alpha,i=t.font_style;let n=t.font_size;const h=t.font,{font_size_scale:r,base_font_size:a}=this,c=(0,o.parse_css_font_size)(n);if(null!=c){let{value:t,unit:e}=c;t*=r,\"em\"==e&&a&&(t*=a,e=\"px\"),n=`${t}${e}`}const l=`${i} ${n} ${h}`;this.font=l,this.color=(0,_.color2css)(e,s),this.line_height=t.line_height;const x=t.align;this._x_anchor=x;const u=t.baseline;this._y_anchor=(()=>{switch(u){case\"top\":return\"top\";case\"middle\":return\"center\";case\"bottom\":return\"bottom\";default:return\"baseline\"}})()}infer_text_height(){if(this.text.includes(\"\\n\"))return\"ascent_descent\";{function t(t){for(const e of new Set(t))if(!(\"0\"<=e&&e<=\"9\"))switch(e){case\",\":case\".\":case\"+\":case\"-\":case\"\\u2212\":case\"e\":continue;default:return!1}return!0}return t(this.text)?\"cap\":\"ascent_descent\"}}_text_line(t){var e;const s=null!==(e=this.text_height_metric)&&void 0!==e?e:this.infer_text_height(),i=(()=>{switch(s){case\"x\":case\"x_descent\":return t.x_height;case\"cap\":case\"cap_descent\":return t.cap_height;case\"ascent\":case\"ascent_descent\":return t.ascent}})(),n=(()=>{switch(s){case\"x\":case\"cap\":case\"ascent\":return 0;case\"x_descent\":case\"cap_descent\":case\"ascent_descent\":return t.descent}})();return{height:i+n,ascent:i,descent:n}}get nlines(){return this.text.split(\"\\n\").length}_size(){var t,e;const{font:i}=this,n=(0,o.font_metrics)(i),h=(this.line_height-1)*n.height,a=\"\"==this.text,c=this.text.split(\"\\n\"),_=c.length,l=c.map((t=>(0,s.text_width)(t,i))),x=this._text_line(n).height*_,u=\"%\"==(null===(t=this.width)||void 0===t?void 0:t.unit)?this.width.value:1,p=\"%\"==(null===(e=this.height)||void 0===e?void 0:e.unit)?this.height.value:1;return{width:(0,r.max)(l)*u,height:a?0:(x+h*(_-1))*p,metrics:n}}_computed_position(t,e,s){const{width:i,height:n}=t,{sx:h,sy:o,x_anchor:r=this._x_anchor,y_anchor:c=this._y_anchor}=this.position;return{x:h-(()=>{if((0,a.isNumber)(r))return r*i;switch(r){case\"left\":return 0;case\"center\":return.5*i;case\"right\":return i}})(),y:o-(()=>{var t;if((0,a.isNumber)(c))return c*n;switch(c){case\"top\":return 0;case\"center\":return.5*n;case\"bottom\":return n;case\"baseline\":if(1!=s)return.5*n;switch(null!==(t=this.text_height_metric)&&void 0!==t?t:this.infer_text_height()){case\"x\":case\"x_descent\":return e.x_height;case\"cap\":case\"cap_descent\":return e.cap_height;case\"ascent\":case\"ascent_descent\":return e.ascent}}})()}}_rect(){const{width:t,height:e,metrics:s}=this._size(),i=this.text.split(\"\\n\").length,{x:n,y:o}=this._computed_position({width:t,height:e},s,i);return new h.BBox({x:n,y:o,width:t,height:e}).rect}paint(t){var e,i;const{font:n}=this,h=(0,o.font_metrics)(n),a=(this.line_height-1)*h.height,c=this.text.split(\"\\n\"),_=c.length,l=c.map((t=>(0,s.text_width)(t,n))),x=this._text_line(h),u=x.height*_,p=\"%\"==(null===(e=this.width)||void 0===e?void 0:e.unit)?this.width.value:1,f=\"%\"==(null===(i=this.height)||void 0===i?void 0:i.unit)?this.height.value:1,g=(0,r.max)(l)*p,d=(u+a*(_-1))*f;t.save(),t.fillStyle=this.color,t.font=this.font,t.textAlign=\"left\",t.textBaseline=\"alphabetic\";const{sx:b,sy:m}=this.position,{align:y}=this,{angle:w}=this;w&&(t.translate(b,m),t.rotate(w),t.translate(-b,-m));let{x:v,y:z}=this._computed_position({width:g,height:d},h,_);if(\"justify\"==y)for(let e=0;e<_;e++){let i=v;const h=c[e].split(\" \"),o=h.length,_=h.map((t=>(0,s.text_width)(t,n))),l=(g-(0,r.sum)(_))/(o-1);for(let e=0;e{switch(y){case\"left\":return 0;case\"center\":return.5*(g-l[e]);case\"right\":return g-l[e]}})();t.fillStyle=this.color,t.fillText(c[e],s,z+x.ascent),z+=x.height+a}t.restore()}}s.TextBox=x,x.__name__=\"TextBox\";class u extends l{constructor(t,e){super(),this.base=t,this.expo=e}get children(){return[this.base,this.expo]}set base_font_size(t){super.base_font_size=t,this.base.base_font_size=t,this.expo.base_font_size=t}set position(t){this._position=t;const e=this.base.size(),s=this.expo.size(),i=this._shift_scale()*e.height,n=Math.max(e.height,i+s.height);this.base.position={sx:0,x_anchor:\"left\",sy:n,y_anchor:\"bottom\"},this.expo.position={sx:e.width,x_anchor:\"left\",sy:i,y_anchor:\"bottom\"}}get position(){return this._position}set visuals(t){this.expo.font_size_scale=.7,this.base.visuals=t,this.expo.visuals=t}_shift_scale(){if(this.base instanceof x&&1==this.base.nlines){const{x_height:t,cap_height:e}=(0,o.font_metrics)(this.base.font);return t/e}return 2/3}infer_text_height(){return this.base.infer_text_height()}_rect(){const t=this.base.bbox(),e=this.expo.bbox(),s=t.union(e),{x:i,y:n}=this._computed_position();return s.translate(i,n).rect}_size(){const t=this.base.size(),e=this.expo.size();return{width:t.width+e.width,height:Math.max(t.height,this._shift_scale()*t.height+e.height)}}paint(t){t.save();const{angle:e}=this;if(e){const{sx:s,sy:i}=this.position;t.translate(s,i),t.rotate(e),t.translate(-s,-i)}const{x:s,y:i}=this._computed_position();t.translate(s,i),this.base.paint(t),this.expo.paint(t),t.restore()}paint_bbox(t){super.paint_bbox(t);const{x:e,y:s}=this._computed_position();t.save(),t.translate(e,s);for(const e of this.children)e.paint_bbox(t);t.restore()}_computed_position(){const{width:t,height:e}=this._size(),{sx:s,sy:i,x_anchor:n=this._x_anchor,y_anchor:h=this._y_anchor}=this.position;return{x:s-(()=>{if((0,a.isNumber)(n))return n*t;switch(n){case\"left\":return 0;case\"center\":return.5*t;case\"right\":return t}})(),y:i-(()=>{if((0,a.isNumber)(h))return h*e;switch(h){case\"top\":return 0;case\"center\":return.5*e;case\"bottom\":return e;case\"baseline\":return.5*e}})()}}}s.BaseExpo=u,u.__name__=\"BaseExpo\";class p{constructor(t){this.items=t}set base_font_size(t){for(const e of this.items)e.base_font_size=t}get length(){return this.items.length}set visuals(t){for(const e of this.items)e.visuals=t;const e={x:0,cap:1,ascent:2,x_descent:3,cap_descent:4,ascent_descent:5},s=(0,r.max_by)(this.items.map((t=>t.infer_text_height())),(t=>e[t]));for(const t of this.items)t.text_height_metric=s}set angle(t){for(const e of this.items)e.angle=t}max_size(){let t=0,e=0;for(const s of this.items){const i=s.size();t=Math.max(t,i.width),e=Math.max(e,i.height)}return{width:t,height:e}}}s.GraphicsBoxes=p,p.__name__=\"GraphicsBoxes\"},\n", - " function _(t,e,n,r,l){r();const a=t(11),c=(()=>{try{return\"undefined\"!=typeof OffscreenCanvas&&null!=new OffscreenCanvas(0,0).getContext(\"2d\")}catch(t){return!1}})()?(t,e)=>new OffscreenCanvas(t,e):(t,e)=>{const n=document.createElement(\"canvas\");return n.width=t,n.height=e,n},o=(()=>{const t=c(0,0).getContext(\"2d\");return e=>{t.font=e;const n=t.measureText(\"M\"),r=t.measureText(\"x\"),l=t.measureText(\"\\xc5\\u015ag|\"),c=l.fontBoundingBoxAscent,o=l.fontBoundingBoxDescent;if(null!=c&&null!=o)return{height:c+o,ascent:c,descent:o,cap_height:n.actualBoundingBoxAscent,x_height:r.actualBoundingBoxAscent};const s=l.actualBoundingBoxAscent,u=l.actualBoundingBoxDescent;if(null!=s&&null!=u)return{height:s+u,ascent:s,descent:u,cap_height:n.actualBoundingBoxAscent,x_height:r.actualBoundingBoxAscent};(0,a.unreachable)()}})(),s=(()=>{const t=c(0,0).getContext(\"2d\");return(e,n)=>{t.font=n;const r=t.measureText(e),l=r.actualBoundingBoxAscent,c=r.actualBoundingBoxDescent;if(null!=l&&null!=c)return{width:r.width,height:l+c,ascent:l,descent:c};(0,a.unreachable)()}})(),u=(()=>{const t=document.createElement(\"canvas\"),e=t.getContext(\"2d\");let n=-1,r=-1;return(l,a=1)=>{e.font=l;const{width:c}=e.measureText(\"M\"),o=c*a,s=Math.ceil(o),u=Math.ceil(2*o),i=Math.ceil(1.5*o);n{let e=0;for(let n=0;n<=i;n++)for(let r=0;r{let e=t.length-4;for(let n=u;n>=i;n--)for(let r=0;r{const t=document.createElement(\"canvas\"),e=t.getContext(\"2d\");let n=-1,r=-1;return(l,a,c=1)=>{e.font=a;const{width:o}=e.measureText(\"M\"),s=o*c,u=Math.ceil(s),i=Math.ceil(2*s),f=Math.ceil(1.5*s);(n{let e=0;for(let n=0;n<=f;n++)for(let r=0;r{let e=t.length-4;for(let n=i;n>=f;n--)for(let r=0;r{try{return o(\"normal 10px sans-serif\"),o}catch(t){return u}})(),h=(()=>{try{return s(\"A\",\"normal 10px sans-serif\"),s}catch(t){return i}})(),g=new Map;function d(t){let e=g.get(t);return null==e&&(e={font:f(t),glyphs:new Map},g.set(t,e)),e.font}n.font_metrics=d,n.glyph_metrics=function(t,e){let n=g.get(e);null==n&&(d(e),n=g.get(e));let r=n.glyphs.get(t);return null==r&&(r=h(t,e),n.glyphs.set(t,r)),r},n.parse_css_font_size=function(t){const e=t.match(/^\\s*(\\d+(\\.\\d+)?)(\\w+)\\s*$/);if(null!=e){const[,t,,n]=e,r=Number(t);if(isFinite(r))return{value:r,unit:n}}return null}},\n", - " function _(t,s,r,n,i){n();const{sin:e,cos:a}=Math;class h{constructor(t=1,s=0,r=0,n=1,i=0,e=0){this.a=t,this.b=s,this.c=r,this.d=n,this.e=i,this.f=e}toString(){const{a:t,b:s,c:r,d:n,e:i,f:e}=this;return`matrix(${t}, ${s}, ${r}, ${n}, ${i}, ${e})`}static from_DOMMatrix(t){const{a:s,b:r,c:n,d:i,e,f:a}=t;return new h(s,r,n,i,e,a)}to_DOMMatrix(){const{a:t,b:s,c:r,d:n,e:i,f:e}=this;return new DOMMatrix([t,s,r,n,i,e])}clone(){const{a:t,b:s,c:r,d:n,e:i,f:e}=this;return new h(t,s,r,n,i,e)}get is_identity(){const{a:t,b:s,c:r,d:n,e:i,f:e}=this;return 1==t&&0==s&&0==r&&1==n&&0==i&&0==e}apply_point(t){const[s,r]=this.apply(t.x,t.y);return{x:s,y:r}}apply_rect(t){return{p0:this.apply_point(t.p0),p1:this.apply_point(t.p1),p2:this.apply_point(t.p2),p3:this.apply_point(t.p3)}}apply(t,s){const{a:r,b:n,c:i,d:e,e:a,f:h}=this;return[r*t+i*s+a,n*t+e*s+h]}iv_apply(t,s){const{a:r,b:n,c:i,d:e,e:a,f:h}=this,c=t.length;for(let o=0;o{const h={max:4,fit:3,min:2,fixed:1};return h[i]>h[t]};if(\"fixed\"!=n&&\"fixed\"!=s)if(n==s){const n=t,s=_(t/e),r=_(h*e),g=h;Math.abs(i.width-n)+Math.abs(i.height-s)<=Math.abs(i.width-r)+Math.abs(i.height-g)?(t=n,h=s):(t=r,h=g)}else r(n,s)?h=_(t/e):t=_(h*e);else\"fixed\"==n?h=_(t/e):\"fixed\"==s&&(t=_(h*e))}return{width:t,height:h}}measure(i){if(!this.sizing.visible)return{width:0,height:0};const t=i=>\"fixed\"==this.sizing.width_policy&&null!=this.sizing.width?this.sizing.width:i,h=i=>\"fixed\"==this.sizing.height_policy&&null!=this.sizing.height?this.sizing.height:i,e=new s.Sizeable(i).shrink_by(this.sizing.margin).map(t,h),n=this._measure(e),r=this.clip_size(n,e),g=t(r.width),l=h(r.height),a=this.apply_aspect(e,{width:g,height:l});return Object.assign(Object.assign({},n),a)}compute(i={}){const t=this.measure({width:null!=i.width&&this.is_width_expanding()?i.width:1/0,height:null!=i.height&&this.is_height_expanding()?i.height:1/0}),{width:h,height:e}=t,n=new r.BBox({left:0,top:0,width:h,height:e});let s;if(null!=t.inner){const{left:i,top:n,right:g,bottom:l}=t.inner;s=new r.BBox({left:i,top:n,right:h-g,bottom:e-l})}this.set_geometry(n,s)}get xview(){return this.bbox.xview}get yview(){return this.bbox.yview}clip_size(i,t){function h(i,t,h,e){return null==h?h=0:(0,g.isNumber)(h)||(h=Math.round(h.percent*t)),null==e?e=1/0:(0,g.isNumber)(e)||(e=Math.round(e.percent*t)),a(h,l(i,e))}return{width:h(i.width,t.width,this.sizing.min_width,this.sizing.max_width),height:h(i.height,t.height,this.sizing.min_height,this.sizing.max_height)}}has_size_changed(){const{_dirty:i}=this;return this._dirty=!1,i}}h.Layoutable=o,o.__name__=\"Layoutable\";class d extends o{_measure(i){const{width_policy:t,height_policy:h}=this.sizing;return{width:(()=>{const{width:h}=this.sizing;if(i.width==1/0)return null!=h?h:0;switch(t){case\"fixed\":return null!=h?h:0;case\"min\":return null!=h?l(i.width,h):0;case\"fit\":return null!=h?l(i.width,h):i.width;case\"max\":return null!=h?a(i.width,h):i.width}})(),height:(()=>{const{height:t}=this.sizing;if(i.height==1/0)return null!=t?t:0;switch(h){case\"fixed\":return null!=t?t:0;case\"min\":return null!=t?l(i.height,t):0;case\"fit\":return null!=t?l(i.height,t):i.height;case\"max\":return null!=t?a(i.height,t):i.height}})()}}}h.LayoutItem=d,d.__name__=\"LayoutItem\";class u extends o{_measure(i){const t=this._content_size(),h=i.bounded_to(this.sizing.size).bounded_to(t);return{width:(()=>{switch(this.sizing.width_policy){case\"fixed\":return null!=this.sizing.width?this.sizing.width:t.width;case\"min\":return t.width;case\"fit\":return h.width;case\"max\":return Math.max(t.width,h.width)}})(),height:(()=>{switch(this.sizing.height_policy){case\"fixed\":return null!=this.sizing.height?this.sizing.height:t.height;case\"min\":return t.height;case\"fit\":return h.height;case\"max\":return Math.max(t.height,h.height)}})()}}}h.ContentLayoutable=u,u.__name__=\"ContentLayoutable\"},\n", - " function _(e,t,s,a,_){a();const r=e(62),n=e(61),g=e(58),i=e(63),c=e(67),h=e(65),l=e(13),o=e(11);class x{constructor(e,t,s,a,_={},r={},n={},g={}){this.in_x_scale=e,this.in_y_scale=t,this.x_range=s,this.y_range=a,this.extra_x_ranges=_,this.extra_y_ranges=r,this.extra_x_scales=n,this.extra_y_scales=g,this._bbox=new h.BBox,(0,o.assert)(null==e.source_range&&null==e.target_range),(0,o.assert)(null==t.source_range&&null==t.target_range),this._configure_scales()}get bbox(){return this._bbox}_get_ranges(e,t){return new Map((0,l.entries)(Object.assign(Object.assign({},t),{default:e})))}_get_scales(e,t,s,a){var _;const g=new Map((0,l.entries)(Object.assign(Object.assign({},t),{default:e}))),h=new Map;for(const[t,l]of s){if(l instanceof c.FactorRange!=e instanceof r.CategoricalScale)throw new Error(`Range ${l.type} is incompatible is Scale ${e.type}`);e instanceof n.LogScale&&l instanceof i.DataRange1d&&(l.scale_hint=\"log\");const s=(null!==(_=g.get(t))&&void 0!==_?_:e).clone();s.setv({source_range:l,target_range:a}),h.set(t,s)}return h}_configure_frame_ranges(){const{bbox:e}=this;this._x_target=new g.Range1d({start:e.left,end:e.right}),this._y_target=new g.Range1d({start:e.bottom,end:e.top})}_configure_scales(){this._configure_frame_ranges(),this._x_ranges=this._get_ranges(this.x_range,this.extra_x_ranges),this._y_ranges=this._get_ranges(this.y_range,this.extra_y_ranges),this._x_scales=this._get_scales(this.in_x_scale,this.extra_x_scales,this._x_ranges,this._x_target),this._y_scales=this._get_scales(this.in_y_scale,this.extra_y_scales,this._y_ranges,this._y_target)}_update_scales(){this._configure_frame_ranges();for(const[,e]of this._x_scales)e.target_range=this._x_target;for(const[,e]of this._y_scales)e.target_range=this._y_target}set_geometry(e){this._bbox=e,this._update_scales()}get x_target(){return this._x_target}get y_target(){return this._y_target}get x_ranges(){return this._x_ranges}get y_ranges(){return this._y_ranges}get x_scales(){return this._x_scales}get y_scales(){return this._y_scales}get x_scale(){return this._x_scales.get(\"default\")}get y_scale(){return this._y_scales.get(\"default\")}get xscales(){return(0,l.to_object)(this.x_scales)}get yscales(){return(0,l.to_object)(this.y_scales)}}s.CartesianFrame=x,x.__name__=\"CartesianFrame\"},\n", - " function _(i,s,x,A,o){A(),o(\"Axis\",i(128).Axis),o(\"CategoricalAxis\",i(140).CategoricalAxis),o(\"ContinuousAxis\",i(143).ContinuousAxis),o(\"DatetimeAxis\",i(144).DatetimeAxis),o(\"LinearAxis\",i(145).LinearAxis),o(\"LogAxis\",i(162).LogAxis),o(\"MercatorAxis\",i(165).MercatorAxis)},\n", - " function _(t,e,i,s,a){s();const o=t(1);var l;const n=t(129),_=t(130),r=t(131),h=t(132),c=(0,o.__importStar)(t(48)),b=t(20),u=t(24),m=t(123),d=t(9),x=t(13),f=t(8),g=t(120),p=t(67),v=t(133),w=t(113),j=t(11),k=t(8),y=t(134),{abs:z}=Math;class M extends n.GuideRendererView{constructor(){super(...arguments),this._axis_label_view=null,this._major_label_views=new Map}async lazy_initialize(){await super.lazy_initialize(),await this._init_axis_label(),await this._init_major_labels()}async _init_axis_label(){const{axis_label:t}=this.model;if(null!=t){const e=(0,k.isString)(t)?(0,y.parse_delimited_string)(t):t;this._axis_label_view=await(0,w.build_view)(e,{parent:this})}else this._axis_label_view=null}async _init_major_labels(){const{major_label_overrides:t}=this.model;for(const[e,i]of(0,x.entries)(t)){const t=(0,k.isString)(i)?(0,y.parse_delimited_string)(i):i;this._major_label_views.set(e,await(0,w.build_view)(t,{parent:this}))}}update_layout(){this.layout=new m.SideLayout(this.panel,(()=>this.get_size()),!0),this.layout.on_resize((()=>this._coordinates=void 0))}get_size(){const{visible:t,fixed_location:e}=this.model;if(t&&null==e&&this.is_renderable){const{extents:t}=this;return{width:0,height:Math.round(t.tick+t.tick_label+t.axis_label)}}return{width:0,height:0}}get is_renderable(){const[t,e]=this.ranges;return t.is_valid&&e.is_valid}_render(){var t;if(!this.is_renderable)return;const{tick_coords:e,extents:i}=this,s=this.layer.ctx;s.save(),this._draw_rule(s,i),this._draw_major_ticks(s,i,e),this._draw_minor_ticks(s,i,e),this._draw_major_labels(s,i,e),this._draw_axis_label(s,i,e),null===(t=this._paint)||void 0===t||t.call(this,s,i,e),s.restore()}connect_signals(){super.connect_signals();const{axis_label:t,major_label_overrides:e}=this.model.properties;this.on_change(t,(async()=>{var t;null===(t=this._axis_label_view)||void 0===t||t.remove(),await this._init_axis_label()})),this.on_change(e,(async()=>{for(const t of this._major_label_views.values())t.remove();await this._init_major_labels()})),this.connect(this.model.change,(()=>this.plot_view.request_layout()))}get needs_clip(){return null!=this.model.fixed_location}_draw_rule(t,e){if(!this.visuals.axis_line.doit)return;const[i,s]=this.rule_coords,[a,o]=this.coordinates.map_to_screen(i,s),[l,n]=this.normals,[_,r]=this.offsets;this.visuals.axis_line.set_value(t),t.beginPath();for(let e=0;e0?s+i+3:0}_draw_axis_label(t,e,i){if(null==this._axis_label_view||null!=this.model.fixed_location)return;const[s,a]=(()=>{const{bbox:t}=this.layout;switch(this.panel.side){case\"above\":return[t.hcenter,t.bottom];case\"below\":return[t.hcenter,t.top];case\"left\":return[t.right,t.vcenter];case\"right\":return[t.left,t.vcenter]}})(),[o,l]=this.normals,n=e.tick+e.tick_label+this.model.axis_label_standoff,{vertical_align:_,align:r}=this.panel.get_label_text_heuristics(\"parallel\"),h={sx:s+o*n,sy:a+l*n,x_anchor:r,y_anchor:_},c=this._axis_label_view.graphics();c.visuals=this.visuals.axis_label_text.values(),c.angle=this.panel.get_label_angle_heuristic(\"parallel\"),this.plot_view.base_font_size&&(c.base_font_size=this.plot_view.base_font_size),c.position=h,c.align=r,c.paint(t)}_draw_ticks(t,e,i,s,a){if(!a.doit)return;const[o,l]=e,[n,_]=this.coordinates.map_to_screen(o,l),[r,h]=this.normals,[c,b]=this.offsets,[u,m]=[r*(c-i),h*(b-i)],[d,x]=[r*(c+s),h*(b+s)];a.set_value(t),t.beginPath();for(let e=0;et.bbox())),M=(()=>{const[t]=this.ranges;return t.is_reversed?0==this.dimension?(t,e)=>z[t].left-z[e].right:(t,e)=>z[e].top-z[t].bottom:0==this.dimension?(t,e)=>z[e].left-z[t].right:(t,e)=>z[t].top-z[e].bottom})(),{major_label_policy:O}=this.model,T=O.filter(k,z,M),A=[...T.ones()];if(0!=A.length){const t=this.parent.canvas_view.bbox,e=e=>{const i=z[e];if(i.left<0){const t=-i.left,{position:s}=y[e];y[e].position=Object.assign(Object.assign({},s),{sx:s.sx+t})}else if(i.right>t.width){const s=i.right-t.width,{position:a}=y[e];y[e].position=Object.assign(Object.assign({},a),{sx:a.sx-s})}},i=e=>{const i=z[e];if(i.top<0){const t=-i.top,{position:s}=y[e];y[e].position=Object.assign(Object.assign({},s),{sy:s.sy+t})}else if(i.bottom>t.height){const s=i.bottom-t.height,{position:a}=y[e];y[e].position=Object.assign(Object.assign({},a),{sy:a.sy-s})}},s=A[0],a=A[A.length-1];0==this.dimension?(e(s),e(a)):(i(s),i(a))}for(const e of T){y[e].paint(t)}}_tick_extent(){return this.model.major_tick_out}_tick_label_extents(){const t=this.tick_coords.major,e=this.compute_labels(t[this.dimension]),i=this.model.major_label_orientation,s=this.model.major_label_standoff,a=this.visuals.major_label_text;return[this._oriented_labels_extent(e,i,s,a)]}get extents(){const t=this._tick_label_extents();return{tick:this._tick_extent(),tick_labels:t,tick_label:(0,d.sum)(t),axis_label:this._axis_label_extent()}}_oriented_labels_extent(t,e,i,s){if(0==t.length||!s.doit)return 0;const a=this.panel.get_label_angle_heuristic(e);t.visuals=s.values(),t.angle=a,t.base_font_size=this.plot_view.base_font_size;const o=t.max_size(),l=0==this.dimension?o.height:o.width;return l>0?i+l+3:0}get normals(){return this.panel.normals}get dimension(){return this.panel.dimension}compute_labels(t){const e=this.model.formatter.format_graphics(t,this),{_major_label_views:i}=this,s=new Set;for(let a=0;az(l-n)?(t=r(_(a,o),l),s=_(r(a,o),n)):(t=_(a,o),s=r(a,o)),[t,s]}}get rule_coords(){const t=this.dimension,e=(t+1)%2,[i]=this.ranges,[s,a]=this.computed_bounds,o=[new Array(2),new Array(2)];return o[t][0]=Math.max(s,i.min),o[t][1]=Math.min(a,i.max),o[t][0]>o[t][1]&&(o[t][0]=o[t][1]=NaN),o[e][0]=this.loc,o[e][1]=this.loc,o}get tick_coords(){const t=this.dimension,e=(t+1)%2,[i]=this.ranges,[s,a]=this.computed_bounds,o=this.model.ticker.get_ticks(s,a,i,this.loc),l=o.major,n=o.minor,_=[[],[]],r=[[],[]],[h,c]=[i.min,i.max];for(let i=0;ic||(_[t].push(l[i]),_[e].push(this.loc));for(let i=0;ic||(r[t].push(n[i]),r[e].push(this.loc));return{major:_,minor:r}}get loc(){const{fixed_location:t}=this.model;if(null!=t){if((0,f.isNumber)(t))return t;const[,e]=this.ranges;if(e instanceof p.FactorRange)return e.synthetic(t);(0,j.unreachable)()}const[,e]=this.ranges;switch(this.panel.side){case\"left\":case\"below\":return e.start;case\"right\":case\"above\":return e.end}}serializable_state(){return Object.assign(Object.assign({},super.serializable_state()),{bbox:this.layout.bbox.box})}remove(){var t;null===(t=this._axis_label_view)||void 0===t||t.remove();for(const t of this._major_label_views.values())t.remove();super.remove()}has_finished(){if(!super.has_finished())return!1;if(null!=this._axis_label_view&&!this._axis_label_view.has_finished())return!1;for(const t of this._major_label_views.values())if(!t.has_finished())return!1;return!0}}i.AxisView=M,M.__name__=\"AxisView\";class O extends n.GuideRenderer{constructor(t){super(t)}}i.Axis=O,l=O,O.__name__=\"Axis\",l.prototype.default_view=M,l.mixins([[\"axis_\",c.Line],[\"major_tick_\",c.Line],[\"minor_tick_\",c.Line],[\"major_label_\",c.Text],[\"axis_label_\",c.Text]]),l.define((({Any:t,Int:e,Number:i,String:s,Ref:a,Dict:o,Tuple:l,Or:n,Nullable:c,Auto:u})=>({bounds:[n(l(i,i),u),\"auto\"],ticker:[a(_.Ticker)],formatter:[a(r.TickFormatter)],axis_label:[c(n(s,a(v.BaseText))),null],axis_label_standoff:[e,5],major_label_standoff:[e,5],major_label_orientation:[n(b.TickLabelOrientation,i),\"horizontal\"],major_label_overrides:[o(n(s,a(v.BaseText))),{}],major_label_policy:[a(h.LabelingPolicy),()=>new h.AllLabels],major_tick_in:[i,2],major_tick_out:[i,6],minor_tick_in:[i,0],minor_tick_out:[i,4],fixed_location:[c(n(i,t)),null]}))),l.override({axis_line_color:\"black\",major_tick_line_color:\"black\",minor_tick_line_color:\"black\",major_label_text_font_size:\"11px\",major_label_text_align:\"center\",major_label_text_baseline:\"alphabetic\",axis_label_text_font_size:\"13px\",axis_label_text_font_style:\"italic\"})},\n", - " function _(e,r,d,n,i){var s;n();const _=e(41);class u extends _.RendererView{}d.GuideRendererView=u,u.__name__=\"GuideRendererView\";class c extends _.Renderer{constructor(e){super(e)}}d.GuideRenderer=c,s=c,c.__name__=\"GuideRenderer\",s.override({level:\"guide\"})},\n", - " function _(c,e,n,s,o){s();const r=c(53);class t extends r.Model{constructor(c){super(c)}}n.Ticker=t,t.__name__=\"Ticker\"},\n", - " function _(t,o,r,e,c){e();const n=t(53),a=t(120);class m extends n.Model{constructor(t){super(t)}format_graphics(t,o){return this.doFormat(t,o).map((t=>new a.TextBox({text:t})))}compute(t,o){return this.doFormat([t],null!=o?o:{loc:0})[0]}v_compute(t,o){return this.doFormat(t,null!=o?o:{loc:0})}}r.TickFormatter=m,m.__name__=\"TickFormatter\"},\n", - " function _(e,n,s,t,i){var c,r;t();const l=e(53),o=e(13),a=e(34),u=e(8),d=e(24);class _ extends l.Model{constructor(e){super(e)}}s.LabelingPolicy=_,_.__name__=\"LabelingPolicy\";class f extends _{constructor(e){super(e)}filter(e,n,s){return e}}s.AllLabels=f,f.__name__=\"AllLabels\";class m extends _{constructor(e){super(e)}filter(e,n,s){const{min_distance:t}=this;let i=null;for(const n of e)null!=i&&s(i,n)({min_distance:[e,5]})));class b extends _{constructor(e){super(e)}get names(){return(0,o.keys)(this.args)}get values(){return(0,o.values)(this.args)}get func(){const e=(0,a.use_strict)(this.code);return new d.GeneratorFunction(\"indices\",\"bboxes\",\"distance\",...this.names,e)}filter(e,n,s){const t=Object.create(null),i=this.func.call(t,e,n,s,...this.values);let c=i.next();if(c.done&&void 0!==c.value){const{value:n}=c;return n instanceof d.Indices?n:void 0===n?e:(0,u.isIterable)(n)?d.Indices.from_indices(e.size,n):d.Indices.all_unset(e.size)}{const n=[];do{n.push(c.value),c=i.next()}while(!c.done);return d.Indices.from_indices(e.size,n)}}}s.CustomLabelingPolicy=b,r=b,b.__name__=\"CustomLabelingPolicy\",r.define((({Unknown:e,String:n,Dict:s})=>({args:[s(e),{}],code:[n,\"\"]})))},\n", - " function _(e,s,t,n,a){var _;n();const x=e(53),c=e(42);class i extends c.View{}t.BaseTextView=i,i.__name__=\"BaseTextView\";class o extends x.Model{constructor(e){super(e)}}t.BaseText=o,_=o,o.__name__=\"BaseText\",_.define((({String:e})=>({text:[e]})))},\n", - " function _(n,e,t,i,r){i();const s=n(135),l=n(139),d=[{start:\"$$\",end:\"$$\",inline:!1},{start:\"\\\\[\",end:\"\\\\]\",inline:!1},{start:\"\\\\(\",end:\"\\\\)\",inline:!0}];t.parse_delimited_string=function(n){for(const e of d){const t=n.indexOf(e.start),i=t+e.start.length;if(0==t){const t=n.indexOf(e.end,i),r=t;if(t==n.length-e.end.length)return new s.TeX({text:n.slice(i,r),inline:e.inline});break}}return new l.PlainText({text:n})}},\n", - " function _(t,e,s,i,n){var o,r,a;i();const h=t(8),_=t(136),l=t(22),c=t(120),d=t(121),u=t(122),g=t(65),p=t(133),x=t(137);class m extends p.BaseTextView{constructor(){super(...arguments),this._position={sx:0,sy:0},this.align=\"left\",this._x_anchor=\"left\",this._y_anchor=\"center\",this._base_font_size=13,this.font_size_scale=1,this.svg_image=null}graphics(){return this}infer_text_height(){return\"ascent_descent\"}set base_font_size(t){null!=t&&(this._base_font_size=t)}get base_font_size(){return this._base_font_size}get has_image_loaded(){return null!=this.svg_image}_rect(){const{width:t,height:e}=this._size(),{x:s,y:i}=this._computed_position();return new g.BBox({x:s,y:i,width:t,height:e}).rect}set position(t){this._position=t}get position(){return this._position}get text(){return this.model.text}get provider(){return x.default_provider}async lazy_initialize(){await super.lazy_initialize(),\"not_started\"==this.provider.status&&await this.provider.fetch(),\"not_started\"!=this.provider.status&&\"loading\"!=this.provider.status||this.provider.ready.connect((()=>this.load_image())),\"loaded\"==this.provider.status&&await this.load_image()}connect_signals(){super.connect_signals(),this.on_change(this.model.properties.text,(()=>this.load_image()))}set visuals(t){const e=t.color,s=t.alpha,i=t.font_style;let n=t.font_size;const o=t.font,{font_size_scale:r,_base_font_size:a}=this,h=(0,d.parse_css_font_size)(n);if(null!=h){let{value:t,unit:e}=h;t*=r,\"em\"==e&&a&&(t*=a,e=\"px\"),n=`${t}${e}`}const _=`${i} ${n} ${o}`;this.font=_,this.color=(0,l.color2css)(e,s)}_computed_position(){const{width:t,height:e}=this._size(),{sx:s,sy:i,x_anchor:n=this._x_anchor,y_anchor:o=this._y_anchor}=this.position;return{x:s-(()=>{if((0,h.isNumber)(n))return n*t;switch(n){case\"left\":return 0;case\"center\":return.5*t;case\"right\":return t}})(),y:i-(()=>{if((0,h.isNumber)(o))return o*e;switch(o){case\"top\":return 0;case\"center\":return.5*e;case\"bottom\":return e;case\"baseline\":return.5*e}})()}}size(){const{width:t,height:e}=this._size(),{angle:s}=this;if(s){const i=Math.cos(Math.abs(s)),n=Math.sin(Math.abs(s));return{width:Math.abs(t*i+e*n),height:Math.abs(t*n+e*i)}}return{width:t,height:e}}get_text_dimensions(){return{width:(0,c.text_width)(this.model.text,this.font),height:(0,d.font_metrics)(this.font).height}}get_image_dimensions(){var t,e,s,i;const n=parseFloat(null!==(e=null===(t=this.svg_element.getAttribute(\"height\"))||void 0===t?void 0:t.replace(/([A-z])/g,\"\"))&&void 0!==e?e:\"0\"),o=parseFloat(null!==(i=null===(s=this.svg_element.getAttribute(\"width\"))||void 0===s?void 0:s.replace(/([A-z])/g,\"\"))&&void 0!==i?i:\"0\");return{width:(0,d.font_metrics)(this.font).x_height*o,height:(0,d.font_metrics)(this.font).x_height*n}}_size(){return this.has_image_loaded?this.get_image_dimensions():this.get_text_dimensions()}bbox(){const{p0:t,p1:e,p2:s,p3:i}=this.rect(),n=Math.min(t.x,e.x,s.x,i.x),o=Math.min(t.y,e.y,s.y,i.y),r=Math.max(t.x,e.x,s.x,i.x),a=Math.max(t.y,e.y,s.y,i.y);return new g.BBox({left:n,right:r,top:o,bottom:a})}rect(){const t=this._rect(),{angle:e}=this;if(e){const{sx:s,sy:i}=this.position,n=new u.AffineTransform;return n.translate(s,i),n.rotate(e),n.translate(-s,-i),n.apply_rect(t)}return t}paint_rect(t){const{p0:e,p1:s,p2:i,p3:n}=this.rect();t.save(),t.strokeStyle=\"red\",t.lineWidth=1,t.beginPath();const{round:o}=Math;t.moveTo(o(e.x),o(e.y)),t.lineTo(o(s.x),o(s.y)),t.lineTo(o(i.x),o(i.y)),t.lineTo(o(n.x),o(n.y)),t.closePath(),t.stroke(),t.restore()}paint_bbox(t){const{x:e,y:s,width:i,height:n}=this.bbox();t.save(),t.strokeStyle=\"blue\",t.lineWidth=1,t.beginPath();const{round:o}=Math;t.moveTo(o(e),o(s)),t.lineTo(o(e),o(s+n)),t.lineTo(o(e+i),o(s+n)),t.lineTo(o(e+i),o(s)),t.closePath(),t.stroke(),t.restore()}async load_image(){if(null==this.provider.MathJax)return null;const t=this._process_text(this.model.text);if(null==t)return this._has_finished=!0,null;const e=t.children[0];this.svg_element=e,e.setAttribute(\"font\",this.font),e.setAttribute(\"stroke\",this.color);const s=e.outerHTML,i=new Blob([s],{type:\"image/svg+xml\"}),n=URL.createObjectURL(i);try{this.svg_image=await(0,_.load_image)(n)}finally{URL.revokeObjectURL(n)}return this.parent.request_layout(),this.svg_image}paint(t){t.save();const{sx:e,sy:s}=this.position;this.angle&&(t.translate(e,s),t.rotate(this.angle),t.translate(-e,-s));const{x:i,y:n}=this._computed_position();if(null!=this.svg_image){const{width:e,height:s}=this.get_image_dimensions();t.drawImage(this.svg_image,i,n,e,s)}else t.fillStyle=this.color,t.font=this.font,t.textAlign=\"left\",t.textBaseline=\"alphabetic\",t.fillText(this.model.text,i,n+(0,d.font_metrics)(this.font).ascent);t.restore(),this._has_finished||\"failed\"!=this.provider.status&&!this.has_image_loaded||(this._has_finished=!0,this.parent.notify_finished_after_paint())}}s.MathTextView=m,m.__name__=\"MathTextView\";class f extends p.BaseText{constructor(t){super(t)}}s.MathText=f,f.__name__=\"MathText\";class v extends m{_process_text(t){}}s.AsciiView=v,v.__name__=\"AsciiView\";class y extends f{constructor(t){super(t)}}s.Ascii=y,o=y,y.__name__=\"Ascii\",o.prototype.default_view=v;class w extends m{_process_text(t){var e;return null===(e=this.provider.MathJax)||void 0===e?void 0:e.mathml2svg(t.trim())}}s.MathMLView=w,w.__name__=\"MathMLView\";class b extends f{constructor(t){super(t)}}s.MathML=b,r=b,b.__name__=\"MathML\",r.prototype.default_view=w;class M extends m{_process_text(t){var e;return null===(e=this.provider.MathJax)||void 0===e?void 0:e.tex2svg(t,void 0,this.model.macros)}}s.TeXView=M,M.__name__=\"TeXView\";class T extends f{constructor(t){super(t)}}s.TeX=T,a=T,T.__name__=\"TeX\",a.prototype.default_view=M,a.define((({Boolean:t,Number:e,String:s,Dict:i,Tuple:n,Or:o})=>({macros:[i(o(s,n(s,e))),{}],inline:[t,!1]})))},\n", - " function _(i,e,t,s,o){s();const a=i(19);t.load_image=async function(i,e){return new n(i,e).promise};class n{constructor(i,e={}){this._image=new Image,this._finished=!1;const{attempts:t=1,timeout:s=1}=e;this.promise=new Promise(((o,n)=>{this._image.crossOrigin=\"anonymous\";let r=0;this._image.onerror=()=>{if(++r==t){const s=`unable to load ${i} image after ${t} attempts`;if(a.logger.warn(s),null==this._image.crossOrigin)return void(null!=e.failed&&e.failed());a.logger.warn(`attempting to load ${i} without a cross origin policy`),this._image.crossOrigin=null,r=0}setTimeout((()=>this._image.src=i),s)},this._image.onload=()=>{this._finished=!0,null!=e.loaded&&e.loaded(this._image),o(this._image)},this._image.src=i}))}get finished(){return this._finished}get image(){if(this._finished)return this._image;throw new Error(\"not loaded yet\")}}t.ImageLoader=n,n.__name__=\"ImageLoader\"},\n", - " function _(t,e,a,s,n){var r=this&&this.__createBinding||(Object.create?function(t,e,a,s){void 0===s&&(s=a),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[a]}})}:function(t,e,a,s){void 0===s&&(s=a),t[s]=e[a]}),i=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,\"default\",{enumerable:!0,value:e})}:function(t,e){t.default=e}),d=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)\"default\"!==a&&Object.prototype.hasOwnProperty.call(t,a)&&r(e,t,a);return i(e,t),e};s();const o=t(15),u=t(138);class c{constructor(){this.ready=new o.Signal0(this,\"ready\"),this.status=\"not_started\"}}a.MathJaxProvider=c,c.__name__=\"MathJaxProvider\";class h extends c{get MathJax(){return null}async fetch(){this.status=\"failed\"}}a.NoProvider=h,h.__name__=\"NoProvider\";class l extends c{get MathJax(){return\"undefined\"!=typeof MathJax?MathJax:null}async fetch(){const t=document.createElement(\"script\");t.src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js\",t.onload=()=>{this.status=\"loaded\",this.ready.emit()},t.onerror=()=>{this.status=\"failed\"},this.status=\"loading\",document.head.appendChild(t)}}a.CDNProvider=l,l.__name__=\"CDNProvider\";class _ extends c{get MathJax(){return this._mathjax}async fetch(){this.status=\"loading\";try{const e=await(0,u.load_module)(Promise.resolve().then((()=>d(t(519)))));this._mathjax=e,this.status=\"loaded\",this.ready.emit()}catch(t){this.status=\"failed\"}}}a.BundleProvider=_,_.__name__=\"BundleProvider\",a.default_provider=new _},\n", - " function _(n,r,o,t,c){t(),o.load_module=async function(n){try{return await n}catch(n){if((r=n)instanceof Error&&\"code\"in r&&\"MODULE_NOT_FOUND\"===n.code)return null;throw n}var r}},\n", - " function _(e,t,i,n,s){var a;n();const x=e(133),_=e(120);class l extends x.BaseTextView{initialize(){super.initialize(),this._has_finished=!0}graphics(){return new _.TextBox({text:this.model.text})}}i.PlainTextView=l,l.__name__=\"PlainTextView\";class r extends x.BaseText{constructor(e){super(e)}}i.PlainText=r,a=r,r.__name__=\"PlainText\",a.prototype.default_view=l},\n", - " function _(t,s,o,e,i){e();const r=t(1);var a;const l=t(128),_=t(141),n=t(142),p=(0,r.__importStar)(t(48)),c=t(20),h=t(120),m=t(8);class u extends l.AxisView{_paint(t,s,o){this._draw_group_separators(t,s,o)}_draw_group_separators(t,s,o){const[e]=this.ranges,[i,r]=this.computed_bounds;if(!e.tops||e.tops.length<2||!this.visuals.separator_line.doit)return;const a=this.dimension,l=(a+1)%2,_=[[],[]];let n=0;for(let t=0;ti&&pnew h.GraphicsBoxes(t.map((t=>(0,m.isString)(t)?new h.TextBox({text:t}):t))),_=t=>l(this.model.formatter.doFormat(t,this));if(1==t.levels){const t=_(i.major);a.push([t,r.major,this.model.major_label_orientation,this.visuals.major_label_text])}else if(2==t.levels){const t=_(i.major.map((t=>t[1])));a.push([t,r.major,this.model.major_label_orientation,this.visuals.major_label_text]),a.push([l(i.tops),r.tops,this.model.group_label_orientation,this.visuals.group_text])}else if(3==t.levels){const t=_(i.major.map((t=>t[2]))),s=i.mids.map((t=>t[1]));a.push([t,r.major,this.model.major_label_orientation,this.visuals.major_label_text]),a.push([l(s),r.mids,this.model.subgroup_label_orientation,this.visuals.subgroup_text]),a.push([l(i.tops),r.tops,this.model.group_label_orientation,this.visuals.group_text])}return a}get tick_coords(){const t=this.dimension,s=(t+1)%2,[o]=this.ranges,[e,i]=this.computed_bounds,r=this.model.ticker.get_ticks(e,i,o,this.loc),a={major:[[],[]],mids:[[],[]],tops:[[],[]],minor:[[],[]]};return a.major[t]=r.major,a.major[s]=r.major.map((()=>this.loc)),3==o.levels&&(a.mids[t]=r.mids,a.mids[s]=r.mids.map((()=>this.loc))),o.levels>1&&(a.tops[t]=r.tops,a.tops[s]=r.tops.map((()=>this.loc))),a}}o.CategoricalAxisView=u,u.__name__=\"CategoricalAxisView\";class d extends l.Axis{constructor(t){super(t)}}o.CategoricalAxis=d,a=d,d.__name__=\"CategoricalAxis\",a.prototype.default_view=u,a.mixins([[\"separator_\",p.Line],[\"group_\",p.Text],[\"subgroup_\",p.Text]]),a.define((({Number:t,Or:s})=>({group_label_orientation:[s(c.TickLabelOrientation,t),\"parallel\"],subgroup_label_orientation:[s(c.TickLabelOrientation,t),\"parallel\"]}))),a.override({ticker:()=>new _.CategoricalTicker,formatter:()=>new n.CategoricalTickFormatter,separator_line_color:\"lightgrey\",separator_line_width:2,group_text_font_style:\"bold\",group_text_font_size:\"11px\",group_text_color:\"grey\",subgroup_text_font_style:\"bold\",subgroup_text_font_size:\"11px\"})},\n", - " function _(t,c,o,s,e){s();const r=t(130);class i extends r.Ticker{constructor(t){super(t)}get_ticks(t,c,o,s){var e,r;return{major:this._collect(o.factors,o,t,c),minor:[],tops:this._collect(null!==(e=o.tops)&&void 0!==e?e:[],o,t,c),mids:this._collect(null!==(r=o.mids)&&void 0!==r?r:[],o,t,c)}}_collect(t,c,o,s){const e=[];for(const r of t){const t=c.synthetic(r);t>o&&tnew _.DatetimeTicker,formatter:()=>new m.DatetimeTickFormatter})},\n", - " function _(e,i,s,n,r){var t;n();const a=e(143),o=e(146),c=e(147);class _ extends a.ContinuousAxisView{}s.LinearAxisView=_,_.__name__=\"LinearAxisView\";class u extends a.ContinuousAxis{constructor(e){super(e)}}s.LinearAxis=u,t=u,u.__name__=\"LinearAxis\",t.prototype.default_view=_,t.override({ticker:()=>new c.BasicTicker,formatter:()=>new o.BasicTickFormatter})},\n", - " function _(i,t,e,n,o){var r;n();const s=i(131),c=i(34);function _(i){let t=\"\";for(const e of i)t+=\"-\"==e?\"\\u2212\":e;return t}e.unicode_replace=_;class a extends s.TickFormatter{constructor(i){super(i),this.last_precision=3}get scientific_limit_low(){return 10**this.power_limit_low}get scientific_limit_high(){return 10**this.power_limit_high}_need_sci(i){if(!this.use_scientific)return!1;const{scientific_limit_high:t}=this,{scientific_limit_low:e}=this,n=i.length<2?0:Math.abs(i[1]-i[0])/1e4;for(const o of i){const i=Math.abs(o);if(!(i<=n)&&(i>=t||i<=e))return!0}return!1}_format_with_precision(i,t,e){return t?i.map((i=>_(i.toExponential(e)))):i.map((i=>_((0,c.to_fixed)(i,e))))}_auto_precision(i,t){const e=new Array(i.length),n=this.last_precision<=15;i:for(let o=this.last_precision;n?o<=15:o>=1;n?o++:o--){if(t){e[0]=i[0].toExponential(o);for(let t=1;t({precision:[n(t,e),\"auto\"],use_scientific:[i,!0],power_limit_high:[t,5],power_limit_low:[t,-3]})))},\n", - " function _(c,e,s,i,n){i();const r=c(148);class t extends r.AdaptiveTicker{constructor(c){super(c)}}s.BasicTicker=t,t.__name__=\"BasicTicker\"},\n", - " function _(t,i,a,s,e){var n;s();const r=t(149),_=t(9),l=t(10);class h extends r.ContinuousTicker{constructor(t){super(t)}get_min_interval(){return this.min_interval}get_max_interval(){var t;return null!==(t=this.max_interval)&&void 0!==t?t:1/0}initialize(){super.initialize();const t=(0,_.nth)(this.mantissas,-1)/this.base,i=(0,_.nth)(this.mantissas,0)*this.base;this.extended_mantissas=[t,...this.mantissas,i],this.base_factor=0===this.get_min_interval()?1:this.get_min_interval()}get_interval(t,i,a){const s=i-t,e=this.get_ideal_interval(t,i,a),n=Math.floor((0,l.log)(e/this.base_factor,this.base)),r=this.base**n*this.base_factor,h=this.extended_mantissas,m=h.map((t=>Math.abs(a-s/(t*r)))),v=h[(0,_.argmin)(m)]*r;return(0,l.clamp)(v,this.get_min_interval(),this.get_max_interval())}}a.AdaptiveTicker=h,n=h,h.__name__=\"AdaptiveTicker\",n.define((({Number:t,Array:i,Nullable:a})=>({base:[t,10],mantissas:[i(t),[1,2,5]],min_interval:[t,0],max_interval:[a(t),null]})))},\n", - " function _(t,n,i,s,e){var o;s();const r=t(130),c=t(9);class _ extends r.Ticker{constructor(t){super(t)}get_ticks(t,n,i,s){return this.get_ticks_no_defaults(t,n,s,this.desired_num_ticks)}get_ticks_no_defaults(t,n,i,s){const e=this.get_interval(t,n,s),o=Math.floor(t/e),r=Math.ceil(n/e);let _;_=isFinite(o)&&isFinite(r)?(0,c.range)(o,r+1):[];const u=_.map((t=>t*e)).filter((i=>t<=i&&i<=n)),a=this.num_minor_ticks,f=[];if(a>0&&u.length>0){const i=e/a,s=(0,c.range)(0,a).map((t=>t*i));for(const i of s.slice(1)){const s=u[0]-i;t<=s&&s<=n&&f.push(s)}for(const i of u)for(const e of s){const s=i+e;t<=s&&s<=n&&f.push(s)}}return{major:u,minor:f}}get_ideal_interval(t,n,i){return(n-t)/i}}i.ContinuousTicker=_,o=_,_.__name__=\"ContinuousTicker\",o.define((({Int:t})=>({num_minor_ticks:[t,5],desired_num_ticks:[t,6]})))},\n", - " function _(s,t,e,n,i){n();var r;const o=(0,s(1).__importDefault)(s(151)),a=s(131),c=s(19),u=s(152),m=s(9),h=s(8);function d(s){return(0,o.default)(s,\"%Y %m %d %H %M %S\").split(/\\s+/).map((s=>parseInt(s,10)))}function l(s,t){if((0,h.isFunction)(t))return t(s);{const e=(0,u.sprintf)(\"$1%06d\",function(s){return Math.round(s/1e3%1*1e6)}(s));return-1==(t=t.replace(/((^|[^%])(%%)*)%f/,e)).indexOf(\"%\")?t:(0,o.default)(s,t)}}const f=[\"microseconds\",\"milliseconds\",\"seconds\",\"minsec\",\"minutes\",\"hourmin\",\"hours\",\"days\",\"months\",\"years\"];class _ extends a.TickFormatter{constructor(s){super(s),this.strip_leading_zeros=!0}initialize(){super.initialize(),this._update_width_formats()}_update_width_formats(){const s=+(0,o.default)(new Date),t=function(t){const e=t.map((t=>l(s,t).length)),n=(0,m.sort_by)((0,m.zip)(e,t),(([s])=>s));return(0,m.unzip)(n)};this._width_formats={microseconds:t(this.microseconds),milliseconds:t(this.milliseconds),seconds:t(this.seconds),minsec:t(this.minsec),minutes:t(this.minutes),hourmin:t(this.hourmin),hours:t(this.hours),days:t(this.days),months:t(this.months),years:t(this.years)}}_get_resolution_str(s,t){const e=1.1*s;switch(!1){case!(e<.001):return\"microseconds\";case!(e<1):return\"milliseconds\";case!(e<60):return t>=60?\"minsec\":\"seconds\";case!(e<3600):return t>=3600?\"hourmin\":\"minutes\";case!(e<86400):return\"hours\";case!(e<2678400):return\"days\";case!(e<31536e3):return\"months\";default:return\"years\"}}doFormat(s,t){if(0==s.length)return[];const e=Math.abs(s[s.length-1]-s[0])/1e3,n=e/(s.length-1),i=this._get_resolution_str(n,e),[,[r]]=this._width_formats[i],o=[],a=f.indexOf(i),u={};for(const s of f)u[s]=0;u.seconds=5,u.minsec=4,u.minutes=4,u.hourmin=3,u.hours=3;for(const t of s){let s,e;try{e=d(t),s=l(t,r)}catch(s){c.logger.warn(`unable to format tick for timestamp value ${t}`),c.logger.warn(` - ${s}`),o.push(\"ERR\");continue}let n=!1,m=a;for(;0==e[u[f[m]]];){let r;if(m+=1,m==f.length)break;if((\"minsec\"==i||\"hourmin\"==i)&&!n){if(\"minsec\"==i&&0==e[4]&&0!=e[5]||\"hourmin\"==i&&0==e[3]&&0!=e[4]){r=this._width_formats[f[a-1]][1][0],s=l(t,r);break}n=!0}r=this._width_formats[f[m]][1][0],s=l(t,r)}if(this.strip_leading_zeros){let t=s.replace(/^0+/g,\"\");t!=s&&isNaN(parseInt(t))&&(t=`0${t}`),o.push(t)}else o.push(s)}return o}}e.DatetimeTickFormatter=_,r=_,_.__name__=\"DatetimeTickFormatter\",r.define((({String:s,Array:t})=>({microseconds:[t(s),[\"%fus\"]],milliseconds:[t(s),[\"%3Nms\",\"%S.%3Ns\"]],seconds:[t(s),[\"%Ss\"]],minsec:[t(s),[\":%M:%S\"]],minutes:[t(s),[\":%M\",\"%Mm\"]],hourmin:[t(s),[\"%H:%M\"]],hours:[t(s),[\"%Hh\",\"%H:%M\"]],days:[t(s),[\"%m/%d\",\"%a%d\"]],months:[t(s),[\"%m/%Y\",\"%b %Y\"]],years:[t(s),[\"%Y\"]]})))},\n", - " function _(e,t,n,r,o){!function(e){\"object\"==typeof t&&t.exports?t.exports=e():\"function\"==typeof define?define(e):this.tz=e()}((function(){function e(e,t,n){var r,o=t.day[1];do{r=new Date(Date.UTC(n,t.month,Math.abs(o++)))}while(t.day[0]<7&&r.getUTCDay()!=t.day[0]);return(r={clock:t.clock,sort:r.getTime(),rule:t,save:6e4*t.save,offset:e.offset})[r.clock]=r.sort+6e4*t.time,r.posix?r.wallclock=r[r.clock]+(e.offset+t.saved):r.posix=r[r.clock]-(e.offset+t.saved),r}function t(t,n,r){var o,a,u,i,l,s,c,f=t[t.zone],h=[],T=new Date(r).getUTCFullYear(),g=1;for(o=1,a=f.length;o=T-g;--c)for(o=0,a=s.length;o=h[o][n]&&h[o][h[o].clock]>u[h[o].clock]&&(i=h[o])}return i&&((l=/^(.*)\\/(.*)$/.exec(u.format))?i.abbrev=l[i.save?2:1]:i.abbrev=u.format.replace(/%s/,i.rule.letter)),i||u}function n(e,n){return\"UTC\"==e.zone?n:(e.entry=t(e,\"posix\",n),n+e.entry.offset+e.entry.save)}function r(e,n){return\"UTC\"==e.zone?n:(e.entry=r=t(e,\"wallclock\",n),0<(o=n-r.wallclock)&&o9)t+=s*l[c-10];else{if(a=new Date(n(e,t)),c<7)for(;s;)a.setUTCDate(a.getUTCDate()+i),a.getUTCDay()==c&&(s-=i);else 7==c?a.setUTCFullYear(a.getUTCFullYear()+s):8==c?a.setUTCMonth(a.getUTCMonth()+s):a.setUTCDate(a.getUTCDate()+s);null==(t=r(e,a.getTime()))&&(t=r(e,a.getTime()+864e5*i)-864e5*i)}return t}var a={clock:function(){return+new Date},zone:\"UTC\",entry:{abbrev:\"UTC\",offset:0,save:0},UTC:1,z:function(e,t,n,r){var o,a,u=this.entry.offset+this.entry.save,i=Math.abs(u/1e3),l=[],s=3600;for(o=0;o<3;o++)l.push((\"0\"+Math.floor(i/s)).slice(-2)),i%=s,s/=60;return\"^\"!=n||u?(\"^\"==n&&(r=3),3==r?(a=(a=l.join(\":\")).replace(/:00$/,\"\"),\"^\"!=n&&(a=a.replace(/:00$/,\"\"))):r?(a=l.slice(0,r+1).join(\":\"),\"^\"==n&&(a=a.replace(/:00$/,\"\"))):a=l.slice(0,2).join(\"\"),a=(a=(u<0?\"-\":\"+\")+a).replace(/([-+])(0)/,{_:\" $1\",\"-\":\"$1\"}[n]||\"$1$2\")):\"Z\"},\"%\":function(e){return\"%\"},n:function(e){return\"\\n\"},t:function(e){return\"\\t\"},U:function(e){return s(e,0)},W:function(e){return s(e,1)},V:function(e){return c(e)[0]},G:function(e){return c(e)[1]},g:function(e){return c(e)[1]%100},j:function(e){return Math.floor((e.getTime()-Date.UTC(e.getUTCFullYear(),0))/864e5)+1},s:function(e){return Math.floor(e.getTime()/1e3)},C:function(e){return Math.floor(e.getUTCFullYear()/100)},N:function(e){return e.getTime()%1e3*1e6},m:function(e){return e.getUTCMonth()+1},Y:function(e){return e.getUTCFullYear()},y:function(e){return e.getUTCFullYear()%100},H:function(e){return e.getUTCHours()},M:function(e){return e.getUTCMinutes()},S:function(e){return e.getUTCSeconds()},e:function(e){return e.getUTCDate()},d:function(e){return e.getUTCDate()},u:function(e){return e.getUTCDay()||7},w:function(e){return e.getUTCDay()},l:function(e){return e.getUTCHours()%12||12},I:function(e){return e.getUTCHours()%12||12},k:function(e){return e.getUTCHours()},Z:function(e){return this.entry.abbrev},a:function(e){return this[this.locale].day.abbrev[e.getUTCDay()]},A:function(e){return this[this.locale].day.full[e.getUTCDay()]},h:function(e){return this[this.locale].month.abbrev[e.getUTCMonth()]},b:function(e){return this[this.locale].month.abbrev[e.getUTCMonth()]},B:function(e){return this[this.locale].month.full[e.getUTCMonth()]},P:function(e){return this[this.locale].meridiem[Math.floor(e.getUTCHours()/12)].toLowerCase()},p:function(e){return this[this.locale].meridiem[Math.floor(e.getUTCHours()/12)]},R:function(e,t){return this.convert([t,\"%H:%M\"])},T:function(e,t){return this.convert([t,\"%H:%M:%S\"])},D:function(e,t){return this.convert([t,\"%m/%d/%y\"])},F:function(e,t){return this.convert([t,\"%Y-%m-%d\"])},x:function(e,t){return this.convert([t,this[this.locale].date])},r:function(e,t){return this.convert([t,this[this.locale].time12||\"%I:%M:%S\"])},X:function(e,t){return this.convert([t,this[this.locale].time24])},c:function(e,t){return this.convert([t,this[this.locale].dateTime])},convert:function(e){if(!e.length)return\"1.0.23\";var t,a,u,l,s,c=Object.create(this),f=[];for(t=0;t=o?Math.floor((n-o)/7)+1:0}function c(e){var t,n,r;return n=e.getUTCFullYear(),t=new Date(Date.UTC(n,0)).getUTCDay(),(r=s(e,1)+(t>1&&t<=4?1:0))?53!=r||4==t||3==t&&29==new Date(n,1,29).getDate()?[r,e.getUTCFullYear()]:[1,e.getUTCFullYear()+1]:(n=e.getUTCFullYear()-1,[r=4==(t=new Date(Date.UTC(n,0)).getUTCDay())||3==t&&29==new Date(n,1,29).getDate()?53:52,e.getUTCFullYear()-1])}return u=u.toLowerCase().split(\"|\"),\"delmHMSUWVgCIky\".replace(/./g,(function(e){a[e].pad=2})),a.N.pad=9,a.j.pad=3,a.k.style=\"_\",a.l.style=\"_\",a.e.style=\"_\",function(){return a.convert(arguments)}}))},\n", - " function _(r,t,n,e,i){e();const u=r(1),a=(0,u.__importStar)(r(153)),f=r(154),o=(0,u.__importDefault)(r(151)),l=r(21),s=r(8);function c(r,...t){return(0,f.sprintf)(r,...t)}function m(r,t,n){if((0,s.isNumber)(r)){return c((()=>{switch(!1){case Math.floor(r)!=r:return\"%d\";case!(Math.abs(r)>.1&&Math.abs(r)<1e3):return\"%0.3f\";default:return\"%0.3e\"}})(),r)}return`${r}`}function _(r,t,e){if(null==t)return m;if(null!=e&&r in e){const t=e[r];if((0,s.isString)(t)){if(t in n.DEFAULT_FORMATTERS)return n.DEFAULT_FORMATTERS[t];throw new Error(`Unknown tooltip field formatter type '${t}'`)}return function(r,n,e){return t.format(r,n,e)}}return n.DEFAULT_FORMATTERS.numeral}function p(r,t,n){const e=t.get_column(r);if(null==e)return null;if((0,s.isNumber)(n))return e[n];const i=e[n.index];if((0,s.isTypedArray)(i)||(0,s.isArray)(i)){if((0,s.isArray)(i[0])){return i[n.dim2][n.dim1]}return i[n.flat_index]}return i}function d(r,t,n,e){if(\"$\"==r[0]){return function(r,t){if(r in t)return t[r];throw new Error(`Unknown special variable '$${r}'`)}(r.substring(1),e)}return p(r.substring(1).replace(/[{}]/g,\"\"),t,n)}n.FormatterType=(0,l.Enum)(\"numeral\",\"printf\",\"datetime\"),n.DEFAULT_FORMATTERS={numeral:(r,t,n)=>a.format(r,t),datetime:(r,t,n)=>(0,o.default)(r,t),printf:(r,t,n)=>c(t,r)},n.sprintf=c,n.basic_formatter=m,n.get_formatter=_,n._get_column_value=p,n.get_value=d,n.replace_placeholders=function(r,t,n,e,i={},u){let a,f;if((0,s.isString)(r)?(a=r,f=!1):(a=r.html,f=!0),a=a.replace(/@\\$name/g,(r=>`@{${i.name}}`)),a=a.replace(/((?:\\$\\w+)|(?:@\\w+)|(?:@{(?:[^{}]+)}))(?:{([^{}]+)})?/g,((r,a,o)=>{const l=d(a,t,n,i);if(null==l)return u?u(\"???\"):\"???\";if(\"safe\"==o)return f=!0,`${l}`;const s=`${_(a,o,e)(l,o,i)}`;return u?u(s):s})),f){return[...(new DOMParser).parseFromString(a,\"text/html\").body.childNodes]}return a}},\n", - " function _(e,n,t,r,i){\n", - " /*!\n", - " * numbro.js\n", - " * version : 1.6.2\n", - " * author : Företagsplatsen AB\n", - " * license : MIT\n", - " * http://www.foretagsplatsen.se\n", - " */\n", - " var a,o={},l=o,u=\"en-US\",c=null,s=\"0,0\";void 0!==n&&n.exports;function f(e){this._value=e}function d(e){var n,t=\"\";for(n=0;n-1?function(e,n){var t,r,i,a;return t=(a=e.toString()).split(\"e\")[0],i=a.split(\"e\")[1],a=t.split(\".\")[0]+(r=t.split(\".\")[1]||\"\")+d(i-r.length),n>0&&(a+=\".\"+d(n)),a}(e,n):(t(e*o)/o).toFixed(n),r&&(i=new RegExp(\"0{1,\"+r+\"}$\"),a=a.replace(i,\"\")),a}function p(e,n,t){var r;return r=n.indexOf(\"$\")>-1?function(e,n,t){var r,i,a=n,l=a.indexOf(\"$\"),c=a.indexOf(\"(\"),s=a.indexOf(\"+\"),f=a.indexOf(\"-\"),d=\"\",h=\"\";-1===a.indexOf(\"$\")?\"infix\"===o[u].currency.position?(h=o[u].currency.symbol,o[u].currency.spaceSeparated&&(h=\" \"+h+\" \")):o[u].currency.spaceSeparated&&(d=\" \"):a.indexOf(\" $\")>-1?(d=\" \",a=a.replace(\" $\",\"\")):a.indexOf(\"$ \")>-1?(d=\" \",a=a.replace(\"$ \",\"\")):a=a.replace(\"$\",\"\");if(i=m(e,a,t,h),-1===n.indexOf(\"$\"))switch(o[u].currency.position){case\"postfix\":i.indexOf(\")\")>-1?((i=i.split(\"\")).splice(-1,0,d+o[u].currency.symbol),i=i.join(\"\")):i=i+d+o[u].currency.symbol;break;case\"infix\":break;case\"prefix\":i.indexOf(\"(\")>-1||i.indexOf(\"-\")>-1?(i=i.split(\"\"),r=Math.max(c,f)+1,i.splice(r,0,o[u].currency.symbol+d),i=i.join(\"\")):i=o[u].currency.symbol+d+i;break;default:throw Error('Currency position should be among [\"prefix\", \"infix\", \"postfix\"]')}else l<=1?i.indexOf(\"(\")>-1||i.indexOf(\"+\")>-1||i.indexOf(\"-\")>-1?(r=1,(l-1?((i=i.split(\"\")).splice(-1,0,d+o[u].currency.symbol),i=i.join(\"\")):i=i+d+o[u].currency.symbol;return i}(e,n,t):n.indexOf(\"%\")>-1?function(e,n,t){var r,i=\"\";e*=100,n.indexOf(\" %\")>-1?(i=\" \",n=n.replace(\" %\",\"\")):n=n.replace(\"%\",\"\");(r=m(e,n,t)).indexOf(\")\")>-1?((r=r.split(\"\")).splice(-1,0,i+\"%\"),r=r.join(\"\")):r=r+i+\"%\";return r}(e,n,t):n.indexOf(\":\")>-1?function(e){var n=Math.floor(e/60/60),t=Math.floor((e-60*n*60)/60),r=Math.round(e-60*n*60-60*t);return n+\":\"+(t<10?\"0\"+t:t)+\":\"+(r<10?\"0\"+r:r)}(e):m(e,n,t),r}function m(e,n,t,r){var i,a,l,s,f,d,p,m,x,g,O,b,w,y,M,v,$,B=!1,E=!1,F=!1,k=\"\",U=!1,N=!1,S=!1,j=!1,D=!1,C=\"\",L=\"\",T=Math.abs(e),K=[\"B\",\"KiB\",\"MiB\",\"GiB\",\"TiB\",\"PiB\",\"EiB\",\"ZiB\",\"YiB\"],G=[\"B\",\"KB\",\"MB\",\"GB\",\"TB\",\"PB\",\"EB\",\"ZB\",\"YB\"],I=\"\",P=!1,R=!1;if(0===e&&null!==c)return c;if(!isFinite(e))return\"\"+e;if(0===n.indexOf(\"{\")){var W=n.indexOf(\"}\");if(-1===W)throw Error('Format should also contain a \"}\"');b=n.slice(1,W),n=n.slice(W+1)}else b=\"\";if(n.indexOf(\"}\")===n.length-1){var Y=n.indexOf(\"{\");if(-1===Y)throw Error('Format should also contain a \"{\"');w=n.slice(Y+1,-1),n=n.slice(0,Y+1)}else w=\"\";if(v=null===($=-1===n.indexOf(\".\")?n.match(/([0-9]+).*/):n.match(/([0-9]+)\\..*/))?-1:$[1].length,-1!==n.indexOf(\"-\")&&(P=!0),n.indexOf(\"(\")>-1?(B=!0,n=n.slice(1,-1)):n.indexOf(\"+\")>-1&&(E=!0,n=n.replace(/\\+/g,\"\")),n.indexOf(\"a\")>-1){if(g=n.split(\".\")[0].match(/[0-9]+/g)||[\"0\"],g=parseInt(g[0],10),U=n.indexOf(\"aK\")>=0,N=n.indexOf(\"aM\")>=0,S=n.indexOf(\"aB\")>=0,j=n.indexOf(\"aT\")>=0,D=U||N||S||j,n.indexOf(\" a\")>-1?(k=\" \",n=n.replace(\" a\",\"\")):n=n.replace(\"a\",\"\"),p=0===(p=(f=Math.floor(Math.log(T)/Math.LN10)+1)%3)?3:p,g&&0!==T&&(d=Math.floor(Math.log(T)/Math.LN10)+1-g,m=3*~~((Math.min(g,f)-p)/3),T/=Math.pow(10,m),-1===n.indexOf(\".\")&&g>3))for(n+=\"[.]\",M=(M=0===d?0:3*~~(d/3)-d)<0?M+3:M,i=0;i=Math.pow(10,12)&&!D||j?(k+=o[u].abbreviations.trillion,e/=Math.pow(10,12)):T=Math.pow(10,9)&&!D||S?(k+=o[u].abbreviations.billion,e/=Math.pow(10,9)):T=Math.pow(10,6)&&!D||N?(k+=o[u].abbreviations.million,e/=Math.pow(10,6)):(T=Math.pow(10,3)&&!D||U)&&(k+=o[u].abbreviations.thousand,e/=Math.pow(10,3)))}if(n.indexOf(\"b\")>-1)for(n.indexOf(\" b\")>-1?(C=\" \",n=n.replace(\" b\",\"\")):n=n.replace(\"b\",\"\"),s=0;s<=K.length;s++)if(a=Math.pow(1024,s),l=Math.pow(1024,s+1),e>=a&&e0&&(e/=a);break}if(n.indexOf(\"d\")>-1)for(n.indexOf(\" d\")>-1?(C=\" \",n=n.replace(\" d\",\"\")):n=n.replace(\"d\",\"\"),s=0;s<=G.length;s++)if(a=Math.pow(1e3,s),l=Math.pow(1e3,s+1),e>=a&&e0&&(e/=a);break}if(n.indexOf(\"o\")>-1&&(n.indexOf(\" o\")>-1?(L=\" \",n=n.replace(\" o\",\"\")):n=n.replace(\"o\",\"\"),o[u].ordinal&&(L+=o[u].ordinal(e))),n.indexOf(\"[.]\")>-1&&(F=!0,n=n.replace(\"[.]\",\".\")),x=e.toString().split(\".\")[0],O=n.split(\".\")[1],y=n.indexOf(\",\"),O){if(x=(I=-1!==O.indexOf(\"*\")?h(e,e.toString().split(\".\")[1].length,t):O.indexOf(\"[\")>-1?h(e,(O=(O=O.replace(\"]\",\"\")).split(\"[\"))[0].length+O[1].length,t,O[1].length):h(e,O.length,t)).split(\".\")[0],I.split(\".\")[1].length)I=(r?k+r:o[u].delimiters.decimal)+I.split(\".\")[1];else I=\"\";F&&0===Number(I.slice(1))&&(I=\"\")}else x=h(e,null,t);return x.indexOf(\"-\")>-1&&(x=x.slice(1),R=!0),x.length-1&&(x=x.toString().replace(/(\\d)(?=(\\d{3})+(?!\\d))/g,\"$1\"+o[u].delimiters.thousands)),0===n.indexOf(\".\")&&(x=\"\"),b+(n.indexOf(\"(\")2)&&(o.length<2?!!o[0].match(/^\\d+.*\\d$/)&&!o[0].match(u):1===o[0].length?!!o[0].match(/^\\d+$/)&&!o[0].match(u)&&!!o[1].match(/^\\d+$/):!!o[0].match(/^\\d+.*\\d$/)&&!o[0].match(u)&&!!o[1].match(/^\\d+$/)))))},n.exports={format:function(e,n,t,r){return null!=t&&t!==a.culture()&&a.setCulture(t),p(Number(e),null!=n?n:s,null==r?Math.round:r)}}},\n", - " function _(e,n,t,r,i){!function(){\"use strict\";var e={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\\x25]+/,modulo:/^\\x25{2}/,placeholder:/^\\x25(?:([1-9]\\d*)\\$|\\(([^)]+)\\))?(\\+)?(0|'[^$])?(-)?(\\d+)?(?:\\.(\\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\\d]*)/i,key_access:/^\\.([a-z_][a-z_\\d]*)/i,index_access:/^\\[(\\d+)\\]/,sign:/^[+-]/};function n(e){return i(a(e),arguments)}function r(e,t){return n.apply(null,[e].concat(t||[]))}function i(t,r){var i,s,a,o,p,c,l,u,f,d=1,g=t.length,y=\"\";for(s=0;s=0),o.type){case\"b\":i=parseInt(i,10).toString(2);break;case\"c\":i=String.fromCharCode(parseInt(i,10));break;case\"d\":case\"i\":i=parseInt(i,10);break;case\"j\":i=JSON.stringify(i,null,o.width?parseInt(o.width):0);break;case\"e\":i=o.precision?parseFloat(i).toExponential(o.precision):parseFloat(i).toExponential();break;case\"f\":i=o.precision?parseFloat(i).toFixed(o.precision):parseFloat(i);break;case\"g\":i=o.precision?String(Number(i.toPrecision(o.precision))):parseFloat(i);break;case\"o\":i=(parseInt(i,10)>>>0).toString(8);break;case\"s\":i=String(i),i=o.precision?i.substring(0,o.precision):i;break;case\"t\":i=String(!!i),i=o.precision?i.substring(0,o.precision):i;break;case\"T\":i=Object.prototype.toString.call(i).slice(8,-1).toLowerCase(),i=o.precision?i.substring(0,o.precision):i;break;case\"u\":i=parseInt(i,10)>>>0;break;case\"v\":i=i.valueOf(),i=o.precision?i.substring(0,o.precision):i;break;case\"x\":i=(parseInt(i,10)>>>0).toString(16);break;case\"X\":i=(parseInt(i,10)>>>0).toString(16).toUpperCase()}e.json.test(o.type)?y+=i:(!e.number.test(o.type)||u&&!o.sign?f=\"\":(f=u?\"+\":\"-\",i=i.toString().replace(e.sign,\"\")),c=o.pad_char?\"0\"===o.pad_char?\"0\":o.pad_char.charAt(1):\" \",l=o.width-(f+i).length,p=o.width&&l>0?c.repeat(l):\"\",y+=o.align?f+i+p:\"0\"===c?f+p+i:p+f+i)}return y}var s=Object.create(null);function a(n){if(s[n])return s[n];for(var t,r=n,i=[],a=0;r;){if(null!==(t=e.text.exec(r)))i.push(t[0]);else if(null!==(t=e.modulo.exec(r)))i.push(\"%\");else{if(null===(t=e.placeholder.exec(r)))throw new SyntaxError(\"[sprintf] unexpected placeholder\");if(t[2]){a|=1;var o=[],p=t[2],c=[];if(null===(c=e.key.exec(p)))throw new SyntaxError(\"[sprintf] failed to parse named argument key\");for(o.push(c[1]);\"\"!==(p=p.substring(c[0].length));)if(null!==(c=e.key_access.exec(p)))o.push(c[1]);else{if(null===(c=e.index_access.exec(p)))throw new SyntaxError(\"[sprintf] failed to parse named argument key\");o.push(c[1])}t[2]=o}else a|=2;if(3===a)throw new Error(\"[sprintf] mixing positional and named placeholders is not (yet) supported\");i.push({placeholder:t[0],param_no:t[1],keys:t[2],sign:t[3],pad_char:t[4],align:t[5],width:t[6],precision:t[7],type:t[8]})}r=r.substring(t[0].length)}return s[n]=i}void 0!==t&&(t.sprintf=n,t.vsprintf=r),\"undefined\"!=typeof window&&(window.sprintf=n,window.vsprintf=r,\"function\"==typeof define&&define.amd&&define((function(){return{sprintf:n,vsprintf:r}})))}()},\n", - " function _(e,n,i,a,s){var r;a();const t=e(9),c=e(148),m=e(156),_=e(157),k=e(160),o=e(161),T=e(159);class w extends m.CompositeTicker{constructor(e){super(e)}}i.DatetimeTicker=w,r=w,w.__name__=\"DatetimeTicker\",r.override({num_minor_ticks:0,tickers:()=>[new c.AdaptiveTicker({mantissas:[1,2,5],base:10,min_interval:0,max_interval:500*T.ONE_MILLI,num_minor_ticks:0}),new c.AdaptiveTicker({mantissas:[1,2,5,10,15,20,30],base:60,min_interval:T.ONE_SECOND,max_interval:30*T.ONE_MINUTE,num_minor_ticks:0}),new c.AdaptiveTicker({mantissas:[1,2,4,6,8,12],base:24,min_interval:T.ONE_HOUR,max_interval:12*T.ONE_HOUR,num_minor_ticks:0}),new _.DaysTicker({days:(0,t.range)(1,32)}),new _.DaysTicker({days:(0,t.range)(1,31,3)}),new _.DaysTicker({days:[1,8,15,22]}),new _.DaysTicker({days:[1,15]}),new k.MonthsTicker({months:(0,t.range)(0,12,1)}),new k.MonthsTicker({months:(0,t.range)(0,12,2)}),new k.MonthsTicker({months:(0,t.range)(0,12,4)}),new k.MonthsTicker({months:(0,t.range)(0,12,6)}),new o.YearsTicker({})]})},\n", - " function _(t,e,i,r,s){var n;r();const _=t(149),a=t(9);class l extends _.ContinuousTicker{constructor(t){super(t)}get min_intervals(){return this.tickers.map((t=>t.get_min_interval()))}get max_intervals(){return this.tickers.map((t=>t.get_max_interval()))}get_min_interval(){return this.min_intervals[0]}get_max_interval(){return this.max_intervals[0]}get_best_ticker(t,e,i){const r=e-t,s=this.get_ideal_interval(t,e,i),n=[(0,a.sorted_index)(this.min_intervals,s)-1,(0,a.sorted_index)(this.max_intervals,s)],_=[this.min_intervals[n[0]],this.max_intervals[n[1]]].map((t=>Math.abs(i-r/t)));let l;if((0,a.is_empty)(_.filter((t=>!isNaN(t)))))l=this.tickers[0];else{const t=n[(0,a.argmin)(_)];l=this.tickers[t]}return l}get_interval(t,e,i){return this.get_best_ticker(t,e,i).get_interval(t,e,i)}get_ticks_no_defaults(t,e,i,r){return this.get_best_ticker(t,e,r).get_ticks_no_defaults(t,e,i,r)}}i.CompositeTicker=l,n=l,l.__name__=\"CompositeTicker\",n.define((({Array:t,Ref:e})=>({tickers:[t(e(_.ContinuousTicker)),[]]})))},\n", - " function _(t,e,n,s,o){var a;s();const i=t(158),r=t(159),c=t(9);class _ extends i.SingleIntervalTicker{constructor(t){super(t)}initialize(){super.initialize();const t=this.days;t.length>1?this.interval=(t[1]-t[0])*r.ONE_DAY:this.interval=31*r.ONE_DAY}get_ticks_no_defaults(t,e,n,s){const o=function(t,e){const n=(0,r.last_month_no_later_than)(new Date(t)),s=(0,r.last_month_no_later_than)(new Date(e));s.setUTCMonth(s.getUTCMonth()+1);const o=[],a=n;for(;o.push((0,r.copy_date)(a)),a.setUTCMonth(a.getUTCMonth()+1),!(a>s););return o}(t,e),a=this.days,i=this.interval,_=(0,c.concat)(o.map((t=>((t,e)=>{const n=t.getUTCMonth(),s=[];for(const o of a){const a=(0,r.copy_date)(t);a.setUTCDate(o),new Date(a.getTime()+e/2).getUTCMonth()==n&&s.push(a)}return s})(t,i))));return{major:_.map((t=>t.getTime())).filter((n=>t<=n&&n<=e)),minor:[]}}}n.DaysTicker=_,a=_,_.__name__=\"DaysTicker\",a.define((({Int:t,Array:e})=>({days:[e(t),[]]}))),a.override({num_minor_ticks:0})},\n", - " function _(e,n,t,r,i){var a;r();const l=e(149);class s extends l.ContinuousTicker{constructor(e){super(e)}get_interval(e,n,t){return this.interval}get_min_interval(){return this.interval}get_max_interval(){return this.interval}}t.SingleIntervalTicker=s,a=s,s.__name__=\"SingleIntervalTicker\",a.define((({Number:e})=>({interval:[e]})))},\n", - " function _(t,n,e,_,E){function N(t){return new Date(t.getTime())}function O(t){const n=N(t);return n.setUTCDate(1),n.setUTCHours(0),n.setUTCMinutes(0),n.setUTCSeconds(0),n.setUTCMilliseconds(0),n}_(),e.ONE_MILLI=1,e.ONE_SECOND=1e3,e.ONE_MINUTE=60*e.ONE_SECOND,e.ONE_HOUR=60*e.ONE_MINUTE,e.ONE_DAY=24*e.ONE_HOUR,e.ONE_MONTH=30*e.ONE_DAY,e.ONE_YEAR=365*e.ONE_DAY,e.copy_date=N,e.last_month_no_later_than=O,e.last_year_no_later_than=function(t){const n=O(t);return n.setUTCMonth(0),n}},\n", - " function _(t,e,n,a,r){var s;a();const i=t(158),o=t(159),l=t(9);class _ extends i.SingleIntervalTicker{constructor(t){super(t)}initialize(){super.initialize();const t=this.months;t.length>1?this.interval=(t[1]-t[0])*o.ONE_MONTH:this.interval=12*o.ONE_MONTH}get_ticks_no_defaults(t,e,n,a){const r=function(t,e){const n=(0,o.last_year_no_later_than)(new Date(t)),a=(0,o.last_year_no_later_than)(new Date(e));a.setUTCFullYear(a.getUTCFullYear()+1);const r=[],s=n;for(;r.push((0,o.copy_date)(s)),s.setUTCFullYear(s.getUTCFullYear()+1),!(s>a););return r}(t,e),s=this.months;return{major:(0,l.concat)(r.map((t=>s.map((e=>{const n=(0,o.copy_date)(t);return n.setUTCMonth(e),n}))))).map((t=>t.getTime())).filter((n=>t<=n&&n<=e)),minor:[]}}}n.MonthsTicker=_,s=_,_.__name__=\"MonthsTicker\",s.define((({Int:t,Array:e})=>({months:[e(t),[]]})))},\n", - " function _(e,t,a,i,r){i();const n=e(147),_=e(158),s=e(159);class c extends _.SingleIntervalTicker{constructor(e){super(e)}initialize(){super.initialize(),this.interval=s.ONE_YEAR,this.basic_ticker=new n.BasicTicker({num_minor_ticks:0})}get_ticks_no_defaults(e,t,a,i){const r=(0,s.last_year_no_later_than)(new Date(e)).getUTCFullYear(),n=(0,s.last_year_no_later_than)(new Date(t)).getUTCFullYear();return{major:this.basic_ticker.get_ticks_no_defaults(r,n,a,i).major.map((e=>Date.UTC(e,0,1))).filter((a=>e<=a&&a<=t)),minor:[]}}}a.YearsTicker=c,c.__name__=\"YearsTicker\"},\n", - " function _(e,o,i,s,t){var n;s();const r=e(143),_=e(163),c=e(164);class a extends r.ContinuousAxisView{}i.LogAxisView=a,a.__name__=\"LogAxisView\";class u extends r.ContinuousAxis{constructor(e){super(e)}}i.LogAxis=u,n=u,u.__name__=\"LogAxis\",n.prototype.default_view=a,n.override({ticker:()=>new c.LogTicker,formatter:()=>new _.LogTickFormatter})},\n", - " function _(e,t,n,o,r){var i;o();const a=e(131),s=e(146),c=e(164),l=e(120),{abs:u,log:x,round:_}=Math;class p extends a.TickFormatter{constructor(e){super(e)}initialize(){super.initialize(),this.basic_formatter=new s.BasicTickFormatter}format_graphics(e,t){var n,o;if(0==e.length)return[];const r=null!==(o=null===(n=this.ticker)||void 0===n?void 0:n.base)&&void 0!==o?o:10,i=this._exponents(e,r);return null==i?this.basic_formatter.format_graphics(e,t):i.map((e=>{if(u(e)u(e)({ticker:[n(t(c.LogTicker)),null],min_exponent:[e,0]})))},\n", - " function _(t,o,e,s,n){var r;s();const i=t(148),a=t(9);class c extends i.AdaptiveTicker{constructor(t){super(t)}get_ticks_no_defaults(t,o,e,s){const n=this.num_minor_ticks,r=[],i=this.base,c=Math.log(t)/Math.log(i),f=Math.log(o)/Math.log(i),l=f-c;let h;if(isFinite(l))if(l<2){const e=this.get_interval(t,o,s),i=Math.floor(t/e),c=Math.ceil(o/e);if(h=(0,a.range)(i,c+1).filter((t=>0!=t)).map((t=>t*e)).filter((e=>t<=e&&e<=o)),n>0&&h.length>0){const t=e/n,o=(0,a.range)(0,n).map((o=>o*t));for(const t of o.slice(1))r.push(h[0]-t);for(const t of h)for(const e of o)r.push(t+e)}}else{const t=Math.ceil(.999999*c),o=Math.floor(1.000001*f),e=Math.ceil((o-t)/9);if(h=(0,a.range)(t-1,o+1,e).map((t=>i**t)),n>0&&h.length>0){const t=i**e/n,o=(0,a.range)(1,n+1).map((o=>o*t));for(const t of o)r.push(h[0]/t);r.push(h[0]);for(const t of h)for(const e of o)r.push(t*e)}}else h=[];return{major:h.filter((e=>t<=e&&e<=o)),minor:r.filter((e=>t<=e&&e<=o))}}}e.LogTicker=c,r=c,c.__name__=\"LogTicker\",r.override({mantissas:[1,5]})},\n", - " function _(e,r,t,i,a){var o;i();const s=e(128),c=e(145),n=e(166),_=e(167);class x extends s.AxisView{}t.MercatorAxisView=x,x.__name__=\"MercatorAxisView\";class d extends c.LinearAxis{constructor(e){super(e)}}t.MercatorAxis=d,o=d,d.__name__=\"MercatorAxis\",o.prototype.default_view=x,o.override({ticker:()=>new _.MercatorTicker({dimension:\"lat\"}),formatter:()=>new n.MercatorTickFormatter({dimension:\"lat\"})})},\n", - " function _(r,t,e,o,n){var i;o();const c=r(146),s=r(20),a=r(78);class l extends c.BasicTickFormatter{constructor(r){super(r)}doFormat(r,t){if(null==this.dimension)throw new Error(\"MercatorTickFormatter.dimension not configured\");if(0==r.length)return[];const e=r.length,o=new Array(e);if(\"lon\"==this.dimension)for(let n=0;n({dimension:[r(s.LatLon),null]})))},\n", - " function _(t,o,n,s,r){var e;s();const i=t(147),c=t(20),_=t(78);class a extends i.BasicTicker{constructor(t){super(t)}get_ticks_no_defaults(t,o,n,s){if(null==this.dimension)throw new Error(`${this}.dimension wasn't configured`);return[t,o]=(0,_.clip_mercator)(t,o,this.dimension),\"lon\"==this.dimension?this._get_ticks_lon(t,o,n,s):this._get_ticks_lat(t,o,n,s)}_get_ticks_lon(t,o,n,s){const[r]=_.wgs84_mercator.invert(t,n),[e,i]=_.wgs84_mercator.invert(o,n),c=super.get_ticks_no_defaults(r,e,n,s),a=[];for(const t of c.major)if((0,_.in_bounds)(t,\"lon\")){const[o]=_.wgs84_mercator.compute(t,i);a.push(o)}const m=[];for(const t of c.minor)if((0,_.in_bounds)(t,\"lon\")){const[o]=_.wgs84_mercator.compute(t,i);m.push(o)}return{major:a,minor:m}}_get_ticks_lat(t,o,n,s){const[,r]=_.wgs84_mercator.invert(n,t),[e,i]=_.wgs84_mercator.invert(n,o),c=super.get_ticks_no_defaults(r,i,n,s),a=[];for(const t of c.major)if((0,_.in_bounds)(t,\"lat\")){const[,o]=_.wgs84_mercator.compute(e,t);a.push(o)}const m=[];for(const t of c.minor)if((0,_.in_bounds)(t,\"lat\")){const[,o]=_.wgs84_mercator.compute(e,t);m.push(o)}return{major:a,minor:m}}}n.MercatorTicker=a,e=a,a.__name__=\"MercatorTicker\",e.define((({Nullable:t})=>({dimension:[t(c.LatLon),null]})))},\n", - " function _(e,i,r,c,k){c(),k(\"AdaptiveTicker\",e(148).AdaptiveTicker),k(\"BasicTicker\",e(147).BasicTicker),k(\"CategoricalTicker\",e(141).CategoricalTicker),k(\"CompositeTicker\",e(156).CompositeTicker),k(\"ContinuousTicker\",e(149).ContinuousTicker),k(\"DatetimeTicker\",e(155).DatetimeTicker),k(\"DaysTicker\",e(157).DaysTicker),k(\"FixedTicker\",e(169).FixedTicker),k(\"LogTicker\",e(164).LogTicker),k(\"MercatorTicker\",e(167).MercatorTicker),k(\"MonthsTicker\",e(160).MonthsTicker),k(\"SingleIntervalTicker\",e(158).SingleIntervalTicker),k(\"Ticker\",e(130).Ticker),k(\"YearsTicker\",e(161).YearsTicker),k(\"BinnedTicker\",e(170).BinnedTicker)},\n", - " function _(r,t,e,i,n){var s;i();const _=r(149);class c extends _.ContinuousTicker{constructor(r){super(r)}get_ticks_no_defaults(r,t,e,i){return{major:this.ticks,minor:this.minor_ticks}}get_interval(r,t,e){return 0}get_min_interval(){return 0}get_max_interval(){return 0}}e.FixedTicker=c,s=c,c.__name__=\"FixedTicker\",s.define((({Number:r,Array:t})=>({ticks:[t(r),[]],minor_ticks:[t(r),[]]})))},\n", - " function _(e,n,t,r,i){var o;r();const a=e(130),s=e(171),c=e(12);class m extends a.Ticker{constructor(e){super(e)}get_ticks(e,n,t,r){const{binning:i}=this.mapper.metrics,o=Math.max(0,(0,c.left_edge_index)(e,i)),a=Math.min((0,c.left_edge_index)(n,i)+1,i.length-1),s=[];for(let e=o;e<=a;e++)s.push(i[e]);const{num_major_ticks:m}=this,_=[],h=\"auto\"==m?s.length:m,l=Math.max(1,Math.floor(s.length/h));for(let e=0;e({mapper:[n(s.ScanningColorMapper)],num_major_ticks:[t(e,r),8]})))},\n", - " function _(n,e,i,r,o){r();const t=n(172),a=n(12);class c extends t.ContinuousColorMapper{constructor(n){super(n)}cmap(n,e,i,r,o){if(no.binning[o.binning.length-1])return r;return e[(0,a.left_edge_index)(n,o.binning)]}}i.ScanningColorMapper=c,c.__name__=\"ScanningColorMapper\"},\n", - " function _(t,e,o,n,s){var l;n();const c=t(173),i=t(175),a=t(9),h=t(8);class r extends c.ColorMapper{constructor(t){super(t),this._scan_data=null}connect_signals(){super.connect_signals();const t=()=>{for(const[t]of this.domain)this.connect(t.view.change,(()=>this.update_data())),this.connect(t.data_source.selected.change,(()=>this.update_data()))};this.connect(this.properties.domain.change,(()=>t())),t()}update_data(){const{domain:t,palette:e}=this,o=[...this._collect(t)];this._scan_data=this.scan(o,e.length),this.metrics_change.emit(),this.change.emit()}get metrics(){return null==this._scan_data&&this.update_data(),this._scan_data}*_collect(t){for(const[e,o]of t)for(const t of(0,h.isArray)(o)?o:[o]){let o=e.data_source.get_column(t);o=e.view.indices.select(o);const n=e.view.masked,s=e.data_source.selected.indices;let l;if(null!=n&&s.length>0?l=(0,a.intersection)([...n],s):null!=n?l=[...n]:s.length>0&&(l=s),null!=l&&(o=(0,a.map)(l,(t=>o[t]))),o.length>0&&!(0,h.isNumber)(o[0]))for(const t of o)yield*t;else yield*o}}_v_compute(t,e,o,n){const{nan_color:s}=n;let{low_color:l,high_color:c}=n;null==l&&(l=o[0]),null==c&&(c=o[o.length-1]);const{domain:i}=this,h=(0,a.is_empty)(i)?t:[...this._collect(i)];this._scan_data=this.scan(h,o.length),this.metrics_change.emit();for(let n=0,i=t.length;n({high:[a(t),null],low:[a(t),null],high_color:[a(n),null],low_color:[a(n),null],domain:[c(l(o(i.GlyphRenderer),s(e,c(e)))),[]]})))},\n", - " function _(e,r,t,n,o){var a;n();const c=e(174),i=e(15),_=e(24),l=e(22),s=e(27);function p(e){return(0,l.encode_rgba)((0,l.color2rgba)(e))}function u(e){const r=new Uint32Array(e.length);for(let t=0,n=e.length;te))),r}get rgba_mapper(){const e=this,r=u(this.palette),t=this._colors(p);return{v_compute(n){const o=new _.ColorArray(n.length);return e._v_compute(n,o,r,t),new Uint8ClampedArray((0,s.to_big_endian)(o).buffer)}}}_colors(e){return{nan_color:e(this.nan_color)}}}t.ColorMapper=h,a=h,h.__name__=\"ColorMapper\",a.define((({Color:e,Array:r})=>({palette:[r(e)],nan_color:[e,\"gray\"]})))},\n", - " function _(r,e,n,s,o){s();const p=r(56);class t extends p.Transform{constructor(r){super(r)}compute(r){throw new Error(\"mapping single values is not supported\")}}n.Mapper=t,t.__name__=\"Mapper\"},\n", - " function _(e,t,i,s,l){var h;s();const n=e(176),o=e(177),a=e(186),c=e(187),_=e(189),r=e(179),d=e(70),p=e(190),g=e(24),u=e(12),y=e(13),m=e(113),v=e(67),f={fill:{},line:{}},w={fill:{fill_alpha:.3,fill_color:\"grey\"},line:{line_alpha:.3,line_color:\"grey\"}},b={fill:{fill_alpha:.2},line:{}},V={fill:{fill_alpha:.2},line:{}};class x extends n.DataRendererView{get glyph_view(){return this.glyph}async lazy_initialize(){var e;await super.lazy_initialize();const t=this.model.glyph;this.glyph=await this.build_glyph_view(t);const i=\"fill\"in this.glyph.visuals,s=\"line\"in this.glyph.visuals,l=Object.assign({},t.attributes);function h(e){const h=(0,y.clone)(l);return i&&(0,y.extend)(h,e.fill),s&&(0,y.extend)(h,e.line),new t.constructor(h)}function n(e,t){return t instanceof r.Glyph?t:h(\"auto\"==t?e:{fill:{},line:{}})}delete l.id;let{selection_glyph:o,nonselection_glyph:a,hover_glyph:c,muted_glyph:_}=this.model;o=n(f,o),this.selection_glyph=await this.build_glyph_view(o),a=n(b,a),this.nonselection_glyph=await this.build_glyph_view(a),null!=c&&(this.hover_glyph=await this.build_glyph_view(c)),_=n(V,_),this.muted_glyph=await this.build_glyph_view(_);const d=n(w,\"auto\");this.decimated_glyph=await this.build_glyph_view(d),this.selection_glyph.set_base(this.glyph),this.nonselection_glyph.set_base(this.glyph),null===(e=this.hover_glyph)||void 0===e||e.set_base(this.glyph),this.muted_glyph.set_base(this.glyph),this.decimated_glyph.set_base(this.glyph),this.set_data()}async build_glyph_view(e){return(0,m.build_view)(e,{parent:this})}remove(){var e;this.glyph.remove(),this.selection_glyph.remove(),this.nonselection_glyph.remove(),null===(e=this.hover_glyph)||void 0===e||e.remove(),this.muted_glyph.remove(),this.decimated_glyph.remove(),super.remove()}connect_signals(){super.connect_signals();const e=()=>this.request_render(),t=()=>this.update_data();this.connect(this.model.change,e),this.connect(this.glyph.model.change,t),this.connect(this.selection_glyph.model.change,t),this.connect(this.nonselection_glyph.model.change,t),null!=this.hover_glyph&&this.connect(this.hover_glyph.model.change,t),this.connect(this.muted_glyph.model.change,t),this.connect(this.decimated_glyph.model.change,t),this.connect(this.model.data_source.change,t),this.connect(this.model.data_source.streaming,t),this.connect(this.model.data_source.patching,(e=>this.update_data(e))),this.connect(this.model.data_source.selected.change,e),this.connect(this.model.data_source._select,e),null!=this.hover_glyph&&this.connect(this.model.data_source.inspect,e),this.connect(this.model.properties.view.change,t),this.connect(this.model.view.properties.indices.change,t),this.connect(this.model.view.properties.masked.change,(()=>this.set_visuals())),this.connect(this.model.properties.visible.change,(()=>this.plot_view.invalidate_dataranges=!0));const{x_ranges:i,y_ranges:s}=this.plot_view.frame;for(const[,e]of i)e instanceof v.FactorRange&&this.connect(e.change,t);for(const[,e]of s)e instanceof v.FactorRange&&this.connect(e.change,t);const{transformchange:l,exprchange:h}=this.model.glyph;this.connect(l,t),this.connect(h,t)}_update_masked_indices(){const e=this.glyph.mask_data();return this.model.view.masked=e,e}update_data(e){this.set_data(e),this.request_render()}set_data(e){const t=this.model.data_source;this.all_indices=this.model.view.indices;const{all_indices:i}=this;this.glyph.set_data(t,i,e),this.set_visuals(),this._update_masked_indices();const{lod_factor:s}=this.plot_model,l=this.all_indices.count;this.decimated=new g.Indices(l);for(let e=0;e!n||n.is_empty()?[]:n.selected_glyph?this.model.view.convert_indices_from_subset(i):n.indices.length>0?n.indices:Object.keys(n.multiline_indices).map((e=>parseInt(e))))()),d=(0,u.filter)(i,(e=>r.has(t[e]))),{lod_threshold:p}=this.plot_model;let g,y,m;if(null!=this.model.document&&this.model.document.interactive_duration()>0&&!e&&null!=p&&t.length>p?(i=[...this.decimated],g=this.decimated_glyph,y=this.decimated_glyph,m=this.selection_glyph):(g=this.model.muted?this.muted_glyph:this.glyph,y=this.nonselection_glyph,m=this.selection_glyph),null!=this.hover_glyph&&d.length){const e=new Set(i);for(const t of d)e.delete(t);i=[...e]}if(h.length){const e={};for(const t of h)e[t]=!0;const l=new Array,n=new Array;if(this.glyph instanceof o.LineView)for(const i of t)null!=e[i]?l.push(i):n.push(i);else for(const s of i)null!=e[t[s]]?l.push(s):n.push(s);y.render(s,n),m.render(s,l),null!=this.hover_glyph&&(this.glyph instanceof o.LineView?this.hover_glyph.render(s,this.model.view.convert_indices_from_subset(d)):this.hover_glyph.render(s,d))}else if(this.glyph instanceof o.LineView)this.hover_glyph&&d.length?this.hover_glyph.render(s,this.model.view.convert_indices_from_subset(d)):g.render(s,t);else if(this.glyph instanceof a.PatchView||this.glyph instanceof c.HAreaView||this.glyph instanceof _.VAreaView)if(0==n.selected_glyphs.length||null==this.hover_glyph)g.render(s,t);else for(const e of n.selected_glyphs)e==this.glyph.model&&this.hover_glyph.render(s,t);else g.render(s,i),this.hover_glyph&&d.length&&this.hover_glyph.render(s,d);s.restore()}draw_legend(e,t,i,s,l,h,n,o){0!=this.glyph.data_size&&(null==o&&(o=this.model.get_reference_point(h,n)),this.glyph.draw_legend_for_index(e,{x0:t,x1:i,y0:s,y1:l},o))}hit_test(e){if(!this.model.visible)return null;const t=this.glyph.hit_test(e);return null==t?null:this.model.view.convert_selection_from_subset(t)}}i.GlyphRendererView=x,x.__name__=\"GlyphRendererView\";class G extends n.DataRenderer{constructor(e){super(e)}initialize(){super.initialize(),this.view.source!=this.data_source&&(this.view.source=this.data_source,this.view.compute_indices())}get_reference_point(e,t){if(null!=e){const i=this.data_source.get_column(e);if(null!=i)for(const[e,s]of Object.entries(this.view.indices_map))if(i[parseInt(e)]==t)return s}return 0}get_selection_manager(){return this.data_source.selection_manager}}i.GlyphRenderer=G,h=G,G.__name__=\"GlyphRenderer\",h.prototype.default_view=x,h.define((({Boolean:e,Auto:t,Or:i,Ref:s,Null:l,Nullable:h})=>({data_source:[s(d.ColumnarDataSource)],view:[s(p.CDSView),e=>new p.CDSView({source:e.data_source})],glyph:[s(r.Glyph)],hover_glyph:[h(s(r.Glyph)),null],nonselection_glyph:[i(s(r.Glyph),t,l),\"auto\"],selection_glyph:[i(s(r.Glyph),t,l),\"auto\"],muted_glyph:[i(s(r.Glyph),t,l),\"auto\"],muted:[e,!1]})))},\n", - " function _(e,r,t,a,n){var s;a();const c=e(41);class _ extends c.RendererView{get xscale(){return this.coordinates.x_scale}get yscale(){return this.coordinates.y_scale}}t.DataRendererView=_,_.__name__=\"DataRendererView\";class i extends c.Renderer{constructor(e){super(e)}get selection_manager(){return this.get_selection_manager()}}t.DataRenderer=i,s=i,i.__name__=\"DataRenderer\",s.override({level:\"glyph\"})},\n", - " function _(e,t,i,s,n){s();const l=e(1);var _;const r=e(178),o=e(184),a=(0,l.__importStar)(e(48)),h=(0,l.__importStar)(e(185)),c=e(72);class d extends r.XYGlyphView{async lazy_initialize(){await super.lazy_initialize();const{webgl:t}=this.renderer.plot_view.canvas_view;if(null==t?void 0:t.regl_wrapper.has_webgl){const{LineGL:i}=await Promise.resolve().then((()=>(0,l.__importStar)(e(426))));this.glglyph=new i(t.regl_wrapper,this)}}_render(e,t,i){const{sx:s,sy:n}=null!=i?i:this;let l=null;const _=e=>null!=l&&e-l!=1;let r=!0;e.beginPath();for(const i of t){const t=s[i],o=n[i];isFinite(t+o)?r||_(i)?(e.moveTo(t,o),r=!1):e.lineTo(t,o):r=!0,l=i}this.visuals.line.set_value(e),e.stroke()}_hit_point(e){const t=new c.Selection,i={x:e.sx,y:e.sy};let s=9999;const n=Math.max(2,this.line_width.value/2);for(let e=0,l=this.sx.length-1;e({x:[c.XCoordinateSpec,{field:\"x\"}],y:[c.YCoordinateSpec,{field:\"y\"}]})))},\n", - " function _(e,t,s,i,n){i();const r=e(1),a=(0,r.__importStar)(e(18)),o=(0,r.__importStar)(e(65)),_=(0,r.__importStar)(e(45)),l=e(42),c=e(53),h=e(19),d=e(24),u=e(8),f=e(180),p=e(12),g=e(26),y=e(181),x=e(67),v=e(72),{abs:b,ceil:m}=Math;class w extends l.View{constructor(){super(...arguments),this._index=null,this._data_size=null,this._nohit_warned=new Set}get renderer(){return this.parent}get has_webgl(){return null!=this.glglyph}get index(){const{_index:e}=this;if(null!=e)return e;throw new Error(`${this}.index_data() wasn't called`)}get data_size(){const{_data_size:e}=this;if(null!=e)return e;throw new Error(`${this}.set_data() wasn't called`)}initialize(){super.initialize(),this.visuals=new _.Visuals(this)}request_render(){this.parent.request_render()}get canvas(){return this.renderer.parent.canvas_view}render(e,t,s){var i;null!=this.glglyph&&(this.renderer.needs_webgl_blit=this.glglyph.render(e,t,null!==(i=this.base)&&void 0!==i?i:this),this.renderer.needs_webgl_blit)||this._render(e,t,null!=s?s:this.base)}has_finished(){return!0}notify_finished(){this.renderer.notify_finished()}_bounds(e){return e}bounds(){return this._bounds(this.index.bbox)}log_bounds(){const{x0:e,x1:t}=this.index.bounds(o.positive_x()),{y0:s,y1:i}=this.index.bounds(o.positive_y());return this._bounds({x0:e,y0:s,x1:t,y1:i})}get_anchor_point(e,t,[s,i]){switch(e){case\"center\":case\"center_center\":{const[e,n]=this.scenterxy(t,s,i);return{x:e,y:n}}default:return null}}scenterx(e,t,s){return this.scenterxy(e,t,s)[0]}scentery(e,t,s){return this.scenterxy(e,t,s)[1]}sdist(e,t,s,i=\"edge\",n=!1){const r=t.length,a=new d.ScreenArray(r),o=e.s_compute;if(\"center\"==i)for(let e=0;em(e))),a}draw_legend_for_index(e,t,s){}hit_test(e){switch(e.type){case\"point\":if(null!=this._hit_point)return this._hit_point(e);break;case\"span\":if(null!=this._hit_span)return this._hit_span(e);break;case\"rect\":if(null!=this._hit_rect)return this._hit_rect(e);break;case\"poly\":if(null!=this._hit_poly)return this._hit_poly(e)}return this._nohit_warned.has(e.type)||(h.logger.debug(`'${e.type}' selection not available for ${this.model.type}`),this._nohit_warned.add(e.type)),null}_hit_rect_against_index(e){const{sx0:t,sx1:s,sy0:i,sy1:n}=e,[r,a]=this.renderer.coordinates.x_scale.r_invert(t,s),[o,_]=this.renderer.coordinates.y_scale.r_invert(i,n),l=[...this.index.indices({x0:r,x1:a,y0:o,y1:_})];return new v.Selection({indices:l})}_project_data(){}*_iter_visuals(){for(const e of this.visuals)for(const t of e)(t instanceof a.VectorSpec||t instanceof a.ScalarSpec)&&(yield t)}set_base(e){e!=this&&e instanceof this.constructor&&(this.base=e)}_configure(e,t){Object.defineProperty(this,(0,u.isString)(e)?e:e.attr,Object.assign({configurable:!0,enumerable:!0},t))}set_visuals(e,t){var s;for(const s of this._iter_visuals()){const{base:i}=this;if(null!=i){const e=i.model.properties[s.attr];if(null!=e&&(0,g.is_equal)(s.get_value(),e.get_value())){this._configure(s,{get:()=>i[`${s.attr}`]});continue}}const n=s.uniform(e).select(t);this._configure(s,{value:n})}for(const e of this.visuals)e.update();null===(s=this.glglyph)||void 0===s||s.set_visuals_changed()}set_data(e,t,s){var i;const{x_source:n,y_source:r}=this.renderer.coordinates,o=new Set(this._iter_visuals());this._data_size=t.count;for(const s of this.model)if((s instanceof a.VectorSpec||s instanceof a.ScalarSpec)&&!o.has(s))if(s instanceof a.BaseCoordinateSpec){const i=s.array(e);let o=t.select(i);const _=\"x\"==s.dimension?n:r;if(_ instanceof x.FactorRange)if(s instanceof a.CoordinateSpec)o=_.v_synthetic(o);else if(s instanceof a.CoordinateSeqSpec)for(let e=0;e{const s=new Uint32Array(r);for(let a=0;a>1;t[s]>i?e=s:n=s+1}return t[n]}class r extends d.default{get boxes(){return this._boxes}search_indices(i,t,n,e){if(this._pos!==this._boxes.length)throw new Error(\"Data not yet indexed - call index.finish().\");let s=this._boxes.length-4;const d=[],x=new o.Indices(this.numItems);for(;void 0!==s;){const o=Math.min(s+4*this.nodeSize,h(s,this._levelBounds));for(let h=s;h>2],r=this._boxes[h+0],l=this._boxes[h+1],a=this._boxes[h+2],_=this._boxes[h+3];na||t>_||(s<4*this.numItems?x.set(o):d.push(o)))}s=d.pop()}return x}}r.__name__=\"_FlatBush\";class l{constructor(i){this.index=null,i>0&&(this.index=new r(i))}add_rect(i,t,n,e){var s;isFinite(i+t+n+e)?null===(s=this.index)||void 0===s||s.add(i,t,n,e):this.add_empty()}add_point(i,t){var n;isFinite(i+t)?null===(n=this.index)||void 0===n||n.add(i,t,i,t):this.add_empty()}add_empty(){var i;null===(i=this.index)||void 0===i||i.add(1/0,1/0,-1/0,-1/0)}finish(){var i;null===(i=this.index)||void 0===i||i.finish()}_normalize(i){let{x0:t,y0:n,x1:e,y1:s}=i;return t>e&&([t,e]=[e,t]),n>s&&([n,s]=[s,n]),{x0:t,y0:n,x1:e,y1:s}}get bbox(){if(null==this.index)return(0,x.empty)();{const{minX:i,minY:t,maxX:n,maxY:e}=this.index;return{x0:i,y0:t,x1:n,y1:e}}}indices(i){if(null==this.index)return new o.Indices(0);{const{x0:t,y0:n,x1:e,y1:s}=this._normalize(i);return this.index.search_indices(t,n,e,s)}}bounds(i){const t=(0,x.empty)();if(null==this.index)return t;const{boxes:n}=this.index;for(const e of this.indices(i)){const s=n[4*e+0],d=n[4*e+1],o=n[4*e+2],x=n[4*e+3];s>=i.x0&&st.x1&&(t.x1=o),d>=i.y0&&dt.y1&&(t.y1=x)}return t}}n.SpatialIndex=l,l.__name__=\"SpatialIndex\"},\n", - " function _(t,s,i,e,h){e();const n=(0,t(1).__importDefault)(t(183)),o=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class r{static from(t){if(!(t instanceof ArrayBuffer))throw new Error(\"Data must be an instance of ArrayBuffer.\");const[s,i]=new Uint8Array(t,0,2);if(251!==s)throw new Error(\"Data does not appear to be in a Flatbush format.\");if(i>>4!=3)throw new Error(`Got v${i>>4} data when expected v3.`);const[e]=new Uint16Array(t,2,1),[h]=new Uint32Array(t,4,1);return new r(h,e,o[15&i],t)}constructor(t,s=16,i=Float64Array,e){if(void 0===t)throw new Error(\"Missing required argument: numItems.\");if(isNaN(t)||t<=0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+s,2),65535);let h=t,r=h;this._levelBounds=[4*h];do{h=Math.ceil(h/this.nodeSize),r+=h,this._levelBounds.push(4*r)}while(1!==h);this.ArrayType=i||Float64Array,this.IndexArrayType=r<16384?Uint16Array:Uint32Array;const a=o.indexOf(this.ArrayType),_=4*r*this.ArrayType.BYTES_PER_ELEMENT;if(a<0)throw new Error(`Unexpected typed array class: ${i}.`);e&&e instanceof ArrayBuffer?(this.data=e,this._boxes=new this.ArrayType(this.data,8,4*r),this._indices=new this.IndexArrayType(this.data,8+_,r),this._pos=4*r,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1]):(this.data=new ArrayBuffer(8+_+r*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,4*r),this._indices=new this.IndexArrayType(this.data,8+_,r),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(this.data,0,2).set([251,48+a]),new Uint16Array(this.data,2,1)[0]=s,new Uint32Array(this.data,4,1)[0]=t),this._queue=new n.default}add(t,s,i,e){const h=this._pos>>2;return this._indices[h]=h,this._boxes[this._pos++]=t,this._boxes[this._pos++]=s,this._boxes[this._pos++]=i,this._boxes[this._pos++]=e,tthis.maxX&&(this.maxX=i),e>this.maxY&&(this.maxY=e),h}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);if(this.numItems<=this.nodeSize)return this._boxes[this._pos++]=this.minX,this._boxes[this._pos++]=this.minY,this._boxes[this._pos++]=this.maxX,void(this._boxes[this._pos++]=this.maxY);const t=this.maxX-this.minX,s=this.maxY-this.minY,i=new Uint32Array(this.numItems);for(let e=0;e>2]=t,this._boxes[this._pos++]=e,this._boxes[this._pos++]=h,this._boxes[this._pos++]=n,this._boxes[this._pos++]=o}}}search(t,s,i,e,h){if(this._pos!==this._boxes.length)throw new Error(\"Data not yet indexed - call index.finish().\");let n=this._boxes.length-4;const o=[],r=[];for(;void 0!==n;){const a=Math.min(n+4*this.nodeSize,_(n,this._levelBounds));for(let _=n;_>2];ithis._boxes[_+2]||s>this._boxes[_+3]||(n<4*this.numItems?(void 0===h||h(a))&&r.push(a):o.push(a)))}n=o.pop()}return r}neighbors(t,s,i=1/0,e=1/0,h){if(this._pos!==this._boxes.length)throw new Error(\"Data not yet indexed - call index.finish().\");let n=this._boxes.length-4;const o=this._queue,r=[],x=e*e;for(;void 0!==n;){const e=Math.min(n+4*this.nodeSize,_(n,this._levelBounds));for(let i=n;i>2],r=a(t,this._boxes[i],this._boxes[i+2]),_=a(s,this._boxes[i+1],this._boxes[i+3]),x=r*r+_*_;n<4*this.numItems?(void 0===h||h(e))&&o.push(-e-1,x):o.push(e,x)}for(;o.length&&o.peek()<0;){if(o.peekValue()>x)return o.clear(),r;if(r.push(-o.pop()-1),r.length===i)return o.clear(),r}n=o.pop()}return o.clear(),r}}function a(t,s,i){return t>1;s[h]>t?e=h:i=h+1}return s[i]}function x(t,s,i,e,h,n){if(Math.floor(e/n)>=Math.floor(h/n))return;const o=t[e+h>>1];let r=e-1,a=h+1;for(;;){do{r++}while(t[r]o);if(r>=a)break;d(t,s,i,r,a)}x(t,s,i,e,a,n),x(t,s,i,a+1,h,n)}function d(t,s,i,e,h){const n=t[e];t[e]=t[h],t[h]=n;const o=4*e,r=4*h,a=s[o],_=s[o+1],x=s[o+2],d=s[o+3];s[o]=s[r],s[o+1]=s[r+1],s[o+2]=s[r+2],s[o+3]=s[r+3],s[r]=a,s[r+1]=_,s[r+2]=x,s[r+3]=d;const m=i[e];i[e]=i[h],i[h]=m}function m(t,s){let i=t^s,e=65535^i,h=65535^(t|s),n=t&(65535^s),o=i|e>>1,r=i>>1^i,a=h>>1^e&n>>1^h,_=i&h>>1^n>>1^n;i=o,e=r,h=a,n=_,o=i&i>>2^e&e>>2,r=i&e>>2^e&(i^e)>>2,a^=i&h>>2^e&n>>2,_^=e&h>>2^(i^e)&n>>2,i=o,e=r,h=a,n=_,o=i&i>>4^e&e>>4,r=i&e>>4^e&(i^e)>>4,a^=i&h>>4^e&n>>4,_^=e&h>>4^(i^e)&n>>4,i=o,e=r,h=a,n=_,a^=i&h>>8^e&n>>8,_^=e&h>>8^(i^e)&n>>8,i=a^a>>1,e=_^_>>1;let x=t^s,d=e|65535^(x|i);return x=16711935&(x|x<<8),x=252645135&(x|x<<4),x=858993459&(x|x<<2),x=1431655765&(x|x<<1),d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),(d<<1|x)>>>0}i.default=r},\n", - " function _(s,t,i,h,e){h();i.default=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(s,t){let i=this.length++;for(this.ids[i]=s,this.values[i]=t;i>0;){const s=i-1>>1,h=this.values[s];if(t>=h)break;this.ids[i]=this.ids[s],this.values[i]=h,i=s}this.ids[i]=s,this.values[i]=t}pop(){if(0===this.length)return;const s=this.ids[0];if(this.length--,this.length>0){const s=this.ids[0]=this.ids[this.length],t=this.values[0]=this.values[this.length],i=this.length>>1;let h=0;for(;h=t)break;this.ids[h]=e,this.values[h]=l,h=s}this.ids[h]=s,this.values[h]=t}return s}peek(){if(0!==this.length)return this.ids[0]}peekValue(){if(0!==this.length)return this.values[0]}}},\n", - " function _(e,n,a,t,i){t();const l=(0,e(1).__importStar)(e(185));function r(e,n,{x0:a,x1:t,y0:i,y1:l},r){n.save(),n.beginPath(),n.moveTo(a,(i+l)/2),n.lineTo(t,(i+l)/2),e.line.apply(n,r),n.restore()}function c(e,n,{x0:a,x1:t,y0:i,y1:l},r){var c,o;const _=.1*Math.abs(t-a),s=.1*Math.abs(l-i),y=a+_,p=t-_,g=i+s,h=l-s;n.beginPath(),n.rect(y,g,p-y,h-g),e.fill.apply(n,r),null===(c=e.hatch)||void 0===c||c.apply(n,r),null===(o=e.line)||void 0===o||o.apply(n,r)}a.generic_line_scalar_legend=function(e,n,{x0:a,x1:t,y0:i,y1:l}){n.save(),n.beginPath(),n.moveTo(a,(i+l)/2),n.lineTo(t,(i+l)/2),e.line.apply(n),n.restore()},a.generic_line_vector_legend=r,a.generic_line_legend=r,a.generic_area_scalar_legend=function(e,n,{x0:a,x1:t,y0:i,y1:l}){var r,c;const o=.1*Math.abs(t-a),_=.1*Math.abs(l-i),s=a+o,y=t-o,p=i+_,g=l-_;n.beginPath(),n.rect(s,p,y-s,g-p),e.fill.apply(n),null===(r=e.hatch)||void 0===r||r.apply(n),null===(c=e.line)||void 0===c||c.apply(n)},a.generic_area_vector_legend=c,a.generic_area_legend=c,a.line_interpolation=function(e,n,a,t,i,r){const{sx:c,sy:o}=n;let _,s,y,p;\"point\"==n.type?([y,p]=e.yscale.r_invert(o-1,o+1),[_,s]=e.xscale.r_invert(c-1,c+1)):\"v\"==n.direction?([y,p]=e.yscale.r_invert(o,o),[_,s]=[Math.min(a-1,i-1),Math.max(a+1,i+1)]):([_,s]=e.xscale.r_invert(c,c),[y,p]=[Math.min(t-1,r-1),Math.max(t+1,r+1)]);const{x:g,y:h}=l.check_2_segments_intersect(_,y,s,p,a,t,i,r);return[g,h]}},\n", - " function _(t,n,e,i,r){function s(t,n){return(t.x-n.x)**2+(t.y-n.y)**2}function o(t,n,e){const i=s(n,e);if(0==i)return s(t,n);const r=((t.x-n.x)*(e.x-n.x)+(t.y-n.y)*(e.y-n.y))/i;if(r<0)return s(t,n);if(r>1)return s(t,e);return s(t,{x:n.x+r*(e.x-n.x),y:n.y+r*(e.y-n.y)})}i(),e.point_in_poly=function(t,n,e,i){let r=!1,s=e[e.length-1],o=i[i.length-1];for(let u=0;u0&&_<1&&h>0&&h<1,x:t+_*(e-t),y:n+_*(i-n)}}}},\n", - " function _(t,s,e,i,a){i();const l=t(1);var n;const _=t(178),o=t(184),c=(0,l.__importStar)(t(185)),h=(0,l.__importStar)(t(48)),r=t(72);class p extends _.XYGlyphView{_render(t,s,e){const{sx:i,sy:a}=null!=e?e:this;let l=!0;t.beginPath();for(const e of s){const s=i[e],n=a[e];isFinite(s+n)?l?(t.moveTo(s,n),l=!1):t.lineTo(s,n):(t.closePath(),l=!0)}t.closePath(),this.visuals.fill.apply(t),this.visuals.hatch.apply(t),this.visuals.line.apply(t)}draw_legend_for_index(t,s,e){(0,o.generic_area_scalar_legend)(this.visuals,t,s)}_hit_point(t){const s=new r.Selection;return c.point_in_poly(t.sx,t.sy,this.sx,this.sy)&&(s.add_to_selected_glyphs(this.model),s.view=this),s}}e.PatchView=p,p.__name__=\"PatchView\";class d extends _.XYGlyph{constructor(t){super(t)}}e.Patch=d,n=d,d.__name__=\"Patch\",n.prototype.default_view=p,n.mixins([h.LineScalar,h.FillScalar,h.HatchScalar])},\n", - " function _(t,s,e,i,n){i();const h=t(1);var r;const a=t(188),_=(0,h.__importStar)(t(185)),o=(0,h.__importStar)(t(18)),l=t(72);class c extends a.AreaView{_index_data(t){const{min:s,max:e}=Math,{data_size:i}=this;for(let n=0;n=0;s--)t.lineTo(n[s],h[s]);t.closePath(),this.visuals.fill.apply(t),this.visuals.hatch.apply(t)}_hit_point(t){const s=this.sy.length,e=new l.Selection;for(let i=0,n=s-1;i({x1:[o.XCoordinateSpec,{field:\"x1\"}],x2:[o.XCoordinateSpec,{field:\"x2\"}],y:[o.YCoordinateSpec,{field:\"y\"}]})))},\n", - " function _(e,a,r,_,s){_();const n=e(1);var c;const i=e(179),l=e(184),t=(0,n.__importStar)(e(48));class o extends i.GlyphView{draw_legend_for_index(e,a,r){(0,l.generic_area_scalar_legend)(this.visuals,e,a)}}r.AreaView=o,o.__name__=\"AreaView\";class d extends i.Glyph{constructor(e){super(e)}}r.Area=d,c=d,d.__name__=\"Area\",c.mixins([t.FillScalar,t.HatchScalar])},\n", - " function _(t,s,e,i,n){i();const h=t(1);var r;const a=t(188),_=(0,h.__importStar)(t(185)),o=(0,h.__importStar)(t(18)),l=t(72);class c extends a.AreaView{_index_data(t){const{min:s,max:e}=Math,{data_size:i}=this;for(let n=0;n=0;s--)t.lineTo(i[s],h[s]);t.closePath(),this.visuals.fill.apply(t),this.visuals.hatch.apply(t)}scenterxy(t){return[this.sx[t],(this.sy1[t]+this.sy2[t])/2]}_hit_point(t){const s=this.sx.length,e=new l.Selection;for(let i=0,n=s-1;i({x:[o.XCoordinateSpec,{field:\"x\"}],y1:[o.YCoordinateSpec,{field:\"y1\"}],y2:[o.YCoordinateSpec,{field:\"y2\"}]})))},\n", - " function _(e,i,s,t,n){var c;t();const o=e(53),r=e(24),u=e(191),_=e(70);class a extends o.Model{constructor(e){super(e)}initialize(){super.initialize(),this.compute_indices()}connect_signals(){super.connect_signals(),this.connect(this.properties.filters.change,(()=>this.compute_indices()));const e=()=>{const e=()=>this.compute_indices();null!=this.source&&(this.connect(this.source.change,e),this.source instanceof _.ColumnarDataSource&&(this.connect(this.source.streaming,e),this.connect(this.source.patching,e)))};let i=null!=this.source;i?e():this.connect(this.properties.source.change,(()=>{i||(e(),i=!0)}))}compute_indices(){var e;const{source:i}=this;if(null==i)return;const s=null!==(e=i.get_length())&&void 0!==e?e:1,t=r.Indices.all_set(s);for(const e of this.filters)t.intersect(e.compute_indices(i));this.indices=t,this._indices=[...t],this.indices_map_to_subset()}indices_map_to_subset(){this.indices_map={};for(let e=0;ethis._indices[e]))}convert_selection_to_subset(e){return e.map((e=>this.indices_map[e]))}convert_indices_from_subset(e){return e.map((e=>this._indices[e]))}}s.CDSView=a,c=a,a.__name__=\"CDSView\",c.define((({Array:e,Ref:i})=>({filters:[e(i(u.Filter)),[]],source:[i(_.ColumnarDataSource)]}))),c.internal((({Int:e,Dict:i,Ref:s,Nullable:t})=>({indices:[s(r.Indices)],indices_map:[i(e),{}],masked:[t(s(r.Indices)),null]})))},\n", - " function _(e,t,n,s,c){s();const o=e(53);class r extends o.Model{constructor(e){super(e)}}n.Filter=r,r.__name__=\"Filter\"},\n", - " function _(t,r,a,e,c){e(),c(\"BasicTickFormatter\",t(146).BasicTickFormatter),c(\"CategoricalTickFormatter\",t(142).CategoricalTickFormatter),c(\"DatetimeTickFormatter\",t(150).DatetimeTickFormatter),c(\"FuncTickFormatter\",t(193).FuncTickFormatter),c(\"LogTickFormatter\",t(163).LogTickFormatter),c(\"MercatorTickFormatter\",t(166).MercatorTickFormatter),c(\"NumeralTickFormatter\",t(194).NumeralTickFormatter),c(\"PrintfTickFormatter\",t(195).PrintfTickFormatter),c(\"TickFormatter\",t(131).TickFormatter)},\n", - " function _(t,e,n,s,r){var c;s();const i=t(131),a=t(13),u=t(34);class o extends i.TickFormatter{constructor(t){super(t)}get names(){return(0,a.keys)(this.args)}get values(){return(0,a.values)(this.args)}_make_func(){const t=(0,u.use_strict)(this.code);return new Function(\"tick\",\"index\",\"ticks\",...this.names,t)}doFormat(t,e){const n=this._make_func().bind({});return t.map(((t,e,s)=>`${n(t,e,s,...this.values)}`))}}n.FuncTickFormatter=o,c=o,o.__name__=\"FuncTickFormatter\",c.define((({Unknown:t,String:e,Dict:n})=>({args:[n(t),{}],code:[e,\"\"]})))},\n", - " function _(r,n,t,o,e){o();var a;const u=(0,r(1).__importStar)(r(153)),c=r(131),i=r(20);class s extends c.TickFormatter{constructor(r){super(r)}get _rounding_fn(){switch(this.rounding){case\"round\":case\"nearest\":return Math.round;case\"floor\":case\"rounddown\":return Math.floor;case\"ceil\":case\"roundup\":return Math.ceil}}doFormat(r,n){const{format:t,language:o,_rounding_fn:e}=this;return r.map((r=>u.format(r,t,o,e)))}}t.NumeralTickFormatter=s,a=s,s.__name__=\"NumeralTickFormatter\",a.define((({String:r})=>({format:[r,\"0,0\"],language:[r,\"en\"],rounding:[i.RoundingFunction,\"round\"]})))},\n", - " function _(t,r,n,o,a){var e;o();const i=t(131),s=t(152);class c extends i.TickFormatter{constructor(t){super(t)}doFormat(t,r){return t.map((t=>(0,s.sprintf)(this.format,t)))}}n.PrintfTickFormatter=c,e=c,c.__name__=\"PrintfTickFormatter\",e.define((({String:t})=>({format:[t,\"%s\"]})))},\n", - " function _(r,o,a,p,e){p(),e(\"CategoricalColorMapper\",r(197).CategoricalColorMapper),e(\"CategoricalMarkerMapper\",r(199).CategoricalMarkerMapper),e(\"CategoricalPatternMapper\",r(200).CategoricalPatternMapper),e(\"ContinuousColorMapper\",r(172).ContinuousColorMapper),e(\"ColorMapper\",r(173).ColorMapper),e(\"LinearColorMapper\",r(201).LinearColorMapper),e(\"LogColorMapper\",r(202).LogColorMapper),e(\"ScanningColorMapper\",r(171).ScanningColorMapper),e(\"EqHistColorMapper\",r(203).EqHistColorMapper)},\n", - " function _(t,o,r,a,e){var c;a();const s=t(198),l=t(173),n=t(67);class _ extends l.ColorMapper{constructor(t){super(t)}_v_compute(t,o,r,{nan_color:a}){(0,s.cat_v_compute)(t,this.factors,r,o,this.start,this.end,a)}}r.CategoricalColorMapper=_,c=_,_.__name__=\"CategoricalColorMapper\",c.define((({Number:t,Nullable:o})=>({factors:[n.FactorSeq],start:[t,0],end:[o(t),null]})))},\n", - " function _(n,t,e,l,i){l();const c=n(12),u=n(8);function f(n,t){if(n.length!=t.length)return!1;for(let e=0,l=n.length;ef(n,h)))),s=_<0||_>=e.length?r:e[_],l[g]=s}}},\n", - " function _(e,r,a,t,s){var c;t();const l=e(198),n=e(67),u=e(174),o=e(20);class p extends u.Mapper{constructor(e){super(e)}v_compute(e){const r=new Array(e.length);return(0,l.cat_v_compute)(e,this.factors,this.markers,r,this.start,this.end,this.default_value),r}}a.CategoricalMarkerMapper=p,c=p,p.__name__=\"CategoricalMarkerMapper\",c.define((({Number:e,Array:r,Nullable:a})=>({factors:[n.FactorSeq],markers:[r(o.MarkerType)],start:[e,0],end:[a(e),null],default_value:[o.MarkerType,\"circle\"]})))},\n", - " function _(t,e,a,r,n){var s;r();const c=t(198),l=t(67),p=t(174),u=t(20);class o extends p.Mapper{constructor(t){super(t)}v_compute(t){const e=new Array(t.length);return(0,c.cat_v_compute)(t,this.factors,this.patterns,e,this.start,this.end,this.default_value),e}}a.CategoricalPatternMapper=o,s=o,o.__name__=\"CategoricalPatternMapper\",s.define((({Number:t,Array:e,Nullable:a})=>({factors:[l.FactorSeq],patterns:[e(u.HatchPatternType)],start:[t,0],end:[a(t),null],default_value:[u.HatchPatternType,\" \"]})))},\n", - " function _(n,r,o,t,a){t();const e=n(172),i=n(12);class s extends e.ContinuousColorMapper{constructor(n){super(n)}scan(n,r){const o=null!=this.low?this.low:(0,i.min)(n),t=null!=this.high?this.high:(0,i.max)(n);return{max:t,min:o,norm_factor:1/(t-o),normed_interval:1/r}}cmap(n,r,o,t,a){const e=r.length-1;if(n==a.max)return r[e];const i=(n-a.min)*a.norm_factor,s=Math.floor(i/a.normed_interval);return s<0?o:s>e?t:r[s]}}o.LinearColorMapper=s,s.__name__=\"LinearColorMapper\"},\n", - " function _(o,t,n,r,l){r();const a=o(172),s=o(12);class e extends a.ContinuousColorMapper{constructor(o){super(o)}scan(o,t){const n=null!=this.low?this.low:(0,s.min)(o),r=null!=this.high?this.high:(0,s.max)(o);return{max:r,min:n,scale:t/(Math.log(r)-Math.log(n))}}cmap(o,t,n,r,l){const a=t.length-1;if(o>l.max)return r;if(o==l.max)return t[a];if(oa&&(e=a),t[e]}}n.LogColorMapper=e,e.__name__=\"LogColorMapper\"},\n", - " function _(e,n,s,t,l){var i;t();const r=e(171),o=e(12),c=e(9);class a extends r.ScanningColorMapper{constructor(e){super(e)}scan(e,n){let s=null!=this.low?this.low:(0,o.min)(e);const t=null!=this.high?this.high:(0,o.max)(e),l=this.bins,i=(0,c.linspace)(s,t,l+1),r=(0,o.bin_counts)(e,i);let a=0;for(let e=0;e1&&(f=1-n)}const d=(0,c.linspace)(f,1,n+1),g=(0,o.interpolate)(d,p,_);return this.rescale_discrete_levels?s=g[0]:g[0]=s,g[g.length-1]=t,{min:s,max:t,binning:g}}}s.EqHistColorMapper=a,i=a,a.__name__=\"EqHistColorMapper\",i.define((({Boolean:e,Int:n})=>({bins:[n,65536],rescale_discrete_levels:[e,!1]})))},\n", - " function _(a,e,l,c,n){c(),n(\"CategoricalScale\",a(62).CategoricalScale),n(\"ContinuousScale\",a(60).ContinuousScale),n(\"LinearScale\",a(59).LinearScale),n(\"LinearInterpolationScale\",a(205).LinearInterpolationScale),n(\"LogScale\",a(61).LogScale),n(\"Scale\",a(55).Scale)},\n", - " function _(e,r,n,t,a){var i;t();const s=e(55),o=e(59),c=e(12);class _ extends s.Scale{constructor(e){super(e)}connect_signals(){super.connect_signals();const{source_range:e,target_range:r}=this.properties;this.on_change([e,r],(()=>{this.linear_scale=new o.LinearScale({source_range:this.source_range,target_range:this.target_range})}))}get s_compute(){throw new Error(\"not implemented\")}get s_invert(){throw new Error(\"not implemented\")}compute(e){return e}v_compute(e){const{binning:r}=this,{start:n,end:t}=this.source_range,a=n,i=t,s=r.length,o=(t-n)/(s-1),_=new Float64Array(s);for(let e=0;e{if(ei)return i;const n=(0,c.left_edge_index)(e,r);if(-1==n)return a;if(n>=s-1)return i;const t=r[n],o=(e-t)/(r[n+1]-t),l=_[n];return l+o*(_[n+1]-l)}));return this.linear_scale.v_compute(l)}invert(e){return e}v_invert(e){return new Float64Array(e)}}n.LinearInterpolationScale=_,i=_,_.__name__=\"LinearInterpolationScale\",i.internal((({Arrayable:e,Ref:r})=>({binning:[e],linear_scale:[r(o.LinearScale),e=>new o.LinearScale({source_range:e.source_range,target_range:e.target_range})]})))},\n", - " function _(a,n,e,g,R){g(),R(\"DataRange\",a(64).DataRange),R(\"DataRange1d\",a(63).DataRange1d),R(\"FactorRange\",a(67).FactorRange),R(\"Range\",a(57).Range),R(\"Range1d\",a(58).Range1d)},\n", - " function _(a,o,i,t,e){t();var n=a(124);e(\"Sizeable\",n.Sizeable),e(\"SizingPolicy\",n.SizingPolicy);var c=a(125);e(\"Layoutable\",c.Layoutable),e(\"LayoutItem\",c.LayoutItem);var r=a(208);e(\"HStack\",r.HStack),e(\"VStack\",r.VStack);var l=a(209);e(\"Grid\",l.Grid),e(\"Row\",l.Row),e(\"Column\",l.Column);var S=a(210);e(\"ContentBox\",S.ContentBox),e(\"VariadicBox\",S.VariadicBox)},\n", - " function _(t,e,h,i,r){i();const n=t(125),o=t(65);class s extends n.Layoutable{constructor(){super(...arguments),this.children=[]}*[Symbol.iterator](){yield*this.children}}h.Stack=s,s.__name__=\"Stack\";class c extends s{_measure(t){let e=0,h=0;for(const t of this.children){const i=t.measure({width:0,height:0});e+=i.width,h=Math.max(h,i.height)}return{width:e,height:h}}_set_geometry(t,e){super._set_geometry(t,e);const h=this.absolute?t.top:0;let i=this.absolute?t.left:0;const{height:r}=t;for(const t of this.children){const{width:e}=t.measure({width:0,height:0});t.set_geometry(new o.BBox({left:i,width:e,top:h,height:r})),i+=e}}}h.HStack=c,c.__name__=\"HStack\";class a extends s{_measure(t){let e=0,h=0;for(const t of this.children){const i=t.measure({width:0,height:0});e=Math.max(e,i.width),h+=i.height}return{width:e,height:h}}_set_geometry(t,e){super._set_geometry(t,e);const h=this.absolute?t.left:0;let i=this.absolute?t.top:0;const{width:r}=t;for(const t of this.children){const{height:e}=t.measure({width:0,height:0});t.set_geometry(new o.BBox({top:i,height:e,left:h,width:r})),i+=e}}}h.VStack=a,a.__name__=\"VStack\";class l extends n.Layoutable{constructor(){super(...arguments),this.children=[]}*[Symbol.iterator](){yield*this.children}_measure(t){const{width_policy:e,height_policy:h}=this.sizing,{min:i,max:r}=Math;let n=0,o=0;for(const e of this.children){const{width:h,height:i}=e.measure(t);n=r(n,h),o=r(o,i)}return{width:(()=>{const{width:h}=this.sizing;if(t.width==1/0)return\"fixed\"==e&&null!=h?h:n;switch(e){case\"fixed\":return null!=h?h:n;case\"min\":return n;case\"fit\":return null!=h?i(t.width,h):t.width;case\"max\":return null!=h?r(t.width,h):t.width}})(),height:(()=>{const{height:e}=this.sizing;if(t.height==1/0)return\"fixed\"==h&&null!=e?e:o;switch(h){case\"fixed\":return null!=e?e:o;case\"min\":return o;case\"fit\":return null!=e?i(t.height,e):t.height;case\"max\":return null!=e?r(t.height,e):t.height}})()}}_set_geometry(t,e){super._set_geometry(t,e);const h=this.absolute?t:t.relative(),{left:i,right:r,top:n,bottom:s}=h,c=Math.round(h.vcenter),a=Math.round(h.hcenter);for(const e of this.children){const{margin:h,halign:l,valign:d}=e.sizing,{width:u,height:g,inner:_}=e.measure(t),w=(()=>{switch(`${d}_${l}`){case\"start_start\":return new o.BBox({left:i+h.left,top:n+h.top,width:u,height:g});case\"start_center\":return new o.BBox({hcenter:a,top:n+h.top,width:u,height:g});case\"start_end\":return new o.BBox({right:r-h.right,top:n+h.top,width:u,height:g});case\"center_start\":return new o.BBox({left:i+h.left,vcenter:c,width:u,height:g});case\"center_center\":return new o.BBox({hcenter:a,vcenter:c,width:u,height:g});case\"center_end\":return new o.BBox({right:r-h.right,vcenter:c,width:u,height:g});case\"end_start\":return new o.BBox({left:i+h.left,bottom:s-h.bottom,width:u,height:g});case\"end_center\":return new o.BBox({hcenter:a,bottom:s-h.bottom,width:u,height:g});case\"end_end\":return new o.BBox({right:r-h.right,bottom:s-h.bottom,width:u,height:g})}})(),m=null==_?w:new o.BBox({left:w.left+_.left,top:w.top+_.top,right:w.right-_.right,bottom:w.bottom-_.bottom});e.set_geometry(w,m)}}}h.NodeLayout=l,l.__name__=\"NodeLayout\"},\n", - " function _(t,i,s,e,o){e();const n=t(124),l=t(125),r=t(8),h=t(65),c=t(9),{max:a,round:g}=Math;class p{constructor(t){this.def=t,this._map=new Map}get(t){let i=this._map.get(t);return void 0===i&&(i=this.def(),this._map.set(t,i)),i}apply(t,i){const s=this.get(t);this._map.set(t,i(s))}}p.__name__=\"DefaultMap\";class f{constructor(){this._items=[],this._nrows=0,this._ncols=0}get nrows(){return this._nrows}get ncols(){return this._ncols}add(t,i){const{r1:s,c1:e}=t;this._nrows=a(this._nrows,s+1),this._ncols=a(this._ncols,e+1),this._items.push({span:t,data:i})}at(t,i){return this._items.filter((({span:s})=>s.r0<=t&&t<=s.r1&&s.c0<=i&&i<=s.c1)).map((({data:t})=>t))}row(t){return this._items.filter((({span:i})=>i.r0<=t&&t<=i.r1)).map((({data:t})=>t))}col(t){return this._items.filter((({span:i})=>i.c0<=t&&t<=i.c1)).map((({data:t})=>t))}foreach(t){for(const{span:i,data:s}of this._items)t(i,s)}map(t){const i=new f;for(const{span:s,data:e}of this._items)i.add(s,t(s,e));return i}}f.__name__=\"Container\";class _ extends l.Layoutable{constructor(t=[]){super(),this.items=t,this.rows=\"auto\",this.cols=\"auto\",this.spacing=0}*[Symbol.iterator](){for(const{layout:t}of this.items)yield t}is_width_expanding(){if(super.is_width_expanding())return!0;if(\"fixed\"==this.sizing.width_policy)return!1;const{cols:t}=this._state;return(0,c.some)(t,(t=>\"max\"==t.policy))}is_height_expanding(){if(super.is_height_expanding())return!0;if(\"fixed\"==this.sizing.height_policy)return!1;const{rows:t}=this._state;return(0,c.some)(t,(t=>\"max\"==t.policy))}_init(){var t,i,s,e;super._init();const o=new f;for(const{layout:t,row:i,col:s,row_span:e,col_span:n}of this.items)if(t.sizing.visible){const l=i,r=s,h=i+(null!=e?e:1)-1,c=s+(null!=n?n:1)-1;o.add({r0:l,c0:r,r1:h,c1:c},t)}const{nrows:n,ncols:l}=o,h=new Array(n);for(let s=0;s{var t;const i=(0,r.isPlainObject)(this.rows)?null!==(t=this.rows[s])&&void 0!==t?t:this.rows[\"*\"]:this.rows;return null==i?{policy:\"auto\"}:(0,r.isNumber)(i)?{policy:\"fixed\",height:i}:(0,r.isString)(i)?{policy:i}:i})(),n=null!==(t=e.align)&&void 0!==t?t:\"auto\";if(\"fixed\"==e.policy)h[s]={policy:\"fixed\",height:e.height,align:n};else if(\"min\"==e.policy)h[s]={policy:\"min\",align:n};else if(\"fit\"==e.policy||\"max\"==e.policy)h[s]={policy:e.policy,flex:null!==(i=e.flex)&&void 0!==i?i:1,align:n};else{if(\"auto\"!=e.policy)throw new Error(\"unrechable\");(0,c.some)(o.row(s),(t=>t.is_height_expanding()))?h[s]={policy:\"max\",flex:1,align:n}:h[s]={policy:\"min\",align:n}}}const a=new Array(l);for(let t=0;t{var i;const s=(0,r.isPlainObject)(this.cols)?null!==(i=this.cols[t])&&void 0!==i?i:this.cols[\"*\"]:this.cols;return null==s?{policy:\"auto\"}:(0,r.isNumber)(s)?{policy:\"fixed\",width:s}:(0,r.isString)(s)?{policy:s}:s})(),n=null!==(s=i.align)&&void 0!==s?s:\"auto\";if(\"fixed\"==i.policy)a[t]={policy:\"fixed\",width:i.width,align:n};else if(\"min\"==i.policy)a[t]={policy:\"min\",align:n};else if(\"fit\"==i.policy||\"max\"==i.policy)a[t]={policy:i.policy,flex:null!==(e=i.flex)&&void 0!==e?e:1,align:n};else{if(\"auto\"!=i.policy)throw new Error(\"unrechable\");(0,c.some)(o.col(t),(t=>t.is_width_expanding()))?a[t]={policy:\"max\",flex:1,align:n}:a[t]={policy:\"min\",align:n}}}const[g,p]=(0,r.isNumber)(this.spacing)?[this.spacing,this.spacing]:this.spacing;this._state={items:o,nrows:n,ncols:l,rows:h,cols:a,rspacing:g,cspacing:p}}_measure_totals(t,i){const{nrows:s,ncols:e,rspacing:o,cspacing:n}=this._state;return{height:(0,c.sum)(t)+(s-1)*o,width:(0,c.sum)(i)+(e-1)*n}}_measure_cells(t){const{items:i,nrows:s,ncols:e,rows:o,cols:l,rspacing:r,cspacing:h}=this._state,c=new Array(s);for(let t=0;t{const{r0:e,c0:f,r1:d,c1:u}=i,w=(d-e)*r,m=(u-f)*h;let y=0;for(let i=e;i<=d;i++)y+=t(i,f).height;y+=w;let x=0;for(let i=f;i<=u;i++)x+=t(e,i).width;x+=m;const b=s.measure({width:x,height:y});_.add(i,{layout:s,size_hint:b});const z=new n.Sizeable(b).grow_by(s.sizing.margin);z.height-=w,z.width-=m;const v=[];for(let t=e;t<=d;t++){const i=o[t];\"fixed\"==i.policy?z.height-=i.height:v.push(t)}if(z.height>0){const t=g(z.height/v.length);for(const i of v)c[i]=a(c[i],t)}const j=[];for(let t=f;t<=u;t++){const i=l[t];\"fixed\"==i.policy?z.width-=i.width:j.push(t)}if(z.width>0){const t=g(z.width/j.length);for(const i of j)p[i]=a(p[i],t)}}));return{size:this._measure_totals(c,p),row_heights:c,col_widths:p,size_hints:_}}_measure_grid(t){const{nrows:i,ncols:s,rows:e,cols:o,rspacing:n,cspacing:l}=this._state,r=this._measure_cells(((t,i)=>{const s=e[t],n=o[i];return{width:\"fixed\"==n.policy?n.width:1/0,height:\"fixed\"==s.policy?s.height:1/0}}));let h;h=\"fixed\"==this.sizing.height_policy&&null!=this.sizing.height?this.sizing.height:t.height!=1/0&&this.is_height_expanding()?t.height:r.size.height;let c,p=0;for(let t=0;t0)for(let t=0;ti?i:e,t--}}}c=\"fixed\"==this.sizing.width_policy&&null!=this.sizing.width?this.sizing.width:t.width!=1/0&&this.is_width_expanding()?t.width:r.size.width;let f=0;for(let t=0;t0)for(let t=0;ts?s:o,t--}}}const{row_heights:_,col_widths:d,size_hints:u}=this._measure_cells(((t,i)=>({width:r.col_widths[i],height:r.row_heights[t]})));return{size:this._measure_totals(_,d),row_heights:_,col_widths:d,size_hints:u}}_measure(t){const{size:i}=this._measure_grid(t);return i}_set_geometry(t,i){super._set_geometry(t,i);const{nrows:s,ncols:e,rspacing:o,cspacing:n}=this._state,{row_heights:l,col_widths:r,size_hints:c}=this._measure_grid(t),f=this._state.rows.map(((t,i)=>Object.assign(Object.assign({},t),{top:0,height:l[i],get bottom(){return this.top+this.height}}))),_=this._state.cols.map(((t,i)=>Object.assign(Object.assign({},t),{left:0,width:r[i],get right(){return this.left+this.width}}))),d=c.map(((t,i)=>Object.assign(Object.assign({},i),{outer:new h.BBox,inner:new h.BBox})));for(let i=0,e=this.absolute?t.top:0;i{const{layout:r,size_hint:c}=l,{sizing:a}=r,{width:p,height:d}=c,u=function(t,i){let s=(i-t)*n;for(let e=t;e<=i;e++)s+=_[e].width;return s}(i,e),w=function(t,i){let s=(i-t)*o;for(let e=t;e<=i;e++)s+=f[e].height;return s}(t,s),m=i==e&&\"auto\"!=_[i].align?_[i].align:a.halign,y=t==s&&\"auto\"!=f[t].align?f[t].align:a.valign;let x=_[i].left;\"start\"==m?x+=a.margin.left:\"center\"==m?x+=g((u-p)/2):\"end\"==m&&(x+=u-a.margin.right-p);let b=f[t].top;\"start\"==y?b+=a.margin.top:\"center\"==y?b+=g((w-d)/2):\"end\"==y&&(b+=w-a.margin.bottom-d),l.outer=new h.BBox({left:x,top:b,width:p,height:d})}));const u=f.map((()=>({start:new p((()=>0)),end:new p((()=>0))}))),w=_.map((()=>({start:new p((()=>0)),end:new p((()=>0))})));d.foreach((({r0:t,c0:i,r1:s,c1:e},{size_hint:o,outer:n})=>{const{inner:l}=o;null!=l&&(u[t].start.apply(n.top,(t=>a(t,l.top))),u[s].end.apply(f[s].bottom-n.bottom,(t=>a(t,l.bottom))),w[i].start.apply(n.left,(t=>a(t,l.left))),w[e].end.apply(_[e].right-n.right,(t=>a(t,l.right))))})),d.foreach((({r0:t,c0:i,r1:s,c1:e},o)=>{const{size_hint:n,outer:l}=o,r=t=>{const i=this.absolute?l:l.relative(),s=i.left+t.left,e=i.top+t.top,o=i.right-t.right,n=i.bottom-t.bottom;return new h.BBox({left:s,top:e,right:o,bottom:n})};if(null!=n.inner){let h=r(n.inner);if(!1!==n.align){const o=u[t].start.get(l.top),n=u[s].end.get(f[s].bottom-l.bottom),c=w[i].start.get(l.left),a=w[e].end.get(_[e].right-l.right);try{h=r({top:o,bottom:n,left:c,right:a})}catch(t){}}o.inner=h}else o.inner=l})),d.foreach(((t,{layout:i,outer:s,inner:e})=>{i.set_geometry(s,e)}))}}s.Grid=_,_.__name__=\"Grid\";class d extends _{constructor(t){super(),this.items=t.map(((t,i)=>({layout:t,row:0,col:i}))),this.rows=\"fit\"}}s.Row=d,d.__name__=\"Row\";class u extends _{constructor(t){super(),this.items=t.map(((t,i)=>({layout:t,row:i,col:0}))),this.cols=\"fit\"}}s.Column=u,u.__name__=\"Column\"},\n", - " function _(e,t,s,n,i){n();const a=e(125),c=e(124),o=e(43);class r extends a.ContentLayoutable{constructor(e){super(),this.content_size=(0,o.unsized)(e,(()=>new c.Sizeable((0,o.size)(e))))}_content_size(){return this.content_size}}s.ContentBox=r,r.__name__=\"ContentBox\";class _ extends a.Layoutable{constructor(e){super(),this.el=e}_measure(e){const t=new c.Sizeable(e).bounded_to(this.sizing.size);return(0,o.sized)(this.el,t,(()=>{const e=new c.Sizeable((0,o.content_size)(this.el)),{border:t,padding:s}=(0,o.extents)(this.el);return e.grow_by(t).grow_by(s).map(Math.ceil)}))}}s.VariadicBox=_,_.__name__=\"VariadicBox\";class h extends _{constructor(e){super(e),this._cache=new Map}_measure(e){const{width:t,height:s}=e,n=`${t},${s}`;let i=this._cache.get(n);return null==i&&(i=super._measure(e),this._cache.set(n,i)),i}invalidate_cache(){this._cache.clear()}}s.CachedVariadicBox=h,h.__name__=\"CachedVariadicBox\"},\n", - " function _(t,e,i,h,o){h();const s=t(124),r=t(125),n=t(65);class g extends r.Layoutable{constructor(){super(...arguments),this.min_border={left:0,top:0,right:0,bottom:0},this.padding={left:0,top:0,right:0,bottom:0}}*[Symbol.iterator](){yield this.top_panel,yield this.bottom_panel,yield this.left_panel,yield this.right_panel,yield this.center_panel}_measure(t){t=new s.Sizeable({width:\"fixed\"==this.sizing.width_policy||t.width==1/0?this.sizing.width:t.width,height:\"fixed\"==this.sizing.height_policy||t.height==1/0?this.sizing.height:t.height});const e=this.left_panel.measure({width:0,height:t.height}),i=Math.max(e.width,this.min_border.left)+this.padding.left,h=this.right_panel.measure({width:0,height:t.height}),o=Math.max(h.width,this.min_border.right)+this.padding.right,r=this.top_panel.measure({width:t.width,height:0}),n=Math.max(r.height,this.min_border.top)+this.padding.top,g=this.bottom_panel.measure({width:t.width,height:0}),a=Math.max(g.height,this.min_border.bottom)+this.padding.bottom,d=new s.Sizeable(t).shrink_by({left:i,right:o,top:n,bottom:a}),l=this.center_panel.measure(d);return{width:i+l.width+o,height:n+l.height+a,inner:{left:i,right:o,top:n,bottom:a},align:(()=>{const{width_policy:t,height_policy:e}=this.center_panel.sizing;return\"fixed\"!=t&&\"fixed\"!=e})()}}_set_geometry(t,e){super._set_geometry(t,e),this.center_panel.set_geometry(e);const i=this.left_panel.measure({width:0,height:t.height}),h=this.right_panel.measure({width:0,height:t.height}),o=this.top_panel.measure({width:t.width,height:0}),s=this.bottom_panel.measure({width:t.width,height:0}),{left:r,top:g,right:a,bottom:d}=e;this.top_panel.set_geometry(new n.BBox({left:r,right:a,bottom:g,height:o.height})),this.bottom_panel.set_geometry(new n.BBox({left:r,right:a,top:d,height:s.height})),this.left_panel.set_geometry(new n.BBox({top:g,bottom:d,right:r,width:i.width})),this.right_panel.set_geometry(new n.BBox({top:g,bottom:d,left:a,width:h.width}))}}i.BorderLayout=g,g.__name__=\"BorderLayout\"},\n", - " function _(t,e,i,s,l){s();const n=t(1);var o;const a=t(119),_=t(10),d=t(20),h=t(120),r=t(123),u=(0,n.__importStar)(t(48));class c extends a.TextAnnotationView{update_layout(){const{panel:t}=this;this.layout=null!=t?new r.SideLayout(t,(()=>this.get_size()),!1):void 0}_get_size(){const{text:t}=this.model,e=new h.TextBox({text:t}),{angle:i,angle_units:s}=this.model;e.angle=(0,_.resolve_angle)(i,s),e.visuals=this.visuals.text.values();const{width:l,height:n}=e.size();return{width:l,height:n}}_render(){const{angle:t,angle_units:e}=this.model,i=(0,_.resolve_angle)(t,e),s=null!=this.layout?this.layout:this.plot_view.frame,l=this.coordinates.x_scale,n=this.coordinates.y_scale;let o=\"data\"==this.model.x_units?l.compute(this.model.x):s.bbox.xview.compute(this.model.x),a=\"data\"==this.model.y_units?n.compute(this.model.y):s.bbox.yview.compute(this.model.y);o+=this.model.x_offset,a-=this.model.y_offset;(\"canvas\"==this.model.render_mode?this._canvas_text.bind(this):this._css_text.bind(this))(this.layer.ctx,this.model.text,o,a,i)}}i.LabelView=c,c.__name__=\"LabelView\";class x extends a.TextAnnotation{constructor(t){super(t)}}i.Label=x,o=x,x.__name__=\"Label\",o.prototype.default_view=c,o.mixins([u.Text,[\"border_\",u.Line],[\"background_\",u.Fill]]),o.define((({Number:t,String:e,Angle:i})=>({x:[t],x_units:[d.SpatialUnits,\"data\"],y:[t],y_units:[d.SpatialUnits,\"data\"],text:[e,\"\"],angle:[i,0],angle_units:[d.AngleUnits,\"rad\"],x_offset:[t,0],y_offset:[t,0]}))),o.override({background_fill_color:null,border_line_color:null})},\n", - " function _(t,e,s,i,l){i();const o=t(1);var a;const r=t(69),n=(0,o.__importStar)(t(48)),d=t(20),_=t(43),c=t(120),h=(0,o.__importStar)(t(18)),u=t(11);class v extends r.DataAnnotationView{set_data(t){var e;if(super.set_data(t),null===(e=this.els)||void 0===e||e.forEach((t=>(0,_.remove)(t))),\"css\"==this.model.render_mode){const t=this.els=[...this.text].map((()=>(0,_.div)({style:{display:\"none\"}})));for(const e of t)this.plot_view.canvas_view.add_overlay(e)}else delete this.els}remove(){var t;null===(t=this.els)||void 0===t||t.forEach((t=>(0,_.remove)(t))),super.remove()}_rerender(){\"css\"==this.model.render_mode?this.render():this.request_render()}map_data(){const{x_scale:t,y_scale:e}=this.coordinates,s=null!=this.layout?this.layout:this.plot_view.frame;this.sx=\"data\"==this.model.x_units?t.v_compute(this._x):s.bbox.xview.v_compute(this._x),this.sy=\"data\"==this.model.y_units?e.v_compute(this._y):s.bbox.yview.v_compute(this._y)}paint(){const t=\"canvas\"==this.model.render_mode?this._v_canvas_text.bind(this):this._v_css_text.bind(this),{ctx:e}=this.layer;for(let s=0,i=this.text.length;s{switch(this.visuals.text.text_align.get(e)){case\"left\":return[\"left\",\"0%\"];case\"center\":return[\"center\",\"-50%\"];case\"right\":return[\"right\",\"-100%\"]}})(),[d,c]=(()=>{switch(this.visuals.text.text_baseline.get(e)){case\"top\":return[\"top\",\"0%\"];case\"middle\":return[\"center\",\"-50%\"];case\"bottom\":return[\"bottom\",\"-100%\"];default:return[\"center\",\"-50%\"]}})();let h=`translate(${n}, ${c})`;o&&(h+=`rotate(${o}rad)`),a.style.transformOrigin=`${r} ${d}`,a.style.transform=h,this.layout,this.visuals.background_fill.doit&&(this.visuals.background_fill.set_vectorize(t,e),a.style.backgroundColor=t.fillStyle),this.visuals.border_line.doit&&(this.visuals.border_line.set_vectorize(t,e),a.style.borderStyle=t.lineDash.length<2?\"solid\":\"dashed\",a.style.borderWidth=`${t.lineWidth}px`,a.style.borderColor=t.strokeStyle),(0,_.display)(a)}}s.LabelSetView=v,v.__name__=\"LabelSetView\";class x extends r.DataAnnotation{constructor(t){super(t)}}s.LabelSet=x,a=x,x.__name__=\"LabelSet\",a.prototype.default_view=v,a.mixins([n.TextVector,[\"border_\",n.LineVector],[\"background_\",n.FillVector]]),a.define((()=>({x:[h.XCoordinateSpec,{field:\"x\"}],y:[h.YCoordinateSpec,{field:\"y\"}],x_units:[d.SpatialUnits,\"data\"],y_units:[d.SpatialUnits,\"data\"],text:[h.StringSpec,{field:\"text\"}],angle:[h.AngleSpec,0],x_offset:[h.NumberSpec,{value:0}],y_offset:[h.NumberSpec,{value:0}],render_mode:[d.RenderMode,\"canvas\"]}))),a.override({background_fill_color:null,border_line_color:null})},\n", - " function _(t,e,i,l,s){l();const n=t(1);var o;const h=t(40),a=t(215),_=t(20),r=(0,n.__importStar)(t(48)),d=t(15),c=t(123),g=t(121),m=t(65),b=t(9),f=t(8),u=t(11);class x extends h.AnnotationView{update_layout(){const{panel:t}=this;this.layout=null!=t?new c.SideLayout(t,(()=>this.get_size())):void 0}cursor(t,e){return\"none\"==this.model.click_policy?null:\"pointer\"}get legend_padding(){return null!=this.model.border_line_color?this.model.padding:0}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render())),this.connect(this.model.item_change,(()=>this.request_render()))}compute_legend_bbox(){const t=this.model.get_legend_names(),{glyph_height:e,glyph_width:i}=this.model,{label_height:l,label_width:s}=this.model;this.max_label_height=(0,b.max)([(0,g.font_metrics)(this.visuals.label_text.font_value()).height,l,e]);const{ctx:n}=this.layer;n.save(),this.visuals.label_text.set_value(n),this.text_widths=new Map;for(const e of t)this.text_widths.set(e,(0,b.max)([n.measureText(e).width,s]));this.visuals.title_text.set_value(n),this.title_height=this.model.title?(0,g.font_metrics)(this.visuals.title_text.font_value()).height+this.model.title_standoff:0,this.title_width=this.model.title?n.measureText(this.model.title).width:0,n.restore();const o=Math.max((0,b.max)([...this.text_widths.values()]),0),h=this.model.margin,{legend_padding:a}=this,_=this.model.spacing,{label_standoff:r}=this.model;let d,c;if(\"vertical\"==this.model.orientation)d=t.length*this.max_label_height+Math.max(t.length-1,0)*_+2*a+this.title_height,c=(0,b.max)([o+i+r+2*a,this.title_width+2*a]);else{let e=2*a+Math.max(t.length-1,0)*_;for(const[,t]of this.text_widths)e+=(0,b.max)([t,s])+i+r;c=(0,b.max)([this.title_width+2*a,e]),d=this.max_label_height+this.title_height+2*a}const x=null!=this.layout?this.layout:this.plot_view.frame,[p,w]=x.bbox.ranges,{location:v}=this.model;let y,k;if((0,f.isString)(v))switch(v){case\"top_left\":y=p.start+h,k=w.start+h;break;case\"top\":case\"top_center\":y=(p.end+p.start)/2-c/2,k=w.start+h;break;case\"top_right\":y=p.end-h-c,k=w.start+h;break;case\"bottom_right\":y=p.end-h-c,k=w.end-h-d;break;case\"bottom\":case\"bottom_center\":y=(p.end+p.start)/2-c/2,k=w.end-h-d;break;case\"bottom_left\":y=p.start+h,k=w.end-h-d;break;case\"left\":case\"center_left\":y=p.start+h,k=(w.end+w.start)/2-d/2;break;case\"center\":case\"center_center\":y=(p.end+p.start)/2-c/2,k=(w.end+w.start)/2-d/2;break;case\"right\":case\"center_right\":y=p.end-h-c,k=(w.end+w.start)/2-d/2}else if((0,f.isArray)(v)&&2==v.length){const[t,e]=v;y=x.bbox.xview.compute(t),k=x.bbox.yview.compute(e)-d}else(0,u.unreachable)();return new m.BBox({left:y,top:k,width:c,height:d})}interactive_bbox(){return this.compute_legend_bbox()}interactive_hit(t,e){return this.interactive_bbox().contains(t,e)}on_hit(t,e){let i;const{glyph_width:l}=this.model,{legend_padding:s}=this,n=this.model.spacing,{label_standoff:o}=this.model;let h=i=s;const a=this.compute_legend_bbox(),_=\"vertical\"==this.model.orientation;for(const r of this.model.items){const d=r.get_labels_list_from_label_prop();for(const c of d){const d=a.x+h,g=a.y+i+this.title_height;let b,f;[b,f]=_?[a.width-2*s,this.max_label_height]:[this.text_widths.get(c)+l+o,this.max_label_height];if(new m.BBox({left:d,top:g,width:b,height:f}).contains(t,e)){switch(this.model.click_policy){case\"hide\":for(const t of r.renderers)t.visible=!t.visible;break;case\"mute\":for(const t of r.renderers)t.muted=!t.muted}return!0}_?i+=this.max_label_height+n:h+=this.text_widths.get(c)+l+o+n}}return!1}_render(){if(0==this.model.items.length)return;if(!(0,b.some)(this.model.items,(t=>t.visible)))return;for(const t of this.model.items)t.legend=this.model;const{ctx:t}=this.layer,e=this.compute_legend_bbox();t.save(),this._draw_legend_box(t,e),this._draw_legend_items(t,e),this._draw_title(t,e),t.restore()}_draw_legend_box(t,e){t.beginPath(),t.rect(e.x,e.y,e.width,e.height),this.visuals.background_fill.apply(t),this.visuals.border_line.apply(t)}_draw_legend_items(t,e){const{glyph_width:i,glyph_height:l}=this.model,{legend_padding:s}=this,n=this.model.spacing,{label_standoff:o}=this.model;let h=s,a=s;const _=\"vertical\"==this.model.orientation;for(const r of this.model.items){if(!r.visible)continue;const d=r.get_labels_list_from_label_prop(),c=r.get_field_from_label_prop();if(0==d.length)continue;const g=(()=>{switch(this.model.click_policy){case\"none\":return!0;case\"hide\":return(0,b.every)(r.renderers,(t=>t.visible));case\"mute\":return(0,b.every)(r.renderers,(t=>!t.muted))}})();for(const m of d){const d=e.x+h,b=e.y+a+this.title_height,f=d+i,u=b+l;_?a+=this.max_label_height+n:h+=this.text_widths.get(m)+i+o+n,this.visuals.label_text.set_value(t),t.fillText(m,f+o,b+this.max_label_height/2);for(const e of r.renderers){const i=this.plot_view.renderer_view(e);null==i||i.draw_legend(t,d,f,b,u,c,m,r.index)}if(!g){let l,n;[l,n]=_?[e.width-2*s,this.max_label_height]:[this.text_widths.get(m)+i+o,this.max_label_height],t.beginPath(),t.rect(d,b,l,n),this.visuals.inactive_fill.set_value(t),t.fill()}}}}_draw_title(t,e){const{title:i}=this.model;i&&this.visuals.title_text.doit&&(t.save(),t.translate(e.x0,e.y0+this.title_height),this.visuals.title_text.set_value(t),t.fillText(i,this.legend_padding,this.legend_padding-this.model.title_standoff),t.restore())}_get_size(){const{width:t,height:e}=this.compute_legend_bbox();return{width:t+2*this.model.margin,height:e+2*this.model.margin}}}i.LegendView=x,x.__name__=\"LegendView\";class p extends h.Annotation{constructor(t){super(t)}initialize(){super.initialize(),this.item_change=new d.Signal0(this,\"item_change\")}get_legend_names(){const t=[];for(const e of this.items){const i=e.get_labels_list_from_label_prop();t.push(...i)}return t}}i.Legend=p,o=p,p.__name__=\"Legend\",o.prototype.default_view=x,o.mixins([[\"label_\",r.Text],[\"title_\",r.Text],[\"inactive_\",r.Fill],[\"border_\",r.Line],[\"background_\",r.Fill]]),o.define((({Number:t,String:e,Array:i,Tuple:l,Or:s,Ref:n,Nullable:o})=>({orientation:[_.Orientation,\"vertical\"],location:[s(_.LegendLocation,l(t,t)),\"top_right\"],title:[o(e),null],title_standoff:[t,5],label_standoff:[t,5],glyph_height:[t,20],glyph_width:[t,20],label_height:[t,20],label_width:[t,20],margin:[t,10],padding:[t,10],spacing:[t,3],items:[i(n(a.LegendItem)),[]],click_policy:[_.LegendClickPolicy,\"none\"]}))),o.override({border_line_color:\"#e5e5e5\",border_line_alpha:.5,border_line_width:1,background_fill_color:\"#ffffff\",background_fill_alpha:.95,inactive_fill_color:\"white\",inactive_fill_alpha:.7,label_text_font_size:\"13px\",label_text_baseline:\"middle\",title_text_font_size:\"13px\",title_text_font_style:\"italic\"})},\n", - " function _(e,r,l,n,t){n();const i=e(1);var s;const o=e(53),a=e(175),_=e(70),u=e(216),d=(0,i.__importStar)(e(18)),c=e(19),f=e(9);class h extends o.Model{constructor(e){super(e)}_check_data_sources_on_renderers(){if(null!=this.get_field_from_label_prop()){if(this.renderers.length<1)return!1;const e=this.renderers[0].data_source;if(null!=e)for(const r of this.renderers)if(r.data_source!=e)return!1}return!0}_check_field_label_on_data_source(){const e=this.get_field_from_label_prop();if(null!=e){if(this.renderers.length<1)return!1;const r=this.renderers[0].data_source;if(null!=r&&!(0,f.includes)(r.columns(),e))return!1}return!0}initialize(){super.initialize(),this.legend=null,this.connect(this.change,(()=>{var e;return null===(e=this.legend)||void 0===e?void 0:e.item_change.emit()}));this._check_data_sources_on_renderers()||c.logger.error(\"Non matching data sources on legend item renderers\");this._check_field_label_on_data_source()||c.logger.error(`Bad column name on label: ${this.label}`)}get_field_from_label_prop(){const{label:e}=this;return(0,u.isField)(e)?e.field:null}get_labels_list_from_label_prop(){if(!this.visible)return[];if((0,u.isValue)(this.label)){const{value:e}=this.label;return null!=e?[e]:[]}const e=this.get_field_from_label_prop();if(null!=e){let r;if(!this.renderers[0]||null==this.renderers[0].data_source)return[\"No source found\"];if(r=this.renderers[0].data_source,r instanceof _.ColumnarDataSource){const l=r.get_column(e);return null!=l?(0,f.uniq)(Array.from(l)):[\"Invalid field\"]}}return[]}}l.LegendItem=h,s=h,h.__name__=\"LegendItem\",s.define((({Boolean:e,Int:r,Array:l,Ref:n,Nullable:t})=>({label:[d.NullStringSpec,null],renderers:[l(n(a.GlyphRenderer)),[]],index:[t(r),null],visible:[e,!0]})))},\n", - " function _(i,n,e,t,u){t();const c=i(8);e.isValue=function(i){return(0,c.isPlainObject)(i)&&\"value\"in i},e.isField=function(i){return(0,c.isPlainObject)(i)&&\"field\"in i},e.isExpr=function(i){return(0,c.isPlainObject)(i)&&\"expr\"in i}},\n", - " function _(t,n,e,s,i){s();const o=t(1);var a;const l=t(40),c=(0,o.__importStar)(t(48)),r=t(20);class _ extends l.AnnotationView{connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render()))}_render(){const{xs:t,ys:n}=this.model;if(t.length!=n.length)return;const e=t.length;if(e<3)return;const{frame:s}=this.plot_view,{ctx:i}=this.layer,o=this.coordinates.x_scale,a=this.coordinates.y_scale,{screen:l}=this.model;function c(t,n,e,s){return l?t:\"data\"==n?e.v_compute(t):s.v_compute(t)}const r=c(t,this.model.xs_units,o,s.bbox.xview),_=c(n,this.model.ys_units,a,s.bbox.yview);i.beginPath();for(let t=0;t({xs:[n(t),[]],xs_units:[r.SpatialUnits,\"data\"],ys:[n(t),[]],ys_units:[r.SpatialUnits,\"data\"]}))),a.internal((({Boolean:t})=>({screen:[t,!1]}))),a.override({fill_color:\"#fff9ba\",fill_alpha:.4,line_color:\"#cccccc\",line_alpha:.3})},\n", - " function _(e,t,n,o,i){o();const s=e(1);var l;const r=e(40),c=(0,s.__importStar)(e(48));class a extends r.AnnotationView{connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render()))}_render(){const{gradient:e,y_intercept:t}=this.model;if(null==e||null==t)return;const{frame:n}=this.plot_view,o=this.coordinates.x_scale,i=this.coordinates.y_scale;let s,l,r,c;if(0==e)s=i.compute(t),l=s,r=n.bbox.left,c=r+n.bbox.width;else{s=n.bbox.top,l=s+n.bbox.height;const a=(i.invert(s)-t)/e,_=(i.invert(l)-t)/e;r=o.compute(a),c=o.compute(_)}const{ctx:a}=this.layer;a.save(),a.beginPath(),this.visuals.line.set_value(a),a.moveTo(r,s),a.lineTo(c,l),a.stroke(),a.restore()}}n.SlopeView=a,a.__name__=\"SlopeView\";class _ extends r.Annotation{constructor(e){super(e)}}n.Slope=_,l=_,_.__name__=\"Slope\",l.prototype.default_view=a,l.mixins(c.Line),l.define((({Number:e,Nullable:t})=>({gradient:[t(e),null],y_intercept:[t(e),null]}))),l.override({line_color:\"black\"})},\n", - " function _(e,t,i,o,n){o();const s=e(1);var l;const a=e(40),r=(0,s.__importStar)(e(48)),c=e(20);class d extends a.AnnotationView{connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.plot_view.request_paint(this)))}_render(){const{location:e}=this.model;if(null==e)return;const{frame:t}=this.plot_view,i=this.coordinates.x_scale,o=this.coordinates.y_scale,n=(t,i)=>\"data\"==this.model.location_units?t.compute(e):this.model.for_hover?e:i.compute(e);let s,l,a,r;\"width\"==this.model.dimension?(a=n(o,t.bbox.yview),l=t.bbox.left,r=t.bbox.width,s=this.model.line_width):(a=t.bbox.top,l=n(i,t.bbox.xview),r=this.model.line_width,s=t.bbox.height);const{ctx:c}=this.layer;c.save(),c.beginPath(),this.visuals.line.set_value(c),c.moveTo(l,a),\"width\"==this.model.dimension?c.lineTo(l+r,a):c.lineTo(l,a+s),c.stroke(),c.restore()}}i.SpanView=d,d.__name__=\"SpanView\";class _ extends a.Annotation{constructor(e){super(e)}}i.Span=_,l=_,_.__name__=\"Span\",l.prototype.default_view=d,l.mixins(r.Line),l.define((({Number:e,Nullable:t})=>({render_mode:[c.RenderMode,\"canvas\"],location:[t(e),null],location_units:[c.SpatialUnits,\"data\"],dimension:[c.Dimension,\"width\"]}))),l.internal((({Boolean:e})=>({for_hover:[e,!1]}))),l.override({line_color:\"black\"})},\n", - " function _(i,e,t,o,l){var s;o();const a=i(40),_=i(221),n=i(113),r=i(43),h=i(123),b=i(65);class v extends a.AnnotationView{constructor(){super(...arguments),this._invalidate_toolbar=!0,this._previous_bbox=new b.BBox}update_layout(){this.layout=new h.SideLayout(this.panel,(()=>this.get_size()),!0)}initialize(){super.initialize(),this.el=(0,r.div)(),this.plot_view.canvas_view.add_event(this.el)}async lazy_initialize(){await super.lazy_initialize(),this._toolbar_view=await(0,n.build_view)(this.model.toolbar,{parent:this}),this.plot_view.visibility_callbacks.push((i=>this._toolbar_view.set_visibility(i)))}remove(){this._toolbar_view.remove(),(0,r.remove)(this.el),super.remove()}render(){this.model.visible||(0,r.undisplay)(this.el),super.render()}_render(){const{bbox:i}=this.layout;this._previous_bbox.equals(i)||((0,r.position)(this.el,i),this._previous_bbox=i,this._invalidate_toolbar=!0),this._invalidate_toolbar&&(this.el.style.position=\"absolute\",this.el.style.overflow=\"hidden\",(0,r.empty)(this.el),this.el.appendChild(this._toolbar_view.el),this._toolbar_view.layout.bbox=i,this._toolbar_view.render(),this._invalidate_toolbar=!1),(0,r.display)(this.el)}_get_size(){const{tools:i,logo:e}=this.model.toolbar;return{width:30*i.length+(null!=e?25:0)+15,height:30}}}t.ToolbarPanelView=v,v.__name__=\"ToolbarPanelView\";class d extends a.Annotation{constructor(i){super(i)}}t.ToolbarPanel=d,s=d,d.__name__=\"ToolbarPanel\",s.prototype.default_view=v,s.define((({Ref:i})=>({toolbar:[i(_.Toolbar)]})))},\n", - " function _(t,e,s,i,o){var c;i();const n=t(8),a=t(9),l=t(13),r=t(222),_=t(223),u=t(232),p=t(233);function v(t){switch(t){case\"tap\":return\"active_tap\";case\"pan\":return\"active_drag\";case\"pinch\":case\"scroll\":return\"active_scroll\";case\"multi\":return\"active_multi\"}return null}function h(t){return\"tap\"==t||\"pan\"==t}s.Drag=r.Tool,s.Inspection=r.Tool,s.Scroll=r.Tool,s.Tap=r.Tool;class f extends p.ToolbarBase{constructor(t){super(t)}connect_signals(){super.connect_signals();const{tools:t,active_drag:e,active_inspect:s,active_scroll:i,active_tap:o,active_multi:c}=this.properties;this.on_change([t,e,s,i,o,c],(()=>this._init_tools()))}_init_tools(){if(super._init_tools(),\"auto\"==this.active_inspect);else if(this.active_inspect instanceof u.InspectTool){let t=!1;for(const e of this.inspectors)e!=this.active_inspect?e.active=!1:t=!0;t||(this.active_inspect=null)}else if((0,n.isArray)(this.active_inspect)){const t=(0,a.intersection)(this.active_inspect,this.inspectors);t.length!=this.active_inspect.length&&(this.active_inspect=t);for(const t of this.inspectors)(0,a.includes)(this.active_inspect,t)||(t.active=!1)}else if(null==this.active_inspect)for(const t of this.inspectors)t.active=!1;const t=t=>{t.active?this._active_change(t):t.active=!0};for(const t of(0,l.values)(this.gestures)){t.tools=(0,a.sort_by)(t.tools,(t=>t.default_order));for(const e of t.tools)this.connect(e.properties.active.change,(()=>this._active_change(e)))}for(const[e,s]of(0,l.entries)(this.gestures)){const i=v(e);if(i){const o=this[i];\"auto\"==o?0!=s.tools.length&&h(e)&&t(s.tools[0]):null!=o&&((0,a.includes)(this.tools,o)?t(o):this[i]=null)}}}}s.Toolbar=f,c=f,f.__name__=\"Toolbar\",c.prototype.default_view=p.ToolbarBaseView,c.define((({Or:t,Ref:e,Auto:i,Null:o})=>({active_drag:[t(e(s.Drag),i,o),\"auto\"],active_inspect:[t(e(s.Inspection),i,o),\"auto\"],active_scroll:[t(e(s.Scroll),i,o),\"auto\"],active_tap:[t(e(s.Tap),i,o),\"auto\"],active_multi:[t(e(_.GestureTool),i,o),\"auto\"]})))},\n", - " function _(t,e,n,o,s){var i;o();const a=t(42),r=t(9),l=t(53);class c extends a.View{get plot_view(){return this.parent}get plot_model(){return this.parent.model}connect_signals(){super.connect_signals(),this.connect(this.model.properties.active.change,(()=>{this.model.active?this.activate():this.deactivate()}))}activate(){}deactivate(){}}n.ToolView=c,c.__name__=\"ToolView\";class _ extends l.Model{constructor(t){super(t)}get synthetic_renderers(){return[]}_get_dim_limits([t,e],[n,o],s,i){const a=s.bbox.h_range;let l;\"width\"==i||\"both\"==i?(l=[(0,r.min)([t,n]),(0,r.max)([t,n])],l=[(0,r.max)([l[0],a.start]),(0,r.min)([l[1],a.end])]):l=[a.start,a.end];const c=s.bbox.v_range;let _;return\"height\"==i||\"both\"==i?(_=[(0,r.min)([e,o]),(0,r.max)([e,o])],_=[(0,r.max)([_[0],c.start]),(0,r.min)([_[1],c.end])]):_=[c.start,c.end],[l,_]}static register_alias(t,e){this.prototype._known_aliases.set(t,e)}static from_string(t){const e=this.prototype._known_aliases.get(t);if(null!=e)return e();{const e=[...this.prototype._known_aliases.keys()];throw new Error(`unexpected tool name '${t}', possible tools are ${e.join(\", \")}`)}}}n.Tool=_,i=_,_.__name__=\"Tool\",i.prototype._known_aliases=new Map,i.define((({String:t,Nullable:e})=>({description:[e(t),null]}))),i.internal((({Boolean:t})=>({active:[t,!1]})))},\n", - " function _(e,o,t,s,n){s();const u=e(224),_=e(231);class l extends u.ButtonToolView{}t.GestureToolView=l,l.__name__=\"GestureToolView\";class i extends u.ButtonTool{constructor(e){super(e),this.button_view=_.OnOffButtonView}}t.GestureTool=i,i.__name__=\"GestureTool\"},\n", - " function _(t,e,o,s,i){s();const n=t(1);var l;const r=(0,n.__importDefault)(t(225)),a=t(226),u=t(222),h=t(43),_=t(34),d=t(8),c=t(9),m=(0,n.__importStar)(t(227)),p=m,v=(0,n.__importDefault)(t(228)),f=(0,n.__importDefault)(t(229)),g=t(230);class b extends a.DOMView{initialize(){super.initialize();const t=this.model.menu;if(null!=t){const e=this.parent.model.toolbar_location,o=\"left\"==e||\"above\"==e,s=this.parent.model.horizontal?\"vertical\":\"horizontal\";this._menu=new g.ContextMenu(o?(0,c.reversed)(t):t,{orientation:s,prevent_hide:t=>t.target==this.el})}this._hammer=new r.default(this.el,{touchAction:\"auto\",inputClass:r.default.TouchMouseInput}),this.connect(this.model.change,(()=>this.render())),this._hammer.on(\"tap\",(t=>{var e;(null===(e=this._menu)||void 0===e?void 0:e.is_open)?this._menu.hide():t.target==this.el&&this._clicked()})),this._hammer.on(\"press\",(()=>this._pressed())),this.el.addEventListener(\"keydown\",(t=>{t.keyCode==h.Keys.Enter&&this._clicked()}))}remove(){var t;this._hammer.destroy(),null===(t=this._menu)||void 0===t||t.remove(),super.remove()}styles(){return[...super.styles(),m.default,v.default,f.default]}css_classes(){return super.css_classes().concat(p.toolbar_button)}render(){(0,h.empty)(this.el);const t=this.model.computed_icon;(0,d.isString)(t)&&((0,_.startsWith)(t,\"data:image\")?this.el.style.backgroundImage=`url(\"${t}\")`:this.el.classList.add(t)),this.el.title=this.model.tooltip,this.el.tabIndex=0,null!=this._menu&&this.root.el.appendChild(this._menu.el)}_pressed(){var t;const e=(()=>{switch(this.parent.model.toolbar_location){case\"right\":return{left_of:this.el};case\"left\":return{right_of:this.el};case\"above\":return{below:this.el};case\"below\":return{above:this.el}}})();null===(t=this._menu)||void 0===t||t.toggle(e)}}o.ButtonToolButtonView=b,b.__name__=\"ButtonToolButtonView\";class w extends u.ToolView{}o.ButtonToolView=w,w.__name__=\"ButtonToolView\";class y extends u.Tool{constructor(t){super(t)}_get_dim_tooltip(t){const{description:e,tool_name:o}=this;return null!=e?e:\"both\"==t?o:`${o} (${\"width\"==t?\"x\":\"y\"}-axis)`}get tooltip(){var t;return null!==(t=this.description)&&void 0!==t?t:this.tool_name}get computed_icon(){return this.icon}get menu(){return null}}o.ButtonTool=y,l=y,y.__name__=\"ButtonTool\",l.internal((({Boolean:t})=>({disabled:[t,!1]})))},\n", - " function _(t,e,i,n,r){\n", - " /*! Hammer.JS - v2.0.7 - 2016-04-22\n", - " * http://hammerjs.github.io/\n", - " *\n", - " * Copyright (c) 2016 Jorik Tangelder;\n", - " * Licensed under the MIT license */\n", - " !function(t,i,n,r){\"use strict\";var s,o=[\"\",\"webkit\",\"Moz\",\"MS\",\"ms\",\"o\"],a=i.createElement(\"div\"),h=Math.round,u=Math.abs,c=Date.now;function l(t,e,i){return setTimeout(T(t,i),e)}function p(t,e,i){return!!Array.isArray(t)&&(f(t,i[e],i),!0)}function f(t,e,i){var n;if(t)if(t.forEach)t.forEach(e,i);else if(t.length!==r)for(n=0;n\\s*\\(/gm,\"{anonymous}()@\"):\"Unknown Stack Trace\",s=t.console&&(t.console.warn||t.console.log);return s&&s.call(t.console,r,n),e.apply(this,arguments)}}s=\"function\"!=typeof Object.assign?function(t){if(t===r||null===t)throw new TypeError(\"Cannot convert undefined or null to object\");for(var e=Object(t),i=1;i-1}function S(t){return t.trim().split(/\\s+/g)}function b(t,e,i){if(t.indexOf&&!i)return t.indexOf(e);for(var n=0;ni[e]})):n.sort()),n}function x(t,e){for(var i,n,s=e[0].toUpperCase()+e.slice(1),a=0;a1&&!i.firstMultiple?i.firstMultiple=H(e):1===s&&(i.firstMultiple=!1);var o=i.firstInput,a=i.firstMultiple,h=a?a.center:o.center,l=e.center=L(n);e.timeStamp=c(),e.deltaTime=e.timeStamp-o.timeStamp,e.angle=G(h,l),e.distance=j(h,l),function(t,e){var i=e.center,n=t.offsetDelta||{},r=t.prevDelta||{},s=t.prevInput||{};1!==e.eventType&&4!==s.eventType||(r=t.prevDelta={x:s.deltaX||0,y:s.deltaY||0},n=t.offsetDelta={x:i.x,y:i.y});e.deltaX=r.x+(i.x-n.x),e.deltaY=r.y+(i.y-n.y)}(i,e),e.offsetDirection=V(e.deltaX,e.deltaY);var p=U(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=p.x,e.overallVelocityY=p.y,e.overallVelocity=u(p.x)>u(p.y)?p.x:p.y,e.scale=a?(f=a.pointers,v=n,j(v[0],v[1],W)/j(f[0],f[1],W)):1,e.rotation=a?function(t,e){return G(e[1],e[0],W)+G(t[1],t[0],W)}(a.pointers,n):0,e.maxPointers=i.prevInput?e.pointers.length>i.prevInput.maxPointers?e.pointers.length:i.prevInput.maxPointers:e.pointers.length,function(t,e){var i,n,s,o,a=t.lastInterval||e,h=e.timeStamp-a.timeStamp;if(8!=e.eventType&&(h>25||a.velocity===r)){var c=e.deltaX-a.deltaX,l=e.deltaY-a.deltaY,p=U(h,c,l);n=p.x,s=p.y,i=u(p.x)>u(p.y)?p.x:p.y,o=V(c,l),t.lastInterval=e}else i=a.velocity,n=a.velocityX,s=a.velocityY,o=a.direction;e.velocity=i,e.velocityX=n,e.velocityY=s,e.direction=o}(i,e);var f,v;var d=t.element;_(e.srcEvent.target,d)&&(d=e.srcEvent.target);e.target=d}(t,i),t.emit(\"hammer.input\",i),t.recognize(i),t.session.prevInput=i}function H(t){for(var e=[],i=0;i=u(e)?t<0?2:4:e<0?8:16}function j(t,e,i){i||(i=F);var n=e[i[0]]-t[i[0]],r=e[i[1]]-t[i[1]];return Math.sqrt(n*n+r*r)}function G(t,e,i){i||(i=F);var n=e[i[0]]-t[i[0]],r=e[i[1]]-t[i[1]];return 180*Math.atan2(r,n)/Math.PI}q.prototype={handler:function(){},init:function(){this.evEl&&I(this.element,this.evEl,this.domHandler),this.evTarget&&I(this.target,this.evTarget,this.domHandler),this.evWin&&I(O(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&A(this.element,this.evEl,this.domHandler),this.evTarget&&A(this.target,this.evTarget,this.domHandler),this.evWin&&A(O(this.element),this.evWin,this.domHandler)}};var Z={mousedown:1,mousemove:2,mouseup:4},B=\"mousedown\",$=\"mousemove mouseup\";function J(){this.evEl=B,this.evWin=$,this.pressed=!1,q.apply(this,arguments)}g(J,q,{handler:function(t){var e=Z[t.type];1&e&&0===t.button&&(this.pressed=!0),2&e&&1!==t.which&&(e=4),this.pressed&&(4&e&&(this.pressed=!1),this.callback(this.manager,e,{pointers:[t],changedPointers:[t],pointerType:X,srcEvent:t}))}});var K={pointerdown:1,pointermove:2,pointerup:4,pointercancel:8,pointerout:8},Q={2:N,3:\"pen\",4:X,5:\"kinect\"},tt=\"pointerdown\",et=\"pointermove pointerup pointercancel\";function it(){this.evEl=tt,this.evWin=et,q.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}t.MSPointerEvent&&!t.PointerEvent&&(tt=\"MSPointerDown\",et=\"MSPointerMove MSPointerUp MSPointerCancel\"),g(it,q,{handler:function(t){var e=this.store,i=!1,n=t.type.toLowerCase().replace(\"ms\",\"\"),r=K[n],s=Q[t.pointerType]||t.pointerType,o=s==N,a=b(e,t.pointerId,\"pointerId\");1&r&&(0===t.button||o)?a<0&&(e.push(t),a=e.length-1):12&r&&(i=!0),a<0||(e[a]=t,this.callback(this.manager,r,{pointers:e,changedPointers:[t],pointerType:s,srcEvent:t}),i&&e.splice(a,1))}});var nt={touchstart:1,touchmove:2,touchend:4,touchcancel:8},rt=\"touchstart\",st=\"touchstart touchmove touchend touchcancel\";function ot(){this.evTarget=rt,this.evWin=st,this.started=!1,q.apply(this,arguments)}function at(t,e){var i=P(t.touches),n=P(t.changedTouches);return 12&e&&(i=D(i.concat(n),\"identifier\",!0)),[i,n]}g(ot,q,{handler:function(t){var e=nt[t.type];if(1===e&&(this.started=!0),this.started){var i=at.call(this,t,e);12&e&&i[0].length-i[1].length==0&&(this.started=!1),this.callback(this.manager,e,{pointers:i[0],changedPointers:i[1],pointerType:N,srcEvent:t})}}});var ht={touchstart:1,touchmove:2,touchend:4,touchcancel:8},ut=\"touchstart touchmove touchend touchcancel\";function ct(){this.evTarget=ut,this.targetIds={},q.apply(this,arguments)}function lt(t,e){var i=P(t.touches),n=this.targetIds;if(3&e&&1===i.length)return n[i[0].identifier]=!0,[i,i];var r,s,o=P(t.changedTouches),a=[],h=this.target;if(s=i.filter((function(t){return _(t.target,h)})),1===e)for(r=0;r-1&&n.splice(t,1)}),2500)}}function dt(t){for(var e=t.srcEvent.clientX,i=t.srcEvent.clientY,n=0;n-1&&this.requireFail.splice(e,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(t){return!!this.simultaneous[t.id]},emit:function(t){var e=this,i=this.state;function n(i){e.manager.emit(i,t)}i<8&&n(e.options.event+Dt(i)),n(e.options.event),t.additionalEvent&&n(t.additionalEvent),i>=8&&n(e.options.event+Dt(i))},tryEmit:function(t){if(this.canEmit())return this.emit(t);this.state=bt},canEmit:function(){for(var t=0;te.threshold&&r&e.direction},attrTest:function(t){return Ot.prototype.attrTest.call(this,t)&&(2&this.state||!(2&this.state)&&this.directionTest(t))},emit:function(t){this.pX=t.deltaX,this.pY=t.deltaY;var e=xt(t.direction);e&&(t.additionalEvent=this.options.event+e),this._super.emit.call(this,t)}}),g(Mt,Ot,{defaults:{event:\"pinch\",threshold:0,pointers:2},getTouchAction:function(){return[It]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.scale-1)>this.options.threshold||2&this.state)},emit:function(t){if(1!==t.scale){var e=t.scale<1?\"in\":\"out\";t.additionalEvent=this.options.event+e}this._super.emit.call(this,t)}}),g(zt,Pt,{defaults:{event:\"press\",pointers:1,time:251,threshold:9},getTouchAction:function(){return[yt]},process:function(t){var e=this.options,i=t.pointers.length===e.pointers,n=t.distancee.time;if(this._input=t,!n||!i||12&t.eventType&&!r)this.reset();else if(1&t.eventType)this.reset(),this._timer=l((function(){this.state=8,this.tryEmit()}),e.time,this);else if(4&t.eventType)return 8;return bt},reset:function(){clearTimeout(this._timer)},emit:function(t){8===this.state&&(t&&4&t.eventType?this.manager.emit(this.options.event+\"up\",t):(this._input.timeStamp=c(),this.manager.emit(this.options.event,this._input)))}}),g(Nt,Ot,{defaults:{event:\"rotate\",threshold:0,pointers:2},getTouchAction:function(){return[It]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.rotation)>this.options.threshold||2&this.state)}}),g(Xt,Ot,{defaults:{event:\"swipe\",threshold:10,velocity:.3,direction:30,pointers:1},getTouchAction:function(){return Rt.prototype.getTouchAction.call(this)},attrTest:function(t){var e,i=this.options.direction;return 30&i?e=t.overallVelocity:6&i?e=t.overallVelocityX:i&Y&&(e=t.overallVelocityY),this._super.attrTest.call(this,t)&&i&t.offsetDirection&&t.distance>this.options.threshold&&t.maxPointers==this.options.pointers&&u(e)>this.options.velocity&&4&t.eventType},emit:function(t){var e=xt(t.offsetDirection);e&&this.manager.emit(this.options.event+e,t),this.manager.emit(this.options.event,t)}}),g(Yt,Pt,{defaults:{event:\"tap\",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[Et]},process:function(t){var e=this.options,i=t.pointers.length===e.pointers,n=t.distance .bk-divider{cursor:default;overflow:hidden;background-color:#e5e5e5;}.bk-root .bk-context-menu.bk-horizontal > .bk-divider{width:1px;margin:5px 0;}.bk-root .bk-context-menu.bk-vertical > .bk-divider{height:1px;margin:0 5px;}.bk-root .bk-context-menu > :not(.bk-divider){border:1px solid transparent;}.bk-root .bk-context-menu > :not(.bk-divider).bk-active{border-color:#26aae1;}.bk-root .bk-context-menu > :not(.bk-divider):hover{background-color:#f9f9f9;}.bk-root .bk-context-menu > :not(.bk-divider):focus,.bk-root .bk-context-menu > :not(.bk-divider):focus-visible{outline:1px dotted #26aae1;outline-offset:-1px;}.bk-root .bk-context-menu > :not(.bk-divider)::-moz-focus-inner{border:0;}.bk-root .bk-context-menu.bk-horizontal > :not(.bk-divider):first-child{border-top-left-radius:4px;border-bottom-left-radius:4px;}.bk-root .bk-context-menu.bk-horizontal > :not(.bk-divider):last-child{border-top-right-radius:4px;border-bottom-right-radius:4px;}.bk-root .bk-context-menu.bk-vertical > :not(.bk-divider):first-child{border-top-left-radius:4px;border-top-right-radius:4px;}.bk-root .bk-context-menu.bk-vertical > :not(.bk-divider):last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;}.bk-root .bk-menu{position:absolute;left:0;width:100%;z-index:100;cursor:pointer;font-size:12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 6px 12px rgba(0, 0, 0, 0.175);}.bk-root .bk-menu.bk-above{bottom:100%;}.bk-root .bk-menu.bk-below{top:100%;}.bk-root .bk-menu > .bk-divider{height:1px;margin:7.5px 0;overflow:hidden;background-color:#e5e5e5;}.bk-root .bk-menu > :not(.bk-divider){padding:6px 12px;}.bk-root .bk-menu > :not(.bk-divider):hover,.bk-root .bk-menu > :not(.bk-divider).bk-active{background-color:#e6e6e6;}.bk-root .bk-caret{display:inline-block;vertical-align:middle;width:0;height:0;margin:0 5px;}.bk-root .bk-caret.bk-down{border-top:4px solid;}.bk-root .bk-caret.bk-up{border-bottom:4px solid;}.bk-root .bk-caret.bk-down,.bk-root .bk-caret.bk-up{border-right:4px solid transparent;border-left:4px solid transparent;}.bk-root .bk-caret.bk-left{border-right:4px solid;}.bk-root .bk-caret.bk-right{border-left:4px solid;}.bk-root .bk-caret.bk-left,.bk-root .bk-caret.bk-right{border-top:4px solid transparent;border-bottom:4px solid transparent;}\"},\n", - " function _(t,e,i,n,o){n();const s=t(1),l=t(43),h=t(9),r=(0,s.__importStar)(t(229));class d{constructor(t,e={}){var i,n;this.items=t,this.el=(0,l.div)(),this._open=!1,this._item_click=t=>{var e;null===(e=t.handler)||void 0===e||e.call(t),this.hide()},this._on_mousedown=t=>{var e;const{target:i}=t;i instanceof Node&&this.el.contains(i)||(null===(e=this.prevent_hide)||void 0===e?void 0:e.call(this,t))||this.hide()},this._on_keydown=t=>{t.keyCode==l.Keys.Esc&&this.hide()},this._on_blur=()=>{this.hide()},this.orientation=null!==(i=e.orientation)&&void 0!==i?i:\"vertical\",this.reversed=null!==(n=e.reversed)&&void 0!==n&&n,this.prevent_hide=e.prevent_hide,(0,l.undisplay)(this.el)}get is_open(){return this._open}get can_open(){return 0!=this.items.length}remove(){(0,l.remove)(this.el),this._unlisten()}_listen(){document.addEventListener(\"mousedown\",this._on_mousedown),document.addEventListener(\"keydown\",this._on_keydown),window.addEventListener(\"blur\",this._on_blur)}_unlisten(){document.removeEventListener(\"mousedown\",this._on_mousedown),document.removeEventListener(\"keydown\",this._on_keydown),window.removeEventListener(\"blur\",this._on_blur)}_position(t){const e=this.el.parentElement;if(null!=e){const i=(()=>{if(\"left_of\"in t){const{left:e,top:i}=t.left_of.getBoundingClientRect();return{right:e,top:i}}if(\"right_of\"in t){const{top:e,right:i}=t.right_of.getBoundingClientRect();return{left:i,top:e}}if(\"below\"in t){const{left:e,bottom:i}=t.below.getBoundingClientRect();return{left:e,top:i}}if(\"above\"in t){const{left:e,top:i}=t.above.getBoundingClientRect();return{left:e,bottom:i}}return t})(),n=e.getBoundingClientRect();this.el.style.left=null!=i.left?i.left-n.left+\"px\":\"\",this.el.style.top=null!=i.top?i.top-n.top+\"px\":\"\",this.el.style.right=null!=i.right?n.right-i.right+\"px\":\"\",this.el.style.bottom=null!=i.bottom?n.bottom-i.bottom+\"px\":\"\"}}render(){var t;(0,l.empty)(this.el,!0),(0,l.classes)(this.el).add(\"bk-context-menu\",`bk-${this.orientation}`);const e=this.reversed?(0,h.reversed)(this.items):this.items;for(const i of e){let e;if(null==i)e=(0,l.div)({class:r.divider});else{if(null!=i.if&&!i.if())continue;if(null!=i.content)e=i.content;else{const n=null!=i.icon?(0,l.div)({class:[\"bk-menu-icon\",i.icon]}):null,o=[(null===(t=i.active)||void 0===t?void 0:t.call(i))?\"bk-active\":null,i.class];e=(0,l.div)({class:o,title:i.tooltip,tabIndex:0},n,i.label,i.content),e.addEventListener(\"click\",(()=>{this._item_click(i)})),e.addEventListener(\"keydown\",(t=>{t.keyCode==l.Keys.Enter&&this._item_click(i)}))}}this.el.appendChild(e)}}show(t){if(0!=this.items.length&&!this._open){if(this.render(),0==this.el.children.length)return;this._position(null!=t?t:{left:0,top:0}),(0,l.display)(this.el),this._listen(),this._open=!0}}hide(){this._open&&(this._open=!1,this._unlisten(),(0,l.undisplay)(this.el))}toggle(t){this._open?this.hide():this.show(t)}}i.ContextMenu=d,d.__name__=\"ContextMenu\"},\n", - " function _(t,e,i,n,o){n();const s=t(1),c=t(224),l=(0,s.__importStar)(t(227)),a=t(43);class _ extends c.ButtonToolButtonView{render(){super.render(),(0,a.classes)(this.el).toggle(l.active,this.model.active)}_clicked(){const{active:t}=this.model;this.model.active=!t}}i.OnOffButtonView=_,_.__name__=\"OnOffButtonView\"},\n", - " function _(e,o,t,n,s){var c;n();const l=e(224),_=e(231);class i extends l.ButtonToolView{}t.InspectToolView=i,i.__name__=\"InspectToolView\";class a extends l.ButtonTool{constructor(e){super(e),this.event_type=\"move\"}}t.InspectTool=a,c=a,a.__name__=\"InspectTool\",c.prototype.button_view=_.OnOffButtonView,c.define((({Boolean:e})=>({toggleable:[e,!0]}))),c.override({active:!0})},\n", - " function _(t,o,e,l,i){l();const s=t(1);var n,a;const r=t(19),c=t(43),h=t(113),_=t(226),u=t(20),v=t(9),d=t(234),p=t(13),b=t(8),g=t(235),f=t(65),m=t(53),w=t(222),y=t(223),T=t(238),z=t(239),x=t(232),B=t(230),C=(0,s.__importStar)(t(227)),k=C,L=(0,s.__importStar)(t(240)),M=L;class S extends m.Model{constructor(t){super(t)}get visible(){var t;return!this.autohide||null!==(t=this._visible)&&void 0!==t&&t}}e.ToolbarViewModel=S,n=S,S.__name__=\"ToolbarViewModel\",n.define((({Boolean:t})=>({autohide:[t,!1]}))),n.internal((({Boolean:t,Nullable:o})=>({_visible:[o(t),null]})));class $ extends _.DOMView{constructor(){super(...arguments),this.layout={bbox:new f.BBox}}initialize(){super.initialize(),this._tool_button_views=new Map,this._toolbar_view_model=new S({autohide:this.model.autohide});const{toolbar_location:t}=this.model,o=\"left\"==t||\"above\"==t,e=this.model.horizontal?\"vertical\":\"horizontal\";this._overflow_menu=new B.ContextMenu([],{orientation:e,reversed:o})}async lazy_initialize(){await super.lazy_initialize(),await this._build_tool_button_views()}connect_signals(){super.connect_signals(),this.connect(this.model.properties.tools.change,(async()=>{await this._build_tool_button_views(),this.render()})),this.connect(this.model.properties.autohide.change,(()=>{this._toolbar_view_model.autohide=this.model.autohide,this._on_visible_change()})),this.connect(this._toolbar_view_model.properties._visible.change,(()=>this._on_visible_change()))}styles(){return[...super.styles(),C.default,L.default]}remove(){(0,h.remove_views)(this._tool_button_views),super.remove()}async _build_tool_button_views(){const t=null!=this.model._proxied_tools?this.model._proxied_tools:this.model.tools;await(0,h.build_views)(this._tool_button_views,t,{parent:this},(t=>t.button_view))}set_visibility(t){t!=this._toolbar_view_model._visible&&(this._toolbar_view_model._visible=t)}_on_visible_change(){const{visible:t}=this._toolbar_view_model;(0,c.classes)(this.el).toggle(k.toolbar_hidden,!t)}render(){(0,c.empty)(this.el),this.el.classList.add(k.toolbar),this.el.classList.add(k[this.model.toolbar_location]),this._toolbar_view_model.autohide=this.model.autohide,this._on_visible_change();const{horizontal:t}=this.model;let o=0;if(null!=this.model.logo){const e=\"grey\"===this.model.logo?M.grey:null,l=(0,c.a)({href:\"https://bokeh.org/\",target:\"_blank\",class:[M.logo,M.logo_small,e]});this.el.appendChild(l);const{width:i,height:s}=l.getBoundingClientRect();o+=t?i:s}for(const[,t]of this._tool_button_views)t.render();const e=[],l=t=>this._tool_button_views.get(t).el,{gestures:i}=this.model;for(const t of(0,p.values)(i))e.push(t.tools.map(l));e.push(this.model.actions.map(l)),e.push(this.model.inspectors.filter((t=>t.toggleable)).map(l));const s=e.filter((t=>0!=t.length)),n=()=>(0,c.div)({class:k.divider}),{bbox:a}=this.layout;let r=!1;this.root.el.appendChild(this._overflow_menu.el);const h=(0,c.div)({class:k.tool_overflow,tabIndex:0},t?\"\\u22ee\":\"\\u22ef\"),_=()=>{const t=(()=>{switch(this.model.toolbar_location){case\"right\":return{left_of:h};case\"left\":return{right_of:h};case\"above\":return{below:h};case\"below\":return{above:h}}})();this._overflow_menu.toggle(t)};h.addEventListener(\"click\",(()=>{_()})),h.addEventListener(\"keydown\",(t=>{t.keyCode==c.Keys.Enter&&_()}));for(const e of(0,d.join)(s,n))if(r)this._overflow_menu.items.push({content:e,class:t?k.right:k.above});else{this.el.appendChild(e);const{width:l,height:i}=e.getBoundingClientRect();if(o+=t?l:i,r=t?o>a.width-15:o>a.height-15,r){this.el.removeChild(e),this.el.appendChild(h);const{items:t}=this._overflow_menu;t.splice(0,t.length),t.push({content:e})}}}update_layout(){}update_position(){}after_layout(){this._has_finished=!0}export(t,o=!0){const e=\"png\"==t?\"canvas\":\"svg\",l=new g.CanvasLayer(e,o);return l.resize(0,0),l}}function V(){return{pan:{tools:[],active:null},scroll:{tools:[],active:null},pinch:{tools:[],active:null},tap:{tools:[],active:null},doubletap:{tools:[],active:null},press:{tools:[],active:null},pressup:{tools:[],active:null},rotate:{tools:[],active:null},move:{tools:[],active:null},multi:{tools:[],active:null}}}e.ToolbarBaseView=$,$.__name__=\"ToolbarBaseView\";class A extends m.Model{constructor(t){super(t)}initialize(){super.initialize(),this._init_tools()}_init_tools(){const t=function(t,o){if(t.length!=o.length)return!0;const e=new Set(o.map((t=>t.id)));return(0,v.some)(t,(t=>!e.has(t.id)))},o=this.tools.filter((t=>t instanceof x.InspectTool));t(this.inspectors,o)&&(this.inspectors=o);const e=this.tools.filter((t=>t instanceof z.HelpTool));t(this.help,e)&&(this.help=e);const l=this.tools.filter((t=>t instanceof T.ActionTool));t(this.actions,l)&&(this.actions=l);const i=(t,o)=>{t in this.gestures||r.logger.warn(`Toolbar: unknown event type '${t}' for tool: ${o}`)},s={pan:{tools:[],active:null},scroll:{tools:[],active:null},pinch:{tools:[],active:null},tap:{tools:[],active:null},doubletap:{tools:[],active:null},press:{tools:[],active:null},pressup:{tools:[],active:null},rotate:{tools:[],active:null},move:{tools:[],active:null},multi:{tools:[],active:null}};for(const t of this.tools)if(t instanceof y.GestureTool&&t.event_type)if((0,b.isString)(t.event_type))s[t.event_type].tools.push(t),i(t.event_type,t);else{s.multi.tools.push(t);for(const o of t.event_type)i(o,t)}for(const o of Object.keys(s)){const e=this.gestures[o];t(e.tools,s[o].tools)&&(e.tools=s[o].tools),e.active&&(0,v.every)(e.tools,(t=>t.id!=e.active.id))&&(e.active=null)}}get horizontal(){return\"above\"===this.toolbar_location||\"below\"===this.toolbar_location}get vertical(){return\"left\"===this.toolbar_location||\"right\"===this.toolbar_location}_active_change(t){const{event_type:o}=t;if(null==o)return;const e=(0,b.isString)(o)?[o]:o;for(const o of e)if(t.active){const e=this.gestures[o].active;null!=e&&t!=e&&(r.logger.debug(`Toolbar: deactivating tool: ${e} for event type '${o}'`),e.active=!1),this.gestures[o].active=t,r.logger.debug(`Toolbar: activating tool: ${t} for event type '${o}'`)}else this.gestures[o].active=null}}e.ToolbarBase=A,a=A,A.__name__=\"ToolbarBase\",a.prototype.default_view=$,a.define((({Boolean:t,Array:o,Ref:e,Nullable:l})=>({tools:[o(e(w.Tool)),[]],logo:[l(u.Logo),\"normal\"],autohide:[t,!1]}))),a.internal((({Array:t,Struct:o,Ref:e,Nullable:l})=>{const i=o({tools:t(e(y.GestureTool)),active:l(e(w.Tool))});return{gestures:[o({pan:i,scroll:i,pinch:i,tap:i,doubletap:i,press:i,pressup:i,rotate:i,move:i,multi:i}),V],actions:[t(e(T.ActionTool)),[]],inspectors:[t(e(x.InspectTool)),[]],help:[t(e(z.HelpTool)),[]],toolbar_location:[u.Location,\"right\"]}}))},\n", - " function _(n,o,e,t,f){t();const r=n(9);function*i(n,o){const e=n.length;if(o>e)return;const t=(0,r.range)(o);for(yield t.map((o=>n[o]));;){let f;for(const n of(0,r.reversed)((0,r.range)(o)))if(t[n]!=n+e-o){f=n;break}if(null==f)return;t[f]+=1;for(const n of(0,r.range)(f+1,o))t[n]=t[n-1]+1;yield t.map((o=>n[o]))}}e.enumerate=function*(n){let o=0;for(const e of n)yield[e,o++]},e.join=function*(n,o){let e=!0;for(const t of n)e?e=!1:null!=o&&(yield o()),yield*t},e.combinations=i,e.subsets=function*(n){for(const o of(0,r.range)(n.length+1))yield*i(n,o)}},\n", - " function _(t,e,s,i,n){i();const o=t(236),a=t(65),r=t(43);function h(t){!function(t){void 0===t.lineDash&&Object.defineProperty(t,\"lineDash\",{get:()=>t.getLineDash(),set:e=>t.setLineDash(e)})}(t),function(t){t.setImageSmoothingEnabled=e=>{t.imageSmoothingEnabled=e,t.mozImageSmoothingEnabled=e,t.oImageSmoothingEnabled=e,t.webkitImageSmoothingEnabled=e,t.msImageSmoothingEnabled=e},t.getImageSmoothingEnabled=()=>{const e=t.imageSmoothingEnabled;return null==e||e}}(t),function(t){t.ellipse||(t.ellipse=function(e,s,i,n,o,a,r,h=!1){const l=.551784;t.translate(e,s),t.rotate(o);let c=i,g=n;h&&(c=-i,g=-n),t.moveTo(-c,0),t.bezierCurveTo(-c,g*l,-c*l,g,0,g),t.bezierCurveTo(c*l,g,c,g*l,c,0),t.bezierCurveTo(c,-g*l,c*l,-g,0,-g),t.bezierCurveTo(-c*l,-g,-c,-g*l,-c,0),t.rotate(-o),t.translate(-e,-s)})}(t)}const l={position:\"absolute\",top:\"0\",left:\"0\",width:\"100%\",height:\"100%\"};class c{constructor(t,e){switch(this.backend=t,this.hidpi=e,this.pixel_ratio=1,this.bbox=new a.BBox,t){case\"webgl\":case\"canvas\":{this._el=this._canvas=(0,r.canvas)({style:l});const t=this.canvas.getContext(\"2d\");if(null==t)throw new Error(\"unable to obtain 2D rendering context\");this._ctx=t,e&&(this.pixel_ratio=devicePixelRatio);break}case\"svg\":{const t=new o.SVGRenderingContext2D;this._ctx=t,this._canvas=t.get_svg(),this._el=(0,r.div)({style:l},this._canvas);break}}this._ctx.layer=this,h(this._ctx)}get canvas(){return this._canvas}get ctx(){return this._ctx}get el(){return this._el}resize(t,e){this.bbox=new a.BBox({left:0,top:0,width:t,height:e});const s=this._ctx instanceof o.SVGRenderingContext2D?this._ctx:this.canvas;s.width=t*this.pixel_ratio,s.height=e*this.pixel_ratio}undo_transform(t){const{ctx:e}=this;if(void 0===e.getTransform)t(e);else{const s=e.getTransform();e.setTransform(this._base_transform);try{t(e)}finally{e.setTransform(s)}}}prepare(){const{ctx:t,hidpi:e,pixel_ratio:s}=this;t.save(),e&&(t.scale(s,s),t.translate(.5,.5)),void 0!==t.getTransform&&(this._base_transform=t.getTransform()),this.clear()}clear(){const{x:t,y:e,width:s,height:i}=this.bbox;this.ctx.clearRect(t,e,s,i)}finish(){this.ctx.restore()}to_blob(){const{_canvas:t}=this;if(t instanceof HTMLCanvasElement)return null!=t.msToBlob?Promise.resolve(t.msToBlob()):new Promise(((e,s)=>{t.toBlob((t=>null!=t?e(t):s()),\"image/png\")}));{const t=this._ctx.get_serialized_svg(!0),e=new Blob([t],{type:\"image/svg+xml\"});return Promise.resolve(e)}}}s.CanvasLayer=c,c.__name__=\"CanvasLayer\"},\n", - " function _(t,e,i,s,r){s();const n=t(122),a=t(8),o=t(237),l=t(10),h=t(43);function _(t){var e;const i={left:\"start\",right:\"end\",center:\"middle\",start:\"start\",end:\"end\"};return null!==(e=i[t])&&void 0!==e?e:i.start}function c(t){var e;const i={alphabetic:\"alphabetic\",hanging:\"hanging\",top:\"text-before-edge\",bottom:\"text-after-edge\",middle:\"central\"};return null!==(e=i[t])&&void 0!==e?e:i.alphabetic}const p=function(t,e){const i=new Map,s=t.split(\",\");e=null!=e?e:10;for(let t=0;t=0?Math.acos(e):-Math.acos(e)}const v=b(f),A=b(g);this.lineTo(d+f[0]*r,m+f[1]*r),this.arc(d,m,r,v,A)}stroke(){\"path\"===this.__currentElement.nodeName&&this.__currentElement.setAttribute(\"paint-order\",\"fill\"),this.__applyCurrentDefaultPath(),this.__applyStyleToCurrentElement(\"stroke\"),null!=this._clip_path&&this.__currentElement.setAttribute(\"clip-path\",this._clip_path)}fill(t,e){let i=null;if(t instanceof Path2D)i=t;else{if(\"evenodd\"!=t&&\"nonzero\"!=t&&null!=t||null!=e)throw new Error(\"invalid arguments\");e=t}if(null!=i)throw new Error(\"not implemented\");\"none\"!=this.__currentElement.getAttribute(\"fill\")&&this.__init_element(),\"path\"===this.__currentElement.nodeName&&this.__currentElement.setAttribute(\"paint-order\",\"stroke\"),this.__applyCurrentDefaultPath(),this.__applyStyleToCurrentElement(\"fill\"),null!=e&&this.__currentElement.setAttribute(\"fill-rule\",e),null!=this._clip_path&&this.__currentElement.setAttribute(\"clip-path\",this._clip_path)}rect(t,e,i,s){isFinite(t+e+i+s)&&(this.moveTo(t,e),this.lineTo(t+i,e),this.lineTo(t+i,e+s),this.lineTo(t,e+s),this.lineTo(t,e))}fillRect(t,e,i,s){isFinite(t+e+i+s)&&(this.beginPath(),this.rect(t,e,i,s),this.fill())}strokeRect(t,e,i,s){isFinite(t+e+i+s)&&(this.beginPath(),this.rect(t,e,i,s),this.stroke())}__clearCanvas(){(0,h.empty)(this.__defs),(0,h.empty)(this.__root),this.__root.appendChild(this.__defs),this.__currentElement=this.__root}clearRect(t,e,i,s){if(!isFinite(t+e+i+s))return;if(0===t&&0===e&&i===this.width&&s===this.height)return void this.__clearCanvas();const r=this.__createElement(\"rect\",{x:t,y:e,width:i,height:s,fill:\"#FFFFFF\"},!0);this._apply_transform(r),this.__root.appendChild(r)}createLinearGradient(t,e,i,s){if(!isFinite(t+e+i+s))throw new Error(\"The provided double value is non-finite\");const[r,n]=this._transform.apply(t,e),[a,o]=this._transform.apply(i,s),l=this.__createElement(\"linearGradient\",{id:this._random_string(),x1:`${r}px`,x2:`${a}px`,y1:`${n}px`,y2:`${o}px`,gradientUnits:\"userSpaceOnUse\"},!1);return this.__defs.appendChild(l),new d(l,this)}createRadialGradient(t,e,i,s,r,n){if(!isFinite(t+e+i+s+r+n))throw new Error(\"The provided double value is non-finite\");const[a,o]=this._transform.apply(t,e),[l,h]=this._transform.apply(s,r),_=this.__createElement(\"radialGradient\",{id:this._random_string(),cx:`${l}px`,cy:`${h}px`,r:`${n}px`,r0:`${i}px`,fx:`${a}px`,fy:`${o}px`,gradientUnits:\"userSpaceOnUse\"},!1);return this.__defs.appendChild(_),new d(_,this)}__parseFont(){var t,e,i,s,r;const n=/^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))(?:\\s*\\/\\s*(normal|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])))?\\s*([-,\\'\\\"\\sa-z0-9]+?)\\s*$/i.exec(this.font);return{style:null!==(t=n[1])&&void 0!==t?t:\"normal\",size:null!==(e=n[4])&&void 0!==e?e:\"10px\",family:null!==(i=n[6])&&void 0!==i?i:\"sans-serif\",weight:null!==(s=n[3])&&void 0!==s?s:\"normal\",decoration:null!==(r=n[2])&&void 0!==r?r:\"normal\"}}__applyText(t,e,i,s){const r=this.__parseFont(),n=this.__createElement(\"text\",{\"font-family\":r.family,\"font-size\":r.size,\"font-style\":r.style,\"font-weight\":r.weight,\"text-decoration\":r.decoration,x:e,y:i,\"text-anchor\":_(this.textAlign),\"dominant-baseline\":c(this.textBaseline)},!0);n.appendChild(this.__document.createTextNode(t)),this._apply_transform(n),this.__currentElement=n,this.__applyStyleToCurrentElement(s);const a=(()=>{if(null!=this._clip_path){const t=this.__createElement(\"g\");return t.setAttribute(\"clip-path\",this._clip_path),t.appendChild(n),t}return n})();this.__root.appendChild(a)}fillText(t,e,i){null!=t&&isFinite(e+i)&&this.__applyText(t,e,i,\"fill\")}strokeText(t,e,i){null!=t&&isFinite(e+i)&&this.__applyText(t,e,i,\"stroke\")}measureText(t){return this.__ctx.font=this.font,this.__ctx.measureText(t)}arc(t,e,i,s,r,n=!1){this.ellipse(t,e,i,i,0,s,r,n)}ellipse(t,e,i,s,r,n,a,o=!1){if(!isFinite(t+e+i+s+r+n+a))return;if(i<0||s<0)throw new DOMException(\"IndexSizeError, radius can't be negative\");const h=o?a-n:n-a;n%=2*Math.PI,a%=2*Math.PI;const _=t+i*Math.cos(n),c=e+s*Math.sin(n);this.lineTo(_,c);const p=180*r/Math.PI,u=o?0:1;if(Math.abs(n-a)<2*l.float32_epsilon&&!(Math.abs(h)<2*l.float32_epsilon&&h<0)){const r=t+i*Math.cos(n+Math.PI),a=e+s*Math.sin(n+Math.PI),[o,l]=this._transform.apply(_,c),[h,d]=this._transform.apply(r,a);this.__addPathCommand(o,l,`A ${i} ${s} ${p} 0 ${u} ${h} ${d} A ${i} ${s} ${p} 0 ${u} ${o} ${l}`)}else{const r=t+i*Math.cos(a),l=e+s*Math.sin(a);let h=a-n;h<0&&(h+=2*Math.PI);const _=o!==h>Math.PI?1:0,[c,d]=this._transform.apply(r,l);this.__addPathCommand(c,d,`A ${i} ${s} ${p} ${_} ${u} ${c} ${d}`)}}clip(){const t=this.__createElement(\"clipPath\"),e=this._random_string();this.__applyCurrentDefaultPath(),t.setAttribute(\"id\",e),t.appendChild(this.__currentElement),this.__defs.appendChild(t),this._clip_path=`url(#${e})`}drawImage(t,...e){let i,s,r,n,a,o,l,h;if(2==e.length){if([i,s]=e,!isFinite(i+s))return;a=0,o=0,l=t.width,h=t.height,r=l,n=h}else if(4==e.length){if([i,s,r,n]=e,!isFinite(i+s+r+n))return;a=0,o=0,l=t.width,h=t.height}else{if(8!==e.length)throw new Error(`Inavlid number of arguments passed to drawImage: ${arguments.length}`);if([a,o,l,h,i,s,r,n]=e,!isFinite(a+o+l+h+i+s+r+n))return}const _=this.__root,c=this._transform.clone().translate(i,s);if(t instanceof f||t instanceof SVGSVGElement){const e=(t instanceof SVGSVGElement?t:t.get_svg()).cloneNode(!0);let i;c.is_identity&&1==this.globalAlpha&&null==this._clip_path?i=_:(i=this.__createElement(\"g\"),c.is_identity||this._apply_transform(i,c),1!=this.globalAlpha&&i.setAttribute(\"opacity\",`${this.globalAlpha}`),null!=this._clip_path&&i.setAttribute(\"clip-path\",this._clip_path),_.appendChild(i));for(const t of[...e.childNodes])if(t instanceof SVGDefsElement){for(const e of[...t.childNodes])if(e instanceof Element){const t=e.getAttribute(\"id\");this.__ids.add(t),this.__defs.appendChild(e.cloneNode(!0))}}else i.appendChild(t.cloneNode(!0))}else if(t instanceof HTMLImageElement||t instanceof SVGImageElement){const e=this.__createElement(\"image\");if(e.setAttribute(\"width\",`${r}`),e.setAttribute(\"height\",`${n}`),e.setAttribute(\"preserveAspectRatio\",\"none\"),1!=this.globalAlpha&&e.setAttribute(\"opacity\",`${this.globalAlpha}`),a||o||l!==t.width||h!==t.height){const e=this.__document.createElement(\"canvas\");e.width=r,e.height=n;e.getContext(\"2d\").drawImage(t,a,o,l,h,0,0,r,n),t=e}this._apply_transform(e,c);const i=t instanceof HTMLCanvasElement?t.toDataURL():t.getAttribute(\"src\");if(e.setAttribute(\"href\",i),null!=this._clip_path){const t=this.__createElement(\"g\");t.setAttribute(\"clip-path\",this._clip_path),t.appendChild(e),_.appendChild(t)}else _.appendChild(e)}else if(t instanceof HTMLCanvasElement){const e=this.__createElement(\"image\");e.setAttribute(\"width\",`${r}`),e.setAttribute(\"height\",`${n}`),e.setAttribute(\"preserveAspectRatio\",\"none\"),1!=this.globalAlpha&&e.setAttribute(\"opacity\",`${this.globalAlpha}`);const i=this.__document.createElement(\"canvas\");i.width=r,i.height=n;const s=i.getContext(\"2d\");if(s.imageSmoothingEnabled=!1,s.drawImage(t,a,o,l,h,0,0,r,n),t=i,this._apply_transform(e,c),e.setAttribute(\"href\",t.toDataURL()),null!=this._clip_path){const t=this.__createElement(\"g\");t.setAttribute(\"clip-path\",this._clip_path),t.appendChild(e),_.appendChild(t)}else _.appendChild(e)}}createPattern(t,e){const i=this.__document.createElementNS(\"http://www.w3.org/2000/svg\",\"pattern\"),s=this._random_string();if(i.setAttribute(\"id\",s),i.setAttribute(\"width\",`${this._to_number(t.width)}`),i.setAttribute(\"height\",`${this._to_number(t.height)}`),i.setAttribute(\"patternUnits\",\"userSpaceOnUse\"),t instanceof HTMLCanvasElement||t instanceof HTMLImageElement||t instanceof SVGImageElement){const e=this.__document.createElementNS(\"http://www.w3.org/2000/svg\",\"image\"),s=t instanceof HTMLCanvasElement?t.toDataURL():t.getAttribute(\"src\");e.setAttribute(\"href\",s),i.appendChild(e),this.__defs.appendChild(i)}else if(t instanceof f){for(const e of[...t.__root.childNodes])e instanceof SVGDefsElement||i.appendChild(e.cloneNode(!0));this.__defs.appendChild(i)}else{if(!(t instanceof SVGSVGElement))throw new Error(\"unsupported\");for(const e of[...t.childNodes])e instanceof SVGDefsElement||i.appendChild(e.cloneNode(!0));this.__defs.appendChild(i)}return new m(i,this)}getLineDash(){const{lineDash:t}=this;return(0,a.isString)(t)?t.split(\",\").map((t=>parseInt(t))):null==t?[]:t}setLineDash(t){t&&t.length>0?this.lineDash=t.join(\",\"):this.lineDash=null}_to_number(t){return(0,a.isNumber)(t)?t:t.baseVal.value}getTransform(){return this._transform.to_DOMMatrix()}setTransform(...t){let e;e=(0,a.isNumber)(t[0])?new DOMMatrix(t):t[0]instanceof DOMMatrix?t[0]:new DOMMatrix(Object.values(!t[0])),this._transform=n.AffineTransform.from_DOMMatrix(e)}resetTransform(){this._transform=new n.AffineTransform}isPointInPath(...t){throw new Error(\"not implemented\")}isPointInStroke(...t){throw new Error(\"not implemented\")}createImageData(...t){throw new Error(\"not implemented\")}getImageData(t,e,i,s){throw new Error(\"not implemented\")}putImageData(...t){throw new Error(\"not implemented\")}drawFocusIfNeeded(...t){throw new Error(\"not implemented\")}scrollPathIntoView(...t){throw new Error(\"not implemented\")}}i.SVGRenderingContext2D=f,f.__name__=\"SVGRenderingContext2D\",f.__random=o.random},\n", - " function _(e,t,s,n,r){n();const o=2147483647;class i{constructor(e){this.seed=e%o,this.seed<=0&&(this.seed+=2147483646)}integer(){return this.seed=48271*this.seed%o,this.seed}float(){return(this.integer()-1)/2147483646}floats(e,t=0,s=1){const n=new Array(e);for(let r=0;rthis.doit(o)))}}n.ActionToolView=_,_.__name__=\"ActionToolView\";class d extends s.ButtonTool{constructor(o){super(o),this.button_view=l,this.do=new c.Signal(this,\"do\")}}n.ActionTool=d,d.__name__=\"ActionTool\"},\n", - " function _(o,e,t,l,i){var s;l();const n=o(238),r=o(228);class c extends n.ActionToolView{doit(){window.open(this.model.redirect)}}t.HelpToolView=c,c.__name__=\"HelpToolView\";class _ extends n.ActionTool{constructor(o){super(o),this.tool_name=\"Help\",this.icon=r.tool_icon_help}}t.HelpTool=_,s=_,_.__name__=\"HelpTool\",s.prototype.default_view=c,s.define((({String:o})=>({redirect:[o,\"https://docs.bokeh.org/en/latest/docs/user_guide/tools.html\"]}))),s.override({description:\"Click the question mark to learn more about Bokeh plot tools.\"}),s.register_alias(\"help\",(()=>new _))},\n", - " function _(o,l,g,A,r){A(),g.root=\"bk-root\",g.logo=\"bk-logo\",g.grey=\"bk-grey\",g.logo_small=\"bk-logo-small\",g.logo_notebook=\"bk-logo-notebook\",g.default=\".bk-root .bk-logo{margin:5px;position:relative;display:block;background-repeat:no-repeat;}.bk-root .bk-logo.bk-grey{filter:url(\\\"data:image/svg+xml;utf8,#grayscale\\\");filter:gray;-webkit-filter:grayscale(100%);}.bk-root .bk-logo-small{width:20px;height:20px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAOkSURBVDiNjZRtaJVlGMd/1/08zzln5zjP1LWcU9N0NkN8m2CYjpgQYQXqSs0I84OLIC0hkEKoPtiH3gmKoiJDU7QpLgoLjLIQCpEsNJ1vqUOdO7ppbuec5+V+rj4ctwzd8IIbbi6u+8f1539dt3A78eXC7QizUF7gyV1fD1Yqg4JWz84yffhm0qkFqBogB9rM8tZdtwVsPUhWhGcFJngGeWrPzHm5oaMmkfEg1usvLFyc8jLRqDOMru7AyC8saQr7GG7f5fvDeH7Ej8CM66nIF+8yngt6HWaKh7k49Soy9nXurCi1o3qUbS3zWfrYeQDTB/Qj6kX6Ybhw4B+bOYoLKCC9H3Nu/leUTZ1JdRWkkn2ldcCamzrcf47KKXdAJllSlxAOkRgyHsGC/zRday5Qld9DyoM4/q/rUoy/CXh3jzOu3bHUVZeU+DEn8FInkPBFlu3+nW3Nw0mk6vCDiWg8CeJaxEwuHS3+z5RgY+YBR6V1Z1nxSOfoaPa4LASWxxdNp+VWTk7+4vzaou8v8PN+xo+KY2xsw6une2frhw05CTYOmQvsEhjhWjn0bmXPjpE1+kplmmkP3suftwTubK9Vq22qKmrBhpY4jvd5afdRA3wGjFAgcnTK2s4hY0/GPNIb0nErGMCRxWOOX64Z8RAC4oCXdklmEvcL8o0BfkNK4lUg9HTl+oPlQxdNo3Mg4Nv175e/1LDGzZen30MEjRUtmXSfiTVu1kK8W4txyV6BMKlbgk3lMwYCiusNy9fVfvvwMxv8Ynl6vxoByANLTWplvuj/nF9m2+PDtt1eiHPBr1oIfhCChQMBw6Aw0UulqTKZdfVvfG7VcfIqLG9bcldL/+pdWTLxLUy8Qq38heUIjh4XlzZxzQm19lLFlr8vdQ97rjZVOLf8nclzckbcD4wxXMidpX30sFd37Fv/GtwwhzhxGVAprjbg0gCAEeIgwCZyTV2Z1REEW8O4py0wsjeloKoMr6iCY6dP92H6Vw/oTyICIthibxjm/DfN9lVz8IqtqKYLUXfoKVMVQVVJOElGjrnnUt9T9wbgp8AyYKaGlqingHZU/uG2NTZSVqwHQTWkx9hxjkpWDaCg6Ckj5qebgBVbT3V3NNXMSiWSDdGV3hrtzla7J+duwPOToIg42ChPQOQjspnSlp1V+Gjdged7+8UN5CRAV7a5EdFNwCjEaBR27b3W890TE7g24NAP/mMDXRWrGoFPQI9ls/MWO2dWFAar/xcOIImbbpA3zgAAAABJRU5ErkJggg==);}.bk-root .bk-logo-notebook{display:inline-block;vertical-align:middle;margin-right:5px;}\"},\n", - " function _(e,t,s,i,l){i();const o=e(1);var n;const a=e(40),h=e(20),r=e(43),c=(0,o.__importStar)(e(242)),d=c;class p extends a.AnnotationView{initialize(){super.initialize(),this.el=(0,r.div)({class:d.tooltip}),(0,r.undisplay)(this.el),this.plot_view.canvas_view.add_overlay(this.el)}remove(){(0,r.remove)(this.el),super.remove()}connect_signals(){super.connect_signals(),this.connect(this.model.properties.content.change,(()=>this.render())),this.connect(this.model.properties.position.change,(()=>this._reposition()))}styles(){return[...super.styles(),c.default]}render(){this.model.visible||(0,r.undisplay)(this.el),super.render()}_render(){const{content:e}=this.model;null!=e?((0,r.empty)(this.el),(0,r.classes)(this.el).toggle(\"bk-tooltip-custom\",this.model.custom),this.el.appendChild(e),this.model.show_arrow&&this.el.classList.add(d.tooltip_arrow)):(0,r.undisplay)(this.el)}_reposition(){const{position:e}=this.model;if(null==e)return void(0,r.undisplay)(this.el);const[t,s]=e,i=(()=>{const e=this.parent.layout.bbox.relative(),{attachment:i}=this.model;switch(i){case\"horizontal\":return t({attachment:[h.TooltipAttachment,\"horizontal\"],inner_only:[e,!0],show_arrow:[e,!0]}))),n.internal((({Boolean:e,Number:t,Tuple:s,Ref:i,Nullable:l})=>({position:[l(s(t,t)),null],content:[i(HTMLElement),()=>(0,r.div)()],custom:[e]}))),n.override({level:\"overlay\"})},\n", - " function _(o,t,r,e,l){e(),r.root=\"bk-root\",r.tooltip=\"bk-tooltip\",r.left=\"bk-left\",r.tooltip_arrow=\"bk-tooltip-arrow\",r.right=\"bk-right\",r.above=\"bk-above\",r.below=\"bk-below\",r.tooltip_row_label=\"bk-tooltip-row-label\",r.tooltip_row_value=\"bk-tooltip-row-value\",r.tooltip_color_block=\"bk-tooltip-color-block\",r.default='.bk-root{}.bk-root .bk-tooltip{font-weight:300;font-size:12px;position:absolute;padding:5px;border:1px solid #e5e5e5;color:#2f2f2f;background-color:white;pointer-events:none;opacity:0.95;z-index:100;}.bk-root .bk-tooltip > div:not(:first-child){margin-top:5px;border-top:#e5e5e5 1px dashed;}.bk-root .bk-tooltip.bk-left.bk-tooltip-arrow::before{position:absolute;margin:-7px 0 0 0;top:50%;width:0;height:0;border-style:solid;border-width:7px 0 7px 0;border-color:transparent;content:\" \";display:block;left:-10px;border-right-width:10px;border-right-color:#909599;}.bk-root .bk-tooltip.bk-left::before{left:-10px;border-right-width:10px;border-right-color:#909599;}.bk-root .bk-tooltip.bk-right.bk-tooltip-arrow::after{position:absolute;margin:-7px 0 0 0;top:50%;width:0;height:0;border-style:solid;border-width:7px 0 7px 0;border-color:transparent;content:\" \";display:block;right:-10px;border-left-width:10px;border-left-color:#909599;}.bk-root .bk-tooltip.bk-right::after{right:-10px;border-left-width:10px;border-left-color:#909599;}.bk-root .bk-tooltip.bk-above::before{position:absolute;margin:0 0 0 -7px;left:50%;width:0;height:0;border-style:solid;border-width:0 7px 0 7px;border-color:transparent;content:\" \";display:block;top:-10px;border-bottom-width:10px;border-bottom-color:#909599;}.bk-root .bk-tooltip.bk-below::after{position:absolute;margin:0 0 0 -7px;left:50%;width:0;height:0;border-style:solid;border-width:0 7px 0 7px;border-color:transparent;content:\" \";display:block;bottom:-10px;border-top-width:10px;border-top-color:#909599;}.bk-root .bk-tooltip-row-label{text-align:right;color:#26aae1;}.bk-root .bk-tooltip-row-value{color:default;}.bk-root .bk-tooltip-color-block{width:12px;height:12px;margin-left:5px;margin-right:5px;outline:#dddddd solid 1px;display:inline-block;}'},\n", - " function _(e,t,s,i,r){var a;i();const l=e(115),_=e(112),h=e(113),o=e(48);class n extends l.UpperLowerView{async lazy_initialize(){await super.lazy_initialize();const{lower_head:e,upper_head:t}=this.model;null!=e&&(this.lower_head=await(0,h.build_view)(e,{parent:this})),null!=t&&(this.upper_head=await(0,h.build_view)(t,{parent:this}))}set_data(e){var t,s;super.set_data(e),null===(t=this.lower_head)||void 0===t||t.set_data(e),null===(s=this.upper_head)||void 0===s||s.set_data(e)}paint(e){if(this.visuals.line.doit)for(let t=0,s=this._lower_sx.length;t({lower_head:[t(e(_.ArrowHead)),()=>new _.TeeHead({size:10})],upper_head:[t(e(_.ArrowHead)),()=>new _.TeeHead({size:10})]}))),a.override({level:\"underlay\"})},\n", - " function _(n,o,t,u,e){u(),e(\"CustomJS\",n(245).CustomJS),e(\"OpenURL\",n(247).OpenURL)},\n", - " function _(t,e,s,n,c){var a;n();const r=t(246),u=t(13),o=t(34);class i extends r.Callback{constructor(t){super(t)}get names(){return(0,u.keys)(this.args)}get values(){return(0,u.values)(this.args)}get func(){const t=(0,o.use_strict)(this.code);return new Function(...this.names,\"cb_obj\",\"cb_data\",t)}execute(t,e={}){return this.func.apply(t,this.values.concat(t,e))}}s.CustomJS=i,a=i,i.__name__=\"CustomJS\",a.define((({Unknown:t,String:e,Dict:s})=>({args:[s(t),{}],code:[e,\"\"]})))},\n", - " function _(c,a,l,n,s){n();const e=c(53);class o extends e.Model{constructor(c){super(c)}}l.Callback=o,o.__name__=\"Callback\"},\n", - " function _(e,t,n,o,i){var s;o();const c=e(246),r=e(152),a=e(8);class d extends c.Callback{constructor(e){super(e)}navigate(e){this.same_tab?window.location.href=e:window.open(e)}execute(e,{source:t}){const n=e=>{const n=(0,r.replace_placeholders)(this.url,t,e,void 0,void 0,encodeURI);if(!(0,a.isString)(n))throw new Error(\"HTML output is not supported in this context\");this.navigate(n)},{selected:o}=t;for(const e of o.indices)n(e);for(const e of o.line_indices)n(e)}}n.OpenURL=d,s=d,d.__name__=\"OpenURL\",s.define((({Boolean:e,String:t})=>({url:[t,\"http://\"],same_tab:[e,!1]})))},\n", - " function _(a,n,i,e,r){e(),r(\"Canvas\",a(249).Canvas),r(\"CartesianFrame\",a(126).CartesianFrame),r(\"CoordinateMapping\",a(54).CoordinateMapping)},\n", - " function _(e,t,i,s,a){var l,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i),Object.defineProperty(e,s,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&r(t,e,i);return n(t,e),t};s();const h=e(14),c=e(28),u=e(226),_=e(19),d=e(43),p=e(20),b=e(13),v=e(250),g=e(65),w=e(138),y=e(235);const f=(()=>{let t;return async()=>void 0!==t?t:t=await async function(){const t=document.createElement(\"canvas\"),i=t.getContext(\"webgl\",{premultipliedAlpha:!0});if(null!=i){const s=await(0,w.load_module)(Promise.resolve().then((()=>o(e(410)))));if(null!=s){const e=s.get_regl(i);if(e.has_webgl)return{canvas:t,regl_wrapper:e};_.logger.trace(\"WebGL is supported, but not the required extensions\")}else _.logger.trace(\"WebGL is supported, but bokehjs(.min).js bundle is not available\")}else _.logger.trace(\"WebGL is not supported\");return null}()})(),m={position:\"absolute\",top:\"0\",left:\"0\",width:\"100%\",height:\"100%\"};class x extends u.DOMView{constructor(){super(...arguments),this.bbox=new g.BBox,this.webgl=null}initialize(){super.initialize(),this.underlays_el=(0,d.div)({style:m}),this.primary=this.create_layer(),this.overlays=this.create_layer(),this.overlays_el=(0,d.div)({style:m}),this.events_el=(0,d.div)({class:\"bk-canvas-events\",style:m});const e=[this.underlays_el,this.primary.el,this.overlays.el,this.overlays_el,this.events_el];(0,b.extend)(this.el.style,m),(0,d.append)(this.el,...e),this.ui_event_bus=new v.UIEventBus(this)}async lazy_initialize(){if(await super.lazy_initialize(),\"webgl\"==this.model.output_backend&&(this.webgl=await f(),c.settings.force_webgl&&null==this.webgl))throw new Error(\"webgl is not available\")}remove(){this.ui_event_bus.destroy(),super.remove()}add_underlay(e){this.underlays_el.appendChild(e)}add_overlay(e){this.overlays_el.appendChild(e)}add_event(e){this.events_el.appendChild(e)}get pixel_ratio(){return this.primary.pixel_ratio}resize(e,t){this.bbox=new g.BBox({left:0,top:0,width:e,height:t}),this.primary.resize(e,t),this.overlays.resize(e,t)}prepare_webgl(e){const{webgl:t}=this;if(null!=t){const{width:i,height:s}=this.bbox;t.canvas.width=this.pixel_ratio*i,t.canvas.height=this.pixel_ratio*s;const[a,l,r,n]=e,{xview:o,yview:h}=this.bbox,c=o.compute(a),u=h.compute(l+n),_=this.pixel_ratio;t.regl_wrapper.set_scissor(_*c,_*u,_*r,_*n),this._clear_webgl()}}blit_webgl(e){const{webgl:t}=this;if(null!=t){if(_.logger.debug(\"Blitting WebGL canvas\"),e.restore(),e.drawImage(t.canvas,0,0),e.save(),this.model.hidpi){const t=this.pixel_ratio;e.scale(t,t),e.translate(.5,.5)}this._clear_webgl()}}_clear_webgl(){const{webgl:e}=this;if(null!=e){const{regl_wrapper:t,canvas:i}=e;t.clear(i.width,i.height)}}compose(){const e=this.create_layer(),{width:t,height:i}=this.bbox;return e.resize(t,i),e.ctx.drawImage(this.primary.canvas,0,0),e.ctx.drawImage(this.overlays.canvas,0,0),e}create_layer(){const{output_backend:e,hidpi:t}=this.model;return new y.CanvasLayer(e,t)}to_blob(){return this.compose().to_blob()}}i.CanvasView=x,x.__name__=\"CanvasView\";class z extends h.HasProps{constructor(e){super(e)}}i.Canvas=z,l=z,z.__name__=\"Canvas\",l.prototype.default_view=x,l.internal((({Boolean:e})=>({hidpi:[e,!0],output_backend:[p.OutputBackend,\"canvas\"]})))},\n", - " function _(t,e,s,n,i){n();const r=t(1),a=(0,r.__importDefault)(t(225)),_=t(15),h=t(19),o=t(43),l=(0,r.__importStar)(t(251)),c=t(252),p=t(9),u=t(8),v=t(27),d=t(230);class g{constructor(t){this.canvas_view=t,this.pan_start=new _.Signal(this,\"pan:start\"),this.pan=new _.Signal(this,\"pan\"),this.pan_end=new _.Signal(this,\"pan:end\"),this.pinch_start=new _.Signal(this,\"pinch:start\"),this.pinch=new _.Signal(this,\"pinch\"),this.pinch_end=new _.Signal(this,\"pinch:end\"),this.rotate_start=new _.Signal(this,\"rotate:start\"),this.rotate=new _.Signal(this,\"rotate\"),this.rotate_end=new _.Signal(this,\"rotate:end\"),this.tap=new _.Signal(this,\"tap\"),this.doubletap=new _.Signal(this,\"doubletap\"),this.press=new _.Signal(this,\"press\"),this.pressup=new _.Signal(this,\"pressup\"),this.move_enter=new _.Signal(this,\"move:enter\"),this.move=new _.Signal(this,\"move\"),this.move_exit=new _.Signal(this,\"move:exit\"),this.scroll=new _.Signal(this,\"scroll\"),this.keydown=new _.Signal(this,\"keydown\"),this.keyup=new _.Signal(this,\"keyup\"),this.hammer=new a.default(this.hit_area,{touchAction:\"auto\",inputClass:a.default.TouchMouseInput}),this._prev_move=null,this._curr_pan=null,this._curr_pinch=null,this._curr_rotate=null,this._configure_hammerjs(),this.hit_area.addEventListener(\"mousemove\",(t=>this._mouse_move(t))),this.hit_area.addEventListener(\"mouseenter\",(t=>this._mouse_enter(t))),this.hit_area.addEventListener(\"mouseleave\",(t=>this._mouse_exit(t))),this.hit_area.addEventListener(\"contextmenu\",(t=>this._context_menu(t))),this.hit_area.addEventListener(\"wheel\",(t=>this._mouse_wheel(t))),document.addEventListener(\"keydown\",this),document.addEventListener(\"keyup\",this),this.menu=new d.ContextMenu([],{prevent_hide:t=>2==t.button&&t.target==this.hit_area}),this.hit_area.appendChild(this.menu.el)}get hit_area(){return this.canvas_view.events_el}destroy(){this.menu.remove(),this.hammer.destroy(),document.removeEventListener(\"keydown\",this),document.removeEventListener(\"keyup\",this)}handleEvent(t){\"keydown\"==t.type?this._key_down(t):\"keyup\"==t.type&&this._key_up(t)}_configure_hammerjs(){this.hammer.get(\"doubletap\").recognizeWith(\"tap\"),this.hammer.get(\"tap\").requireFailure(\"doubletap\"),this.hammer.get(\"doubletap\").dropRequireFailure(\"tap\"),this.hammer.on(\"doubletap\",(t=>this._doubletap(t))),this.hammer.on(\"tap\",(t=>this._tap(t))),this.hammer.on(\"press\",(t=>this._press(t))),this.hammer.on(\"pressup\",(t=>this._pressup(t))),this.hammer.get(\"pan\").set({direction:a.default.DIRECTION_ALL}),this.hammer.on(\"panstart\",(t=>this._pan_start(t))),this.hammer.on(\"pan\",(t=>this._pan(t))),this.hammer.on(\"panend\",(t=>this._pan_end(t))),this.hammer.get(\"pinch\").set({enable:!0}),this.hammer.on(\"pinchstart\",(t=>this._pinch_start(t))),this.hammer.on(\"pinch\",(t=>this._pinch(t))),this.hammer.on(\"pinchend\",(t=>this._pinch_end(t))),this.hammer.get(\"rotate\").set({enable:!0}),this.hammer.on(\"rotatestart\",(t=>this._rotate_start(t))),this.hammer.on(\"rotate\",(t=>this._rotate(t))),this.hammer.on(\"rotateend\",(t=>this._rotate_end(t)))}register_tool(t){const e=t.model.event_type;null!=e&&((0,u.isString)(e)?this._register_tool(t,e):e.forEach(((e,s)=>this._register_tool(t,e,s<1))))}_register_tool(t,e,s=!0){const n=t,{id:i}=n.model,r=t=>e=>{e.id==i&&t(e.e)},a=t=>e=>{t(e.e)};switch(e){case\"pan\":null!=n._pan_start&&n.connect(this.pan_start,r(n._pan_start.bind(n))),null!=n._pan&&n.connect(this.pan,r(n._pan.bind(n))),null!=n._pan_end&&n.connect(this.pan_end,r(n._pan_end.bind(n)));break;case\"pinch\":null!=n._pinch_start&&n.connect(this.pinch_start,r(n._pinch_start.bind(n))),null!=n._pinch&&n.connect(this.pinch,r(n._pinch.bind(n))),null!=n._pinch_end&&n.connect(this.pinch_end,r(n._pinch_end.bind(n)));break;case\"rotate\":null!=n._rotate_start&&n.connect(this.rotate_start,r(n._rotate_start.bind(n))),null!=n._rotate&&n.connect(this.rotate,r(n._rotate.bind(n))),null!=n._rotate_end&&n.connect(this.rotate_end,r(n._rotate_end.bind(n)));break;case\"move\":null!=n._move_enter&&n.connect(this.move_enter,r(n._move_enter.bind(n))),null!=n._move&&n.connect(this.move,r(n._move.bind(n))),null!=n._move_exit&&n.connect(this.move_exit,r(n._move_exit.bind(n)));break;case\"tap\":null!=n._tap&&n.connect(this.tap,r(n._tap.bind(n))),null!=n._doubletap&&n.connect(this.doubletap,r(n._doubletap.bind(n)));break;case\"press\":null!=n._press&&n.connect(this.press,r(n._press.bind(n))),null!=n._pressup&&n.connect(this.pressup,r(n._pressup.bind(n)));break;case\"scroll\":null!=n._scroll&&n.connect(this.scroll,r(n._scroll.bind(n)));break;default:throw new Error(`unsupported event_type: ${e}`)}s&&(null!=n._keydown&&n.connect(this.keydown,a(n._keydown.bind(n))),null!=n._keyup&&n.connect(this.keyup,a(n._keyup.bind(n))),v.is_mobile&&null!=n._scroll&&\"pinch\"==e&&(h.logger.debug(\"Registering scroll on touch screen\"),n.connect(this.scroll,r(n._scroll.bind(n)))))}_hit_test_renderers(t,e,s){var n;const i=t.get_renderer_views();for(const t of(0,p.reversed)(i))if(null===(n=t.interactive_hit)||void 0===n?void 0:n.call(t,e,s))return t;return null}set_cursor(t=\"default\"){this.hit_area.style.cursor=t}_hit_test_frame(t,e,s){return t.frame.bbox.contains(e,s)}_hit_test_canvas(t,e,s){return t.layout.bbox.contains(e,s)}_hit_test_plot(t,e){for(const s of this.canvas_view.plot_views)if(s.layout.bbox.relative().contains(t,e))return s;return null}_trigger(t,e,s){var n;const{sx:i,sy:r}=e,a=this._hit_test_plot(i,r),_=t=>{const[s,n]=[i,r];return Object.assign(Object.assign({},e),{sx:s,sy:n})};if(\"panstart\"==e.type||\"pan\"==e.type||\"panend\"==e.type){let n;if(\"panstart\"==e.type&&null!=a?(this._curr_pan={plot_view:a},n=a):\"pan\"==e.type&&null!=this._curr_pan?n=this._curr_pan.plot_view:\"panend\"==e.type&&null!=this._curr_pan?(n=this._curr_pan.plot_view,this._curr_pan=null):n=null,null!=n){const e=_();this.__trigger(n,t,e,s)}}else if(\"pinchstart\"==e.type||\"pinch\"==e.type||\"pinchend\"==e.type){let n;if(\"pinchstart\"==e.type&&null!=a?(this._curr_pinch={plot_view:a},n=a):\"pinch\"==e.type&&null!=this._curr_pinch?n=this._curr_pinch.plot_view:\"pinchend\"==e.type&&null!=this._curr_pinch?(n=this._curr_pinch.plot_view,this._curr_pinch=null):n=null,null!=n){const e=_();this.__trigger(n,t,e,s)}}else if(\"rotatestart\"==e.type||\"rotate\"==e.type||\"rotateend\"==e.type){let n;if(\"rotatestart\"==e.type&&null!=a?(this._curr_rotate={plot_view:a},n=a):\"rotate\"==e.type&&null!=this._curr_rotate?n=this._curr_rotate.plot_view:\"rotateend\"==e.type&&null!=this._curr_rotate?(n=this._curr_rotate.plot_view,this._curr_rotate=null):n=null,null!=n){const e=_();this.__trigger(n,t,e,s)}}else if(\"mouseenter\"==e.type||\"mousemove\"==e.type||\"mouseleave\"==e.type){const h=null===(n=this._prev_move)||void 0===n?void 0:n.plot_view;if(null!=h&&(\"mouseleave\"==e.type||h!=a)){const{sx:t,sy:e}=_();this.__trigger(h,this.move_exit,{type:\"mouseleave\",sx:t,sy:e,shiftKey:!1,ctrlKey:!1},s)}if(null!=a&&(\"mouseenter\"==e.type||h!=a)){const{sx:t,sy:e}=_();this.__trigger(a,this.move_enter,{type:\"mouseenter\",sx:t,sy:e,shiftKey:!1,ctrlKey:!1},s)}if(null!=a&&\"mousemove\"==e.type){const e=_();this.__trigger(a,t,e,s)}this._prev_move={sx:i,sy:r,plot_view:a}}else if(null!=a){const e=_();this.__trigger(a,t,e,s)}}__trigger(t,e,s,n){var i,r,a;const _=t.model.toolbar.gestures,h=e.name.split(\":\")[0],o=this._hit_test_renderers(t,s.sx,s.sy),l=this._hit_test_canvas(t,s.sx,s.sy);switch(h){case\"move\":{const n=_.move.active;null!=n&&this.trigger(e,s,n.id);const r=t.model.toolbar.inspectors.filter((t=>t.active));let a=\"default\";null!=o?(a=null!==(i=o.cursor(s.sx,s.sy))&&void 0!==i?i:a,(0,p.is_empty)(r)||(e=this.move_exit)):this._hit_test_frame(t,s.sx,s.sy)&&((0,p.is_empty)(r)||(a=\"crosshair\")),this.set_cursor(a),t.set_toolbar_visibility(l),r.map((t=>this.trigger(e,s,t.id)));break}case\"tap\":{const{target:i}=n;if(null!=i&&i!=this.hit_area)return;if(null===(r=null==o?void 0:o.on_hit)||void 0===r||r.call(o,s.sx,s.sy),this._hit_test_frame(t,s.sx,s.sy)){const t=_.tap.active;null!=t&&this.trigger(e,s,t.id)}break}case\"doubletap\":if(this._hit_test_frame(t,s.sx,s.sy)){const t=null!==(a=_.doubletap.active)&&void 0!==a?a:_.tap.active;null!=t&&this.trigger(e,s,t.id)}break;case\"scroll\":{const t=_[v.is_mobile?\"pinch\":\"scroll\"].active;null!=t&&(n.preventDefault(),n.stopPropagation(),this.trigger(e,s,t.id));break}case\"pan\":{const t=_.pan.active;null!=t&&(n.preventDefault(),this.trigger(e,s,t.id));break}default:{const t=_[h].active;null!=t&&this.trigger(e,s,t.id)}}this._trigger_bokeh_event(t,s)}trigger(t,e,s=null){t.emit({id:s,e})}_trigger_bokeh_event(t,e){const s=(()=>{const{sx:s,sy:n}=e,i=t.frame.x_scale.invert(s),r=t.frame.y_scale.invert(n);switch(e.type){case\"wheel\":return new l.MouseWheel(s,n,i,r,e.delta);case\"mousemove\":return new l.MouseMove(s,n,i,r);case\"mouseenter\":return new l.MouseEnter(s,n,i,r);case\"mouseleave\":return new l.MouseLeave(s,n,i,r);case\"tap\":return new l.Tap(s,n,i,r);case\"doubletap\":return new l.DoubleTap(s,n,i,r);case\"press\":return new l.Press(s,n,i,r);case\"pressup\":return new l.PressUp(s,n,i,r);case\"pan\":return new l.Pan(s,n,i,r,e.deltaX,e.deltaY);case\"panstart\":return new l.PanStart(s,n,i,r);case\"panend\":return new l.PanEnd(s,n,i,r);case\"pinch\":return new l.Pinch(s,n,i,r,e.scale);case\"pinchstart\":return new l.PinchStart(s,n,i,r);case\"pinchend\":return new l.PinchEnd(s,n,i,r);case\"rotate\":return new l.Rotate(s,n,i,r,e.rotation);case\"rotatestart\":return new l.RotateStart(s,n,i,r);case\"rotateend\":return new l.RotateEnd(s,n,i,r);default:return}})();null!=s&&t.model.trigger_event(s)}_get_sxy(t){const{pageX:e,pageY:s}=function(t){return\"undefined\"!=typeof TouchEvent&&t instanceof TouchEvent}(t)?(0!=t.touches.length?t.touches:t.changedTouches)[0]:t,{left:n,top:i}=(0,o.offset)(this.hit_area);return{sx:e-n,sy:s-i}}_pan_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t.srcEvent)),{deltaX:t.deltaX,deltaY:t.deltaY,shiftKey:t.srcEvent.shiftKey,ctrlKey:t.srcEvent.ctrlKey})}_pinch_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t.srcEvent)),{scale:t.scale,shiftKey:t.srcEvent.shiftKey,ctrlKey:t.srcEvent.ctrlKey})}_rotate_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t.srcEvent)),{rotation:t.rotation,shiftKey:t.srcEvent.shiftKey,ctrlKey:t.srcEvent.ctrlKey})}_tap_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t.srcEvent)),{shiftKey:t.srcEvent.shiftKey,ctrlKey:t.srcEvent.ctrlKey})}_move_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t)),{shiftKey:t.shiftKey,ctrlKey:t.ctrlKey})}_scroll_event(t){return Object.assign(Object.assign({type:t.type},this._get_sxy(t)),{delta:(0,c.getDeltaY)(t),shiftKey:t.shiftKey,ctrlKey:t.ctrlKey})}_key_event(t){return{type:t.type,keyCode:t.keyCode}}_pan_start(t){const e=this._pan_event(t);e.sx-=t.deltaX,e.sy-=t.deltaY,this._trigger(this.pan_start,e,t.srcEvent)}_pan(t){this._trigger(this.pan,this._pan_event(t),t.srcEvent)}_pan_end(t){this._trigger(this.pan_end,this._pan_event(t),t.srcEvent)}_pinch_start(t){this._trigger(this.pinch_start,this._pinch_event(t),t.srcEvent)}_pinch(t){this._trigger(this.pinch,this._pinch_event(t),t.srcEvent)}_pinch_end(t){this._trigger(this.pinch_end,this._pinch_event(t),t.srcEvent)}_rotate_start(t){this._trigger(this.rotate_start,this._rotate_event(t),t.srcEvent)}_rotate(t){this._trigger(this.rotate,this._rotate_event(t),t.srcEvent)}_rotate_end(t){this._trigger(this.rotate_end,this._rotate_event(t),t.srcEvent)}_tap(t){this._trigger(this.tap,this._tap_event(t),t.srcEvent)}_doubletap(t){this._trigger(this.doubletap,this._tap_event(t),t.srcEvent)}_press(t){this._trigger(this.press,this._tap_event(t),t.srcEvent)}_pressup(t){this._trigger(this.pressup,this._tap_event(t),t.srcEvent)}_mouse_enter(t){this._trigger(this.move_enter,this._move_event(t),t)}_mouse_move(t){this._trigger(this.move,this._move_event(t),t)}_mouse_exit(t){this._trigger(this.move_exit,this._move_event(t),t)}_mouse_wheel(t){this._trigger(this.scroll,this._scroll_event(t),t)}_context_menu(t){!this.menu.is_open&&this.menu.can_open&&t.preventDefault();const{sx:e,sy:s}=this._get_sxy(t);this.menu.toggle({left:e,top:s})}_key_down(t){this.trigger(this.keydown,this._key_event(t))}_key_up(t){this.trigger(this.keyup,this._key_event(t))}}s.UIEventBus=g,g.__name__=\"UIEventBus\"},\n", - " function _(e,t,s,n,_){n();var a=this&&this.__decorate||function(e,t,s,n){var _,a=arguments.length,o=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,s):n;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,s,n);else for(var r=e.length-1;r>=0;r--)(_=e[r])&&(o=(a<3?_(o):a>3?_(t,s,o):_(t,s))||o);return a>3&&o&&Object.defineProperty(t,s,o),o};function o(e){return function(t){t.prototype.event_name=e}}class r{to_json(){const{event_name:e}=this;return{event_name:e,event_values:this._to_json()}}}s.BokehEvent=r,r.__name__=\"BokehEvent\";class c extends r{constructor(){super(...arguments),this.origin=null}_to_json(){return{model:this.origin}}}s.ModelEvent=c,c.__name__=\"ModelEvent\";let l=class extends r{_to_json(){return{}}};s.DocumentReady=l,l.__name__=\"DocumentReady\",s.DocumentReady=l=a([o(\"document_ready\")],l);let i=class extends c{};s.ButtonClick=i,i.__name__=\"ButtonClick\",s.ButtonClick=i=a([o(\"button_click\")],i);let u=class extends c{constructor(e){super(),this.item=e}_to_json(){const{item:e}=this;return Object.assign(Object.assign({},super._to_json()),{item:e})}};s.MenuItemClick=u,u.__name__=\"MenuItemClick\",s.MenuItemClick=u=a([o(\"menu_item_click\")],u);class d extends c{}s.UIEvent=d,d.__name__=\"UIEvent\";let m=class extends d{};s.LODStart=m,m.__name__=\"LODStart\",s.LODStart=m=a([o(\"lodstart\")],m);let h=class extends d{};s.LODEnd=h,h.__name__=\"LODEnd\",s.LODEnd=h=a([o(\"lodend\")],h);let p=class extends d{constructor(e,t,s,n){super(),this.x0=e,this.x1=t,this.y0=s,this.y1=n}_to_json(){const{x0:e,x1:t,y0:s,y1:n}=this;return Object.assign(Object.assign({},super._to_json()),{x0:e,x1:t,y0:s,y1:n})}};s.RangesUpdate=p,p.__name__=\"RangesUpdate\",s.RangesUpdate=p=a([o(\"rangesupdate\")],p);let x=class extends d{constructor(e,t){super(),this.geometry=e,this.final=t}_to_json(){const{geometry:e,final:t}=this;return Object.assign(Object.assign({},super._to_json()),{geometry:e,final:t})}};s.SelectionGeometry=x,x.__name__=\"SelectionGeometry\",s.SelectionGeometry=x=a([o(\"selectiongeometry\")],x);let j=class extends d{};s.Reset=j,j.__name__=\"Reset\",s.Reset=j=a([o(\"reset\")],j);class y extends d{constructor(e,t,s,n){super(),this.sx=e,this.sy=t,this.x=s,this.y=n}_to_json(){const{sx:e,sy:t,x:s,y:n}=this;return Object.assign(Object.assign({},super._to_json()),{sx:e,sy:t,x:s,y:n})}}s.PointEvent=y,y.__name__=\"PointEvent\";let g=class extends y{constructor(e,t,s,n,_,a){super(e,t,s,n),this.delta_x=_,this.delta_y=a}_to_json(){const{delta_x:e,delta_y:t}=this;return Object.assign(Object.assign({},super._to_json()),{delta_x:e,delta_y:t})}};s.Pan=g,g.__name__=\"Pan\",s.Pan=g=a([o(\"pan\")],g);let P=class extends y{constructor(e,t,s,n,_){super(e,t,s,n),this.scale=_}_to_json(){const{scale:e}=this;return Object.assign(Object.assign({},super._to_json()),{scale:e})}};s.Pinch=P,P.__name__=\"Pinch\",s.Pinch=P=a([o(\"pinch\")],P);let O=class extends y{constructor(e,t,s,n,_){super(e,t,s,n),this.rotation=_}_to_json(){const{rotation:e}=this;return Object.assign(Object.assign({},super._to_json()),{rotation:e})}};s.Rotate=O,O.__name__=\"Rotate\",s.Rotate=O=a([o(\"rotate\")],O);let b=class extends y{constructor(e,t,s,n,_){super(e,t,s,n),this.delta=_}_to_json(){const{delta:e}=this;return Object.assign(Object.assign({},super._to_json()),{delta:e})}};s.MouseWheel=b,b.__name__=\"MouseWheel\",s.MouseWheel=b=a([o(\"wheel\")],b);let v=class extends y{};s.MouseMove=v,v.__name__=\"MouseMove\",s.MouseMove=v=a([o(\"mousemove\")],v);let E=class extends y{};s.MouseEnter=E,E.__name__=\"MouseEnter\",s.MouseEnter=E=a([o(\"mouseenter\")],E);let R=class extends y{};s.MouseLeave=R,R.__name__=\"MouseLeave\",s.MouseLeave=R=a([o(\"mouseleave\")],R);let M=class extends y{};s.Tap=M,M.__name__=\"Tap\",s.Tap=M=a([o(\"tap\")],M);let f=class extends y{};s.DoubleTap=f,f.__name__=\"DoubleTap\",s.DoubleTap=f=a([o(\"doubletap\")],f);let S=class extends y{};s.Press=S,S.__name__=\"Press\",s.Press=S=a([o(\"press\")],S);let D=class extends y{};s.PressUp=D,D.__name__=\"PressUp\",s.PressUp=D=a([o(\"pressup\")],D);let k=class extends y{};s.PanStart=k,k.__name__=\"PanStart\",s.PanStart=k=a([o(\"panstart\")],k);let L=class extends y{};s.PanEnd=L,L.__name__=\"PanEnd\",s.PanEnd=L=a([o(\"panend\")],L);let U=class extends y{};s.PinchStart=U,U.__name__=\"PinchStart\",s.PinchStart=U=a([o(\"pinchstart\")],U);let C=class extends y{};s.PinchEnd=C,C.__name__=\"PinchEnd\",s.PinchEnd=C=a([o(\"pinchend\")],C);let T=class extends y{};s.RotateStart=T,T.__name__=\"RotateStart\",s.RotateStart=T=a([o(\"rotatestart\")],T);let B=class extends y{};s.RotateEnd=B,B.__name__=\"RotateEnd\",s.RotateEnd=B=a([o(\"rotateend\")],B)},\n", - " function _(t,e,n,l,o){\n", - " /*!\n", - " * jQuery Mousewheel 3.1.13\n", - " *\n", - " * Copyright jQuery Foundation and other contributors\n", - " * Released under the MIT license\n", - " * http://jquery.org/license\n", - " */\n", - " function u(t){const e=getComputedStyle(t).fontSize;return null!=e?parseInt(e,10):null}l(),n.getDeltaY=function(t){let e=-t.deltaY;if(t.target instanceof HTMLElement)switch(t.deltaMode){case t.DOM_DELTA_LINE:e*=(n=t.target,null!==(a=null!==(o=u(null!==(l=n.offsetParent)&&void 0!==l?l:document.body))&&void 0!==o?o:u(n))&&void 0!==a?a:16);break;case t.DOM_DELTA_PAGE:e*=function(t){return t.clientHeight}(t.target)}var n,l,o,a;return e}},\n", - " function _(m,o,n,r,a){r(),a(\"Expression\",m(254).Expression),a(\"CustomJSExpr\",m(255).CustomJSExpr),a(\"Stack\",m(256).Stack),a(\"CumSum\",m(257).CumSum),a(\"ScalarExpression\",m(254).ScalarExpression),a(\"Minimum\",m(258).Minimum),a(\"Maximum\",m(259).Maximum);var s=m(260);a(\"XComponent\",s.XComponent),a(\"YComponent\",s.YComponent),a(\"PolarTransform\",m(261).PolarTransform)},\n", - " function _(e,t,s,i,r){i();const n=e(53);class _ extends n.Model{constructor(e){super(e)}initialize(){super.initialize(),this._result=new Map}v_compute(e){let t=this._result.get(e);return(void 0===t||e.changed_for(this))&&(t=this._v_compute(e),this._result.set(e,t)),t}}s.Expression=_,_.__name__=\"Expression\";class o extends n.Model{constructor(e){super(e)}initialize(){super.initialize(),this._result=new Map}compute(e){let t=this._result.get(e);return(void 0===t||e.changed_for(this))&&(t=this._compute(e),this._result.set(e,t)),t}}s.ScalarExpression=o,o.__name__=\"ScalarExpression\"},\n", - " function _(e,s,t,n,r){var a;n();const o=e(14),c=e(254),i=e(24),u=e(9),l=e(13),h=e(34),g=e(8);class p extends c.Expression{constructor(e){super(e)}connect_signals(){super.connect_signals();for(const e of(0,l.values)(this.args))e instanceof o.HasProps&&e.change.connect((()=>{this._result.clear(),this.change.emit()}))}get names(){return(0,l.keys)(this.args)}get values(){return(0,l.values)(this.args)}get func(){const e=(0,h.use_strict)(this.code);return new i.GeneratorFunction(...this.names,e)}_v_compute(e){const s=this.func.apply(e,this.values);let t=s.next();if(t.done&&void 0!==t.value){const{value:s}=t;return(0,g.isArray)(s)||(0,g.isTypedArray)(s)?s:(0,g.isIterable)(s)?[...s]:(0,u.repeat)(s,e.length)}{const e=[];do{e.push(t.value),t=s.next()}while(!t.done);return e}}}t.CustomJSExpr=p,a=p,p.__name__=\"CustomJSExpr\",a.define((({Unknown:e,String:s,Dict:t})=>({args:[t(e),{}],code:[s,\"\"]})))},\n", - " function _(t,n,e,o,r){var s;o();const a=t(254);class c extends a.Expression{constructor(t){super(t)}_v_compute(t){var n;const e=null!==(n=t.get_length())&&void 0!==n?n:0,o=new Float64Array(e);for(const n of this.fields){const r=t.data[n];if(null!=r){const t=Math.min(e,r.length);for(let n=0;n({fields:[n(t),[]]})))},\n", - " function _(e,n,t,o,r){var i;o();const l=e(254);class u extends l.Expression{constructor(e){super(e)}_v_compute(e){var n;const t=new Float64Array(null!==(n=e.get_length())&&void 0!==n?n:0),o=e.data[this.field],r=this.include_zero?1:0;t[0]=this.include_zero?0:o[0];for(let e=1;e({field:[n],include_zero:[e,!1]})))},\n", - " function _(i,n,l,t,e){var a;t();const u=i(254),r=i(9);class s extends u.ScalarExpression{constructor(i){super(i)}_compute(i){var n,l;const t=null!==(n=i.data[this.field])&&void 0!==n?n:[];return Math.min(null!==(l=this.initial)&&void 0!==l?l:1/0,(0,r.min)(t))}}l.Minimum=s,a=s,s.__name__=\"Minimum\",a.define((({Number:i,String:n,Nullable:l})=>({field:[n],initial:[l(i),null]})))},\n", - " function _(i,a,n,l,t){var e;l();const u=i(254),r=i(9);class s extends u.ScalarExpression{constructor(i){super(i)}_compute(i){var a,n;const l=null!==(a=i.data[this.field])&&void 0!==a?a:[];return Math.max(null!==(n=this.initial)&&void 0!==n?n:-1/0,(0,r.max)(l))}}n.Maximum=s,e=s,s.__name__=\"Maximum\",e.define((({Number:i,String:a,Nullable:n})=>({field:[a],initial:[n(i),null]})))},\n", - " function _(n,e,t,o,r){var s;o();const _=n(254);class m extends _.Expression{constructor(n){super(n)}get x(){return new c({transform:this})}get y(){return new u({transform:this})}}t.CoordinateTransform=m,m.__name__=\"CoordinateTransform\";class a extends _.Expression{constructor(n){super(n)}}t.XYComponent=a,s=a,a.__name__=\"XYComponent\",s.define((({Ref:n})=>({transform:[n(m)]})));class c extends a{constructor(n){super(n)}_v_compute(n){return this.transform.v_compute(n).x}}t.XComponent=c,c.__name__=\"XComponent\";class u extends a{constructor(n){super(n)}_v_compute(n){return this.transform.v_compute(n).y}}t.YComponent=u,u.__name__=\"YComponent\"},\n", - " function _(r,t,n,e,o){e();const i=r(1);var a;const s=r(260),c=r(20),l=(0,i.__importStar)(r(18));class d extends s.CoordinateTransform{constructor(r){super(r)}_v_compute(r){const t=this.properties.radius.uniform(r),n=this.properties.angle.uniform(r),e=\"anticlock\"==this.direction?-1:1,o=Math.min(t.length,n.length),i=new Float64Array(o),a=new Float64Array(o);for(let r=0;r({radius:[l.DistanceSpec,{field:\"radius\"}],angle:[l.AngleSpec,{field:\"angle\"}],direction:[c.Direction,\"anticlock\"]})))},\n", - " function _(e,t,l,r,i){r(),i(\"BooleanFilter\",e(263).BooleanFilter),i(\"CustomJSFilter\",e(264).CustomJSFilter),i(\"Filter\",e(191).Filter),i(\"GroupFilter\",e(265).GroupFilter),i(\"IndexFilter\",e(266).IndexFilter)},\n", - " function _(e,n,l,o,s){var t;o();const a=e(191),r=e(24);class c extends a.Filter{constructor(e){super(e)}compute_indices(e){const n=e.length,{booleans:l}=this;return null==l?r.Indices.all_set(n):r.Indices.from_booleans(n,l)}}l.BooleanFilter=c,t=c,c.__name__=\"BooleanFilter\",t.define((({Boolean:e,Array:n,Nullable:l})=>({booleans:[l(n(e)),null]})))},\n", - " function _(e,n,r,s,t){var i;s();const o=e(191),c=e(24),u=e(13),a=e(8),l=e(34);class f extends o.Filter{constructor(e){super(e)}get names(){return(0,u.keys)(this.args)}get values(){return(0,u.values)(this.args)}get func(){const e=(0,l.use_strict)(this.code);return new Function(...this.names,\"source\",e)}compute_indices(e){const n=e.length,r=this.func(...this.values,e);if(null==r)return c.Indices.all_set(n);if((0,a.isArrayOf)(r,a.isInteger))return c.Indices.from_indices(n,r);if((0,a.isArrayOf)(r,a.isBoolean))return c.Indices.from_booleans(n,r);throw new Error(`expect an array of integers or booleans, or null, got ${r}`)}}r.CustomJSFilter=f,i=f,f.__name__=\"CustomJSFilter\",i.define((({Unknown:e,String:n,Dict:r})=>({args:[r(e),{}],code:[n,\"\"]})))},\n", - " function _(n,e,t,o,r){var u;o();const s=n(191),c=n(24),i=n(19);class l extends s.Filter{constructor(n){super(n)}compute_indices(n){const e=n.get_column(this.column_name);if(null==e)return i.logger.warn(`${this}: groupby column '${this.column_name}' not found in the data source`),new c.Indices(n.length,1);{const t=new c.Indices(n.length);for(let n=0;n({column_name:[n],group:[n]})))},\n", - " function _(e,n,i,s,t){var l;s();const c=e(191),r=e(24);class d extends c.Filter{constructor(e){super(e)}compute_indices(e){const n=e.length,{indices:i}=this;return null==i?r.Indices.all_set(n):r.Indices.from_indices(n,i)}}i.IndexFilter=d,l=d,d.__name__=\"IndexFilter\",l.define((({Int:e,Array:n,Nullable:i})=>({indices:[i(n(e)),null]})))},\n", - " function _(e,a,l,i,t){i(),t(\"AnnularWedge\",e(268).AnnularWedge),t(\"Annulus\",e(269).Annulus),t(\"Arc\",e(270).Arc),t(\"Bezier\",e(271).Bezier),t(\"Circle\",e(272).Circle),t(\"Ellipse\",e(273).Ellipse),t(\"EllipseOval\",e(274).EllipseOval),t(\"Glyph\",e(179).Glyph),t(\"HArea\",e(187).HArea),t(\"HBar\",e(276).HBar),t(\"HexTile\",e(278).HexTile),t(\"Image\",e(279).Image),t(\"ImageRGBA\",e(281).ImageRGBA),t(\"ImageURL\",e(282).ImageURL),t(\"Line\",e(177).Line),t(\"MultiLine\",e(283).MultiLine),t(\"MultiPolygons\",e(284).MultiPolygons),t(\"Oval\",e(285).Oval),t(\"Patch\",e(186).Patch),t(\"Patches\",e(286).Patches),t(\"Quad\",e(287).Quad),t(\"Quadratic\",e(288).Quadratic),t(\"Ray\",e(289).Ray),t(\"Rect\",e(290).Rect),t(\"Scatter\",e(291).Scatter),t(\"Segment\",e(294).Segment),t(\"Spline\",e(295).Spline),t(\"Step\",e(297).Step),t(\"Text\",e(298).Text),t(\"VArea\",e(189).VArea),t(\"VBar\",e(299).VBar),t(\"Wedge\",e(300).Wedge)},\n", - " function _(e,s,t,i,r){i();const n=e(1);var a;const _=e(178),o=e(184),d=e(48),u=e(24),h=e(20),c=(0,n.__importStar)(e(18)),l=e(10),g=e(72),p=e(12);class x extends _.XYGlyphView{_map_data(){\"data\"==this.model.properties.inner_radius.units?this.sinner_radius=this.sdist(this.renderer.xscale,this._x,this.inner_radius):this.sinner_radius=(0,u.to_screen)(this.inner_radius),\"data\"==this.model.properties.outer_radius.units?this.souter_radius=this.sdist(this.renderer.xscale,this._x,this.outer_radius):this.souter_radius=(0,u.to_screen)(this.outer_radius),this.max_souter_radius=(0,p.max)(this.souter_radius)}_render(e,s,t){const{sx:i,sy:r,start_angle:n,end_angle:a,sinner_radius:_,souter_radius:o}=null!=t?t:this,d=\"anticlock\"==this.model.direction;for(const t of s){const s=i[t],u=r[t],h=_[t],c=o[t],l=n.get(t),g=a.get(t);if(!isFinite(s+u+h+c+l+g))continue;const p=g-l;e.translate(s,u),e.rotate(l),e.beginPath(),e.moveTo(c,0),e.arc(0,0,c,0,p,d),e.rotate(p),e.lineTo(h,0),e.arc(0,0,h,0,-p,!d),e.closePath(),e.rotate(-p-l),e.translate(-s,-u),this.visuals.fill.apply(e,t),this.visuals.hatch.apply(e,t),this.visuals.line.apply(e,t)}}_hit_point(e){const{sx:s,sy:t}=e,i=this.renderer.xscale.invert(s),r=this.renderer.yscale.invert(t),n=s-this.max_souter_radius,a=s+this.max_souter_radius,[_,o]=this.renderer.xscale.r_invert(n,a),d=t-this.max_souter_radius,u=t+this.max_souter_radius,[h,c]=this.renderer.yscale.r_invert(d,u),p=[];for(const e of this.index.indices({x0:_,x1:o,y0:h,y1:c})){const s=this.souter_radius[e]**2,t=this.sinner_radius[e]**2,[n,a]=this.renderer.xscale.r_compute(i,this._x[e]),[_,o]=this.renderer.yscale.r_compute(r,this._y[e]),d=(n-a)**2+(_-o)**2;d<=s&&d>=t&&p.push(e)}const x=\"anticlock\"==this.model.direction,m=[];for(const e of p){const i=Math.atan2(t-this.sy[e],s-this.sx[e]);(0,l.angle_between)(-i,-this.start_angle.get(e),-this.end_angle.get(e),x)&&m.push(e)}return new g.Selection({indices:m})}draw_legend_for_index(e,s,t){(0,o.generic_area_vector_legend)(this.visuals,e,s,t)}scenterxy(e){const s=(this.sinner_radius[e]+this.souter_radius[e])/2,t=(this.start_angle.get(e)+this.end_angle.get(e))/2;return[this.sx[e]+s*Math.cos(t),this.sy[e]+s*Math.sin(t)]}}t.AnnularWedgeView=x,x.__name__=\"AnnularWedgeView\";class m extends _.XYGlyph{constructor(e){super(e)}}t.AnnularWedge=m,a=m,m.__name__=\"AnnularWedge\",a.prototype.default_view=x,a.mixins([d.LineVector,d.FillVector,d.HatchVector]),a.define((({})=>({direction:[h.Direction,\"anticlock\"],inner_radius:[c.DistanceSpec,{field:\"inner_radius\"}],outer_radius:[c.DistanceSpec,{field:\"outer_radius\"}],start_angle:[c.AngleSpec,{field:\"start_angle\"}],end_angle:[c.AngleSpec,{field:\"end_angle\"}]})))},\n", - " function _(s,e,i,r,t){r();const n=s(1);var a;const u=s(178),o=s(24),_=s(48),d=(0,n.__importStar)(s(18)),h=s(27),c=s(72);class l extends u.XYGlyphView{_map_data(){\"data\"==this.model.properties.inner_radius.units?this.sinner_radius=this.sdist(this.renderer.xscale,this._x,this.inner_radius):this.sinner_radius=(0,o.to_screen)(this.inner_radius),\"data\"==this.model.properties.outer_radius.units?this.souter_radius=this.sdist(this.renderer.xscale,this._x,this.outer_radius):this.souter_radius=(0,o.to_screen)(this.outer_radius)}_render(s,e,i){const{sx:r,sy:t,sinner_radius:n,souter_radius:a}=null!=i?i:this;for(const i of e){const e=r[i],u=t[i],o=n[i],_=a[i];if(isFinite(e+u+o+_)){if(s.beginPath(),h.is_ie)for(const i of[!1,!0])s.moveTo(e,u),s.arc(e,u,o,0,Math.PI,i),s.moveTo(e+_,u),s.arc(e,u,_,Math.PI,0,!i);else s.arc(e,u,o,0,2*Math.PI,!0),s.moveTo(e+_,u),s.arc(e,u,_,2*Math.PI,0,!1);this.visuals.fill.apply(s,i),this.visuals.hatch.apply(s,i),this.visuals.line.apply(s,i)}}}_hit_point(s){const{sx:e,sy:i}=s,r=this.renderer.xscale.invert(e),t=this.renderer.yscale.invert(i);let n,a,u,o;if(\"data\"==this.model.properties.outer_radius.units)n=r-this.max_outer_radius,u=r+this.max_outer_radius,a=t-this.max_outer_radius,o=t+this.max_outer_radius;else{const s=e-this.max_outer_radius,r=e+this.max_outer_radius;[n,u]=this.renderer.xscale.r_invert(s,r);const t=i-this.max_outer_radius,_=i+this.max_outer_radius;[a,o]=this.renderer.yscale.r_invert(t,_)}const _=[];for(const s of this.index.indices({x0:n,x1:u,y0:a,y1:o})){const e=this.souter_radius[s]**2,i=this.sinner_radius[s]**2,[n,a]=this.renderer.xscale.r_compute(r,this._x[s]),[u,o]=this.renderer.yscale.r_compute(t,this._y[s]),d=(n-a)**2+(u-o)**2;d<=e&&d>=i&&_.push(s)}return new c.Selection({indices:_})}draw_legend_for_index(s,{x0:e,y0:i,x1:r,y1:t},n){const a=n+1,u=new Array(a);u[n]=(e+r)/2;const o=new Array(a);o[n]=(i+t)/2;const _=.5*Math.min(Math.abs(r-e),Math.abs(t-i)),d=new Array(a);d[n]=.4*_;const h=new Array(a);h[n]=.8*_,this._render(s,[n],{sx:u,sy:o,sinner_radius:d,souter_radius:h})}}i.AnnulusView=l,l.__name__=\"AnnulusView\";class x extends u.XYGlyph{constructor(s){super(s)}}i.Annulus=x,a=x,x.__name__=\"Annulus\",a.prototype.default_view=l,a.mixins([_.LineVector,_.FillVector,_.HatchVector]),a.define((({})=>({inner_radius:[d.DistanceSpec,{field:\"inner_radius\"}],outer_radius:[d.DistanceSpec,{field:\"outer_radius\"}]})))},\n", - " function _(e,i,s,t,n){t();const r=e(1);var a;const c=e(178),d=e(184),l=e(48),_=e(24),o=e(20),u=(0,r.__importStar)(e(18));class h extends c.XYGlyphView{_map_data(){\"data\"==this.model.properties.radius.units?this.sradius=this.sdist(this.renderer.xscale,this._x,this.radius):this.sradius=(0,_.to_screen)(this.radius)}_render(e,i,s){if(this.visuals.line.doit){const{sx:t,sy:n,sradius:r,start_angle:a,end_angle:c}=null!=s?s:this,d=\"anticlock\"==this.model.direction;for(const s of i){const i=t[s],l=n[s],_=r[s],o=a.get(s),u=c.get(s);isFinite(i+l+_+o+u)&&(e.beginPath(),e.arc(i,l,_,o,u,d),this.visuals.line.set_vectorize(e,s),e.stroke())}}}draw_legend_for_index(e,i,s){(0,d.generic_line_vector_legend)(this.visuals,e,i,s)}}s.ArcView=h,h.__name__=\"ArcView\";class g extends c.XYGlyph{constructor(e){super(e)}}s.Arc=g,a=g,g.__name__=\"Arc\",a.prototype.default_view=h,a.mixins(l.LineVector),a.define((({})=>({direction:[o.Direction,\"anticlock\"],radius:[u.DistanceSpec,{field:\"radius\"}],start_angle:[u.AngleSpec,{field:\"start_angle\"}],end_angle:[u.AngleSpec,{field:\"end_angle\"}]})))},\n", - " function _(e,t,i,n,s){n();const o=e(1);var c;const r=e(48),a=e(179),_=e(184),d=e(78),l=(0,o.__importStar)(e(18));function x(e,t,i,n,s,o,c,r){const a=[],_=[[],[]];for(let _=0;_<=2;_++){let d,l,x;if(0===_?(l=6*e-12*i+6*s,d=-3*e+9*i-9*s+3*c,x=3*i-3*e):(l=6*t-12*n+6*o,d=-3*t+9*n-9*o+3*r,x=3*n-3*t),Math.abs(d)<1e-12){if(Math.abs(l)<1e-12)continue;const e=-x/l;0({x0:[l.XCoordinateSpec,{field:\"x0\"}],y0:[l.YCoordinateSpec,{field:\"y0\"}],x1:[l.XCoordinateSpec,{field:\"x1\"}],y1:[l.YCoordinateSpec,{field:\"y1\"}],cx0:[l.XCoordinateSpec,{field:\"cx0\"}],cy0:[l.YCoordinateSpec,{field:\"cy0\"}],cx1:[l.XCoordinateSpec,{field:\"cx1\"}],cy1:[l.YCoordinateSpec,{field:\"cy1\"}]}))),c.mixins(r.LineVector)},\n", - " function _(s,i,e,t,r){t();const a=s(1);var n;const h=s(178),d=s(48),l=s(24),_=s(20),c=(0,a.__importStar)(s(185)),u=(0,a.__importStar)(s(18)),o=s(9),x=s(12),m=s(72);class p extends h.XYGlyphView{async lazy_initialize(){await super.lazy_initialize();const{webgl:i}=this.renderer.plot_view.canvas_view;if(null!=i&&i.regl_wrapper.has_webgl){const{CircleGL:e}=await Promise.resolve().then((()=>(0,a.__importStar)(s(423))));this.glglyph=new e(i.regl_wrapper,this)}}get use_radius(){return!(this.radius.is_Scalar()&&isNaN(this.radius.value))}_set_data(s){super._set_data(s);const i=(()=>{if(this.use_radius)return 2*this.max_radius;{const{size:s}=this;return s.is_Scalar()?s.value:(0,x.max)(s.array)}})();this._configure(\"max_size\",{value:i})}_map_data(){if(this.use_radius)if(\"data\"==this.model.properties.radius.units)switch(this.model.radius_dimension){case\"x\":this.sradius=this.sdist(this.renderer.xscale,this._x,this.radius);break;case\"y\":this.sradius=this.sdist(this.renderer.yscale,this._y,this.radius);break;case\"max\":{const s=this.sdist(this.renderer.xscale,this._x,this.radius),i=this.sdist(this.renderer.yscale,this._y,this.radius);this.sradius=(0,x.map)(s,((s,e)=>Math.max(s,i[e])));break}case\"min\":{const s=this.sdist(this.renderer.xscale,this._x,this.radius),i=this.sdist(this.renderer.yscale,this._y,this.radius);this.sradius=(0,x.map)(s,((s,e)=>Math.min(s,i[e])));break}}else this.sradius=(0,l.to_screen)(this.radius);else{const s=l.ScreenArray.from(this.size);this.sradius=(0,x.map)(s,(s=>s/2))}}_mask_data(){const{frame:s}=this.renderer.plot_view,i=s.x_target,e=s.y_target;let t,r;return this.use_radius&&\"data\"==this.model.properties.radius.units?(t=i.map((s=>this.renderer.xscale.invert(s))).widen(this.max_radius),r=e.map((s=>this.renderer.yscale.invert(s))).widen(this.max_radius)):(t=i.widen(this.max_size).map((s=>this.renderer.xscale.invert(s))),r=e.widen(this.max_size).map((s=>this.renderer.yscale.invert(s)))),this.index.indices({x0:t.start,x1:t.end,y0:r.start,y1:r.end})}_render(s,i,e){const{sx:t,sy:r,sradius:a}=null!=e?e:this;for(const e of i){const i=t[e],n=r[e],h=a[e];isFinite(i+n+h)&&(s.beginPath(),s.arc(i,n,h,0,2*Math.PI,!1),this.visuals.fill.apply(s,e),this.visuals.hatch.apply(s,e),this.visuals.line.apply(s,e))}}_hit_point(s){const{sx:i,sy:e}=s,t=this.renderer.xscale.invert(i),r=this.renderer.yscale.invert(e),{hit_dilation:a}=this.model;let n,h,d,l;if(this.use_radius&&\"data\"==this.model.properties.radius.units)n=t-this.max_radius*a,h=t+this.max_radius*a,d=r-this.max_radius*a,l=r+this.max_radius*a;else{const s=i-this.max_size*a,t=i+this.max_size*a;[n,h]=this.renderer.xscale.r_invert(s,t);const r=e-this.max_size*a,_=e+this.max_size*a;[d,l]=this.renderer.yscale.r_invert(r,_)}const _=this.index.indices({x0:n,x1:h,y0:d,y1:l}),c=[];if(this.use_radius&&\"data\"==this.model.properties.radius.units)for(const s of _){const i=(this.sradius[s]*a)**2,[e,n]=this.renderer.xscale.r_compute(t,this._x[s]),[h,d]=this.renderer.yscale.r_compute(r,this._y[s]);(e-n)**2+(h-d)**2<=i&&c.push(s)}else for(const s of _){const t=(this.sradius[s]*a)**2;(this.sx[s]-i)**2+(this.sy[s]-e)**2<=t&&c.push(s)}return new m.Selection({indices:c})}_hit_span(s){const{sx:i,sy:e}=s,t=this.bounds();let r,a,n,h;if(\"h\"==s.direction){let s,e;if(n=t.y0,h=t.y1,this.use_radius&&\"data\"==this.model.properties.radius.units)s=i-this.max_radius,e=i+this.max_radius,[r,a]=this.renderer.xscale.r_invert(s,e);else{const t=this.max_size/2;s=i-t,e=i+t,[r,a]=this.renderer.xscale.r_invert(s,e)}}else{let s,i;if(r=t.x0,a=t.x1,this.use_radius&&\"data\"==this.model.properties.radius.units)s=e-this.max_radius,i=e+this.max_radius,[n,h]=this.renderer.yscale.r_invert(s,i);else{const t=this.max_size/2;s=e-t,i=e+t,[n,h]=this.renderer.yscale.r_invert(s,i)}}const d=[...this.index.indices({x0:r,x1:a,y0:n,y1:h})];return new m.Selection({indices:d})}_hit_rect(s){const{sx0:i,sx1:e,sy0:t,sy1:r}=s,[a,n]=this.renderer.xscale.r_invert(i,e),[h,d]=this.renderer.yscale.r_invert(t,r),l=[...this.index.indices({x0:a,x1:n,y0:h,y1:d})];return new m.Selection({indices:l})}_hit_poly(s){const{sx:i,sy:e}=s,t=(0,o.range)(0,this.sx.length),r=[];for(let s=0,a=t.length;s({angle:[u.AngleSpec,0],size:[u.ScreenSizeSpec,{value:4}],radius:[u.NullDistanceSpec,null],radius_dimension:[_.RadiusDimension,\"x\"],hit_dilation:[s,1]})))},\n", - " function _(e,l,s,i,_){var p;i();const t=e(274);class a extends t.EllipseOvalView{}s.EllipseView=a,a.__name__=\"EllipseView\";class n extends t.EllipseOval{constructor(e){super(e)}}s.Ellipse=n,p=n,n.__name__=\"Ellipse\",p.prototype.default_view=a},\n", - " function _(t,s,e,i,h){i();const n=t(1),r=t(275),a=(0,n.__importStar)(t(185)),l=t(24),_=t(72),o=(0,n.__importStar)(t(18));class d extends r.CenterRotatableView{_map_data(){\"data\"==this.model.properties.width.units?this.sw=this.sdist(this.renderer.xscale,this._x,this.width,\"center\"):this.sw=(0,l.to_screen)(this.width),\"data\"==this.model.properties.height.units?this.sh=this.sdist(this.renderer.yscale,this._y,this.height,\"center\"):this.sh=(0,l.to_screen)(this.height)}_render(t,s,e){const{sx:i,sy:h,sw:n,sh:r,angle:a}=null!=e?e:this;for(const e of s){const s=i[e],l=h[e],_=n[e],o=r[e],d=a.get(e);isFinite(s+l+_+o+d)&&(t.beginPath(),t.ellipse(s,l,_/2,o/2,d,0,2*Math.PI),this.visuals.fill.apply(t,e),this.visuals.hatch.apply(t,e),this.visuals.line.apply(t,e))}}_hit_point(t){let s,e,i,h,n,r,l,o,d;const{sx:c,sy:p}=t,w=this.renderer.xscale.invert(c),x=this.renderer.yscale.invert(p);\"data\"==this.model.properties.width.units?(s=w-this.max_width,e=w+this.max_width):(r=c-this.max_width,l=c+this.max_width,[s,e]=this.renderer.xscale.r_invert(r,l)),\"data\"==this.model.properties.height.units?(i=x-this.max_height,h=x+this.max_height):(o=p-this.max_height,d=p+this.max_height,[i,h]=this.renderer.yscale.r_invert(o,d));const m=this.index.indices({x0:s,x1:e,y0:i,y1:h}),y=[];for(const t of m)n=a.point_in_ellipse(c,p,this.angle.get(t),this.sh[t]/2,this.sw[t]/2,this.sx[t],this.sy[t]),n&&y.push(t);return new _.Selection({indices:y})}draw_legend_for_index(t,{x0:s,y0:e,x1:i,y1:h},n){const r=n+1,a=new Array(r);a[n]=(s+i)/2;const l=new Array(r);l[n]=(e+h)/2;const _=this.sw[n]/this.sh[n],d=.8*Math.min(Math.abs(i-s),Math.abs(h-e)),c=new Array(r),p=new Array(r);_>1?(c[n]=d,p[n]=d/_):(c[n]=d*_,p[n]=d);const w=new o.UniformScalar(0,r);this._render(t,[n],{sx:a,sy:l,sw:c,sh:p,angle:w})}}e.EllipseOvalView=d,d.__name__=\"EllipseOvalView\";class c extends r.CenterRotatable{constructor(t){super(t)}}e.EllipseOval=c,c.__name__=\"EllipseOval\"},\n", - " function _(e,t,i,a,n){a();const s=e(1);var r;const h=e(178),o=e(48),_=(0,s.__importStar)(e(18));class c extends h.XYGlyphView{get max_w2(){return\"data\"==this.model.properties.width.units?this.max_width/2:0}get max_h2(){return\"data\"==this.model.properties.height.units?this.max_height/2:0}_bounds({x0:e,x1:t,y0:i,y1:a}){const{max_w2:n,max_h2:s}=this;return{x0:e-n,x1:t+n,y0:i-s,y1:a+s}}}i.CenterRotatableView=c,c.__name__=\"CenterRotatableView\";class l extends h.XYGlyph{constructor(e){super(e)}}i.CenterRotatable=l,r=l,l.__name__=\"CenterRotatable\",r.mixins([o.LineVector,o.FillVector,o.HatchVector]),r.define((({})=>({angle:[_.AngleSpec,0],width:[_.DistanceSpec,{field:\"width\"}],height:[_.DistanceSpec,{field:\"height\"}]})))},\n", - " function _(t,e,s,i,r){i();const h=t(1);var a;const n=t(277),_=t(24),o=(0,h.__importStar)(t(18));class l extends n.BoxView{async lazy_initialize(){await super.lazy_initialize();const{webgl:e}=this.renderer.plot_view.canvas_view;if(null!=e&&e.regl_wrapper.has_webgl){const{LRTBGL:s}=await Promise.resolve().then((()=>(0,h.__importStar)(t(427))));this.glglyph=new s(e.regl_wrapper,this)}}scenterxy(t){return[(this.sleft[t]+this.sright[t])/2,this.sy[t]]}_lrtb(t){const e=this._left[t],s=this._right[t],i=this._y[t],r=this.height.get(t)/2;return[Math.min(e,s),Math.max(e,s),i+r,i-r]}_map_data(){this.sy=this.renderer.yscale.v_compute(this._y),this.sh=this.sdist(this.renderer.yscale,this._y,this.height,\"center\"),this.sleft=this.renderer.xscale.v_compute(this._left),this.sright=this.renderer.xscale.v_compute(this._right);const t=this.sy.length;this.stop=new _.ScreenArray(t),this.sbottom=new _.ScreenArray(t);for(let e=0;e({left:[o.XCoordinateSpec,{value:0}],y:[o.YCoordinateSpec,{field:\"y\"}],height:[o.NumberSpec,{value:1}],right:[o.XCoordinateSpec,{field:\"right\"}]})))},\n", - " function _(t,e,s,r,i){var n;r();const a=t(48),h=t(179),o=t(184),c=t(72);class _ extends h.GlyphView{get_anchor_point(t,e,s){const r=Math.min(this.sleft[e],this.sright[e]),i=Math.max(this.sright[e],this.sleft[e]),n=Math.min(this.stop[e],this.sbottom[e]),a=Math.max(this.sbottom[e],this.stop[e]);switch(t){case\"top_left\":return{x:r,y:n};case\"top\":case\"top_center\":return{x:(r+i)/2,y:n};case\"top_right\":return{x:i,y:n};case\"bottom_left\":return{x:r,y:a};case\"bottom\":case\"bottom_center\":return{x:(r+i)/2,y:a};case\"bottom_right\":return{x:i,y:a};case\"left\":case\"center_left\":return{x:r,y:(n+a)/2};case\"center\":case\"center_center\":return{x:(r+i)/2,y:(n+a)/2};case\"right\":case\"center_right\":return{x:i,y:(n+a)/2}}}_index_data(t){const{min:e,max:s}=Math,{data_size:r}=this;for(let i=0;i(0,n.__importStar)(e(425))));this.glglyph=new s(t.regl_wrapper,this)}}scenterxy(e){return[this.sx[e],this.sy[e]]}_set_data(){const{orientation:e,size:t,aspect_scale:s}=this.model,{q:i,r}=this,n=this.q.length;this._x=new Float64Array(n),this._y=new Float64Array(n);const{_x:a,_y:l}=this,o=Math.sqrt(3);if(\"pointytop\"==e)for(let e=0;e({r:[c.NumberSpec,{field:\"r\"}],q:[c.NumberSpec,{field:\"q\"}],scale:[c.NumberSpec,1],size:[e,1],aspect_scale:[e,1],orientation:[_.HexTileOrientation,\"pointytop\"]}))),a.override({line_color:null})},\n", - " function _(e,a,t,_,r){var n;_();const s=e(280),o=e(173),i=e(201);class p extends s.ImageBaseView{connect_signals(){super.connect_signals(),this.connect(this.model.color_mapper.change,(()=>this._update_image()))}_update_image(){null!=this.image_data&&(this._set_data(null),this.renderer.request_render())}_flat_img_to_buf8(e){return this.model.color_mapper.rgba_mapper.v_compute(e)}}t.ImageView=p,p.__name__=\"ImageView\";class m extends s.ImageBase{constructor(e){super(e)}}t.Image=m,n=m,m.__name__=\"Image\",n.prototype.default_view=p,n.define((({Ref:e})=>({color_mapper:[e(o.ColorMapper),()=>new i.LinearColorMapper({palette:[\"#000000\",\"#252525\",\"#525252\",\"#737373\",\"#969696\",\"#bdbdbd\",\"#d9d9d9\",\"#f0f0f0\",\"#ffffff\"]})]})))},\n", - " function _(e,t,i,s,a){s();const h=e(1);var n;const r=e(178),_=e(24),d=(0,h.__importStar)(e(18)),l=e(72),g=e(9),o=e(29),c=e(11);class m extends r.XYGlyphView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.global_alpha.change,(()=>this.renderer.request_render()))}_render(e,t,i){const{image_data:s,sx:a,sy:h,sw:n,sh:r,global_alpha:_}=null!=i?i:this,d=e.getImageSmoothingEnabled();e.setImageSmoothingEnabled(!1);const l=_.is_Scalar();l&&(e.globalAlpha=_.value);for(const i of t){const t=s[i],_=a[i],d=h[i],g=n[i],o=r[i],c=this.global_alpha.get(i);if(null==t||!isFinite(_+d+g+o+c))continue;l||(e.globalAlpha=c);const m=d;e.translate(0,m),e.scale(1,-1),e.translate(0,-m),e.drawImage(t,0|_,0|d,g,o),e.translate(0,m),e.scale(1,-1),e.translate(0,-m)}e.setImageSmoothingEnabled(d)}_set_data(e){this._set_width_heigh_data();for(let t=0,i=this.image.length;t({image:[d.NDArraySpec,{field:\"image\"}],dw:[d.DistanceSpec,{field:\"dw\"}],dh:[d.DistanceSpec,{field:\"dh\"}],global_alpha:[d.NumberSpec,{value:1}],dilate:[e,!1]})))},\n", - " function _(e,a,t,r,_){var n;r();const s=e(280),m=e(8);class i extends s.ImageBaseView{_flat_img_to_buf8(e){let a;return a=(0,m.isArray)(e)?new Uint32Array(e):e,new Uint8ClampedArray(a.buffer)}}t.ImageRGBAView=i,i.__name__=\"ImageRGBAView\";class g extends s.ImageBase{constructor(e){super(e)}}t.ImageRGBA=g,n=g,g.__name__=\"ImageRGBA\",n.prototype.default_view=i},\n", - " function _(e,t,s,r,a){r();const i=e(1);var n;const o=e(178),c=e(24),_=e(20),h=(0,i.__importStar)(e(18)),l=e(12),d=e(136);class m extends o.XYGlyphView{constructor(){super(...arguments),this._images_rendered=!1,this._set_data_iteration=0}connect_signals(){super.connect_signals(),this.connect(this.model.properties.global_alpha.change,(()=>this.renderer.request_render()))}_index_data(e){const{data_size:t}=this;for(let s=0;s{this._set_data_iteration==r&&(this.image[a]=e,this.renderer.request_render())},attempts:t+1,timeout:s})}const a=\"data\"==this.model.properties.w.units,i=\"data\"==this.model.properties.h.units,n=this._x.length,o=new c.ScreenArray(a?2*n:n),_=new c.ScreenArray(i?2*n:n),{anchor:h}=this.model;function m(e,t){switch(h){case\"top_left\":case\"bottom_left\":case\"left\":case\"center_left\":return[e,e+t];case\"top\":case\"top_center\":case\"bottom\":case\"bottom_center\":case\"center\":case\"center_center\":return[e-t/2,e+t/2];case\"top_right\":case\"bottom_right\":case\"right\":case\"center_right\":return[e-t,e]}}function g(e,t){switch(h){case\"top_left\":case\"top\":case\"top_center\":case\"top_right\":return[e,e-t];case\"bottom_left\":case\"bottom\":case\"bottom_center\":case\"bottom_right\":return[e+t,e];case\"left\":case\"center_left\":case\"center\":case\"center_center\":case\"right\":case\"center_right\":return[e+t/2,e-t/2]}}if(a)for(let e=0;e({url:[h.StringSpec,{field:\"url\"}],anchor:[_.Anchor,\"top_left\"],global_alpha:[h.NumberSpec,{value:1}],angle:[h.AngleSpec,0],w:[h.NullDistanceSpec,null],h:[h.NullDistanceSpec,null],dilate:[e,!1],retry_attempts:[t,0],retry_timeout:[t,0]})))},\n", - " function _(e,t,s,i,n){i();const o=e(1);var r;const l=e(78),_=e(48),c=(0,o.__importStar)(e(185)),h=(0,o.__importStar)(e(18)),a=e(12),d=e(13),x=e(179),y=e(184),g=e(72);class p extends x.GlyphView{_project_data(){l.inplace.project_xy(this._xs.array,this._ys.array)}_index_data(e){const{data_size:t}=this;for(let s=0;s0&&o.set(e,s)}return new g.Selection({indices:[...o.keys()],multiline_indices:(0,d.to_object)(o)})}get_interpolation_hit(e,t,s){const i=this._xs.get(e),n=this._ys.get(e),o=i[t],r=n[t],l=i[t+1],_=n[t+1];return(0,y.line_interpolation)(this.renderer,s,o,r,l,_)}draw_legend_for_index(e,t,s){(0,y.generic_line_vector_legend)(this.visuals,e,t,s)}scenterxy(){throw new Error(`${this}.scenterxy() is not implemented`)}}s.MultiLineView=p,p.__name__=\"MultiLineView\";class u extends x.Glyph{constructor(e){super(e)}}s.MultiLine=u,r=u,u.__name__=\"MultiLine\",r.prototype.default_view=p,r.define((({})=>({xs:[h.XCoordinateSeqSpec,{field:\"xs\"}],ys:[h.YCoordinateSeqSpec,{field:\"ys\"}]}))),r.mixins(_.LineVector)},\n", - " function _(t,e,s,n,i){n();const o=t(1);var r;const l=t(181),h=t(179),a=t(184),_=t(12),c=t(12),d=t(48),x=(0,o.__importStar)(t(185)),y=(0,o.__importStar)(t(18)),f=t(72),g=t(11);class p extends h.GlyphView{_project_data(){}_index_data(t){const{min:e,max:s}=Math,{data_size:n}=this;for(let i=0;i1&&c.length>1)for(let s=1,n=i.length;s1){let r=!1;for(let t=1;t({xs:[y.XCoordinateSeqSeqSeqSpec,{field:\"xs\"}],ys:[y.YCoordinateSeqSeqSeqSpec,{field:\"ys\"}]}))),r.mixins([d.LineVector,d.FillVector,d.HatchVector])},\n", - " function _(a,e,l,s,_){var t;s();const i=a(274),n=a(12);class p extends i.EllipseOvalView{_map_data(){super._map_data(),(0,n.mul)(this.sw,.75)}}l.OvalView=p,p.__name__=\"OvalView\";class v extends i.EllipseOval{constructor(a){super(a)}}l.Oval=v,t=v,v.__name__=\"Oval\",t.prototype.default_view=p},\n", - " function _(e,t,s,i,n){i();const r=e(1);var a;const o=e(179),c=e(184),_=e(12),h=e(48),l=(0,r.__importStar)(e(185)),d=(0,r.__importStar)(e(18)),y=e(72),p=e(11),x=e(78);class f extends o.GlyphView{_project_data(){x.inplace.project_xy(this._xs.array,this._ys.array)}_index_data(e){const{data_size:t}=this;for(let s=0;s({xs:[d.XCoordinateSeqSpec,{field:\"xs\"}],ys:[d.YCoordinateSeqSpec,{field:\"ys\"}]}))),a.mixins([h.LineVector,h.FillVector,h.HatchVector])},\n", - " function _(t,e,i,o,r){o();const s=t(1);var a;const n=t(277),l=(0,s.__importStar)(t(18));class _ extends n.BoxView{async lazy_initialize(){await super.lazy_initialize();const{webgl:e}=this.renderer.plot_view.canvas_view;if(null!=e&&e.regl_wrapper.has_webgl){const{LRTBGL:i}=await Promise.resolve().then((()=>(0,s.__importStar)(t(427))));this.glglyph=new i(e.regl_wrapper,this)}}scenterxy(t){return[this.sleft[t]/2+this.sright[t]/2,this.stop[t]/2+this.sbottom[t]/2]}_lrtb(t){return[this._left[t],this._right[t],this._top[t],this._bottom[t]]}}i.QuadView=_,_.__name__=\"QuadView\";class p extends n.Box{constructor(t){super(t)}}i.Quad=p,a=p,p.__name__=\"Quad\",a.prototype.default_view=_,a.define((({})=>({right:[l.XCoordinateSpec,{field:\"right\"}],bottom:[l.YCoordinateSpec,{field:\"bottom\"}],left:[l.XCoordinateSpec,{field:\"left\"}],top:[l.YCoordinateSpec,{field:\"top\"}]})))},\n", - " function _(e,t,i,n,s){n();const c=e(1);var o;const r=e(48),a=e(78),_=e(179),d=e(184),l=(0,c.__importStar)(e(18));function x(e,t,i){if(t==(e+i)/2)return[e,i];{const n=(e-t)/(e-2*t+i),s=e*(1-n)**2+2*t*(1-n)*n+i*n**2;return[Math.min(e,i,s),Math.max(e,i,s)]}}class y extends _.GlyphView{_project_data(){a.inplace.project_xy(this._x0,this._y0),a.inplace.project_xy(this._x1,this._y1)}_index_data(e){const{_x0:t,_x1:i,_y0:n,_y1:s,_cx:c,_cy:o,data_size:r}=this;for(let a=0;a({x0:[l.XCoordinateSpec,{field:\"x0\"}],y0:[l.YCoordinateSpec,{field:\"y0\"}],x1:[l.XCoordinateSpec,{field:\"x1\"}],y1:[l.YCoordinateSpec,{field:\"y1\"}],cx:[l.XCoordinateSpec,{field:\"cx\"}],cy:[l.YCoordinateSpec,{field:\"cy\"}]}))),o.mixins(r.LineVector)},\n", - " function _(e,t,s,i,n){i();const l=e(1);var a;const r=e(178),o=e(184),h=e(48),_=e(24),c=(0,l.__importStar)(e(18));class g extends r.XYGlyphView{_map_data(){\"data\"==this.model.properties.length.units?this.slength=this.sdist(this.renderer.xscale,this._x,this.length):this.slength=(0,_.to_screen)(this.length);const{width:e,height:t}=this.renderer.plot_view.frame.bbox,s=2*(e+t),{slength:i}=this;for(let e=0,t=i.length;e({length:[c.DistanceSpec,0],angle:[c.AngleSpec,0]})))},\n", - " function _(t,e,s,i,r){var n,h=this&&this.__createBinding||(Object.create?function(t,e,s,i){void 0===i&&(i=s),Object.defineProperty(t,i,{enumerable:!0,get:function(){return e[s]}})}:function(t,e,s,i){void 0===i&&(i=s),t[i]=e[s]}),a=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,\"default\",{enumerable:!0,value:e})}:function(t,e){t.default=e}),l=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var s in t)\"default\"!==s&&Object.prototype.hasOwnProperty.call(t,s)&&h(e,t,s);return a(e,t),e};i();const o=t(275),c=t(184),_=t(24),d=t(12),f=t(72);class y extends o.CenterRotatableView{async lazy_initialize(){await super.lazy_initialize();const{webgl:e}=this.renderer.plot_view.canvas_view;if(null==e?void 0:e.regl_wrapper.has_webgl){const{RectGL:s}=await Promise.resolve().then((()=>l(t(429))));this.glglyph=new s(e.regl_wrapper,this)}}_map_data(){if(\"data\"==this.model.properties.width.units)[this.sw,this.sx0]=this._map_dist_corner_for_data_side_length(this._x,this.width,this.renderer.xscale);else{this.sw=(0,_.to_screen)(this.width);const t=this.sx.length;this.sx0=new _.ScreenArray(t);for(let e=0;e({dilate:[t,!1]})))},\n", - " function _(e,t,r,a,s){a();const i=e(1);var n;const l=e(292),_=e(293),c=(0,i.__importStar)(e(18));class o extends l.MarkerView{async lazy_initialize(){await super.lazy_initialize();const{webgl:t}=this.renderer.plot_view.canvas_view;if(null!=t&&t.regl_wrapper.has_webgl){const{MultiMarkerGL:r}=await Promise.resolve().then((()=>(0,i.__importStar)(e(428))));this.glglyph=new r(t.regl_wrapper,this)}}_render(e,t,r){const{sx:a,sy:s,size:i,angle:n,marker:l}=null!=r?r:this;for(const r of t){const t=a[r],c=s[r],o=i.get(r),g=n.get(r),w=l.get(r);if(!isFinite(t+c+o+g)||null==w)continue;const p=o/2;e.beginPath(),e.translate(t,c),g&&e.rotate(g),_.marker_funcs[w](e,r,p,this.visuals),g&&e.rotate(-g),e.translate(-t,-c)}}draw_legend_for_index(e,{x0:t,x1:r,y0:a,y1:s},i){const n=i+1,l=this.marker.get(i),_=Object.assign(Object.assign({},this._get_legend_args({x0:t,x1:r,y0:a,y1:s},i)),{marker:new c.UniformScalar(l,n)});this._render(e,[i],_)}}r.ScatterView=o,o.__name__=\"ScatterView\";class g extends l.Marker{constructor(e){super(e)}}r.Scatter=g,n=g,g.__name__=\"Scatter\",n.prototype.default_view=o,n.define((()=>({marker:[c.MarkerSpec,{value:\"circle\"}]})))},\n", - " function _(e,t,s,n,i){n();const r=e(1);var a;const c=e(178),o=e(48),_=(0,r.__importStar)(e(185)),h=(0,r.__importStar)(e(18)),l=e(9),x=e(72);class d extends c.XYGlyphView{_render(e,t,s){const{sx:n,sy:i,size:r,angle:a}=null!=s?s:this;for(const s of t){const t=n[s],c=i[s],o=r.get(s),_=a.get(s);if(!isFinite(t+c+o+_))continue;const h=o/2;e.beginPath(),e.translate(t,c),_&&e.rotate(_),this._render_one(e,s,h,this.visuals),_&&e.rotate(-_),e.translate(-t,-c)}}_mask_data(){const{x_target:e,y_target:t}=this.renderer.plot_view.frame,s=e.widen(this.max_size).map((e=>this.renderer.xscale.invert(e))),n=t.widen(this.max_size).map((e=>this.renderer.yscale.invert(e)));return this.index.indices({x0:s.start,x1:s.end,y0:n.start,y1:n.end})}_hit_point(e){const{sx:t,sy:s}=e,{max_size:n}=this,{hit_dilation:i}=this.model,r=t-n*i,a=t+n*i,[c,o]=this.renderer.xscale.r_invert(r,a),_=s-n*i,h=s+n*i,[l,d]=this.renderer.yscale.r_invert(_,h),y=this.index.indices({x0:c,x1:o,y0:l,y1:d}),g=[];for(const e of y){const n=this.size.get(e)/2*i;Math.abs(this.sx[e]-t)<=n&&Math.abs(this.sy[e]-s)<=n&&g.push(e)}return new x.Selection({indices:g})}_hit_span(e){const{sx:t,sy:s}=e,n=this.bounds(),i=this.max_size/2;let r,a,c,o;if(\"h\"==e.direction){c=n.y0,o=n.y1;const e=t-i,s=t+i;[r,a]=this.renderer.xscale.r_invert(e,s)}else{r=n.x0,a=n.x1;const e=s-i,t=s+i;[c,o]=this.renderer.yscale.r_invert(e,t)}const _=[...this.index.indices({x0:r,x1:a,y0:c,y1:o})];return new x.Selection({indices:_})}_hit_rect(e){const{sx0:t,sx1:s,sy0:n,sy1:i}=e,[r,a]=this.renderer.xscale.r_invert(t,s),[c,o]=this.renderer.yscale.r_invert(n,i),_=[...this.index.indices({x0:r,x1:a,y0:c,y1:o})];return new x.Selection({indices:_})}_hit_poly(e){const{sx:t,sy:s}=e,n=(0,l.range)(0,this.sx.length),i=[];for(let e=0,r=n.length;e({size:[h.ScreenSizeSpec,{value:4}],angle:[h.AngleSpec,0],hit_dilation:[e,1]})))},\n", - " function _(l,o,n,t,i){t();const e=Math.sqrt(3),a=Math.sqrt(5),c=(a+1)/4,p=Math.sqrt((5-a)/8),r=(a-1)/4,h=Math.sqrt((5+a)/8);function u(l,o){l.rotate(Math.PI/4),s(l,o),l.rotate(-Math.PI/4)}function f(l,o){const n=o*e,t=n/3;l.moveTo(-n/2,-t),l.lineTo(0,0),l.lineTo(n/2,-t),l.lineTo(0,0),l.lineTo(0,o)}function s(l,o){l.moveTo(0,o),l.lineTo(0,-o),l.moveTo(-o,0),l.lineTo(o,0)}function T(l,o){l.moveTo(0,o),l.lineTo(o/1.5,0),l.lineTo(0,-o),l.lineTo(-o/1.5,0),l.closePath()}function y(l,o){const n=o*e,t=n/3;l.moveTo(-o,t),l.lineTo(o,t),l.lineTo(0,t-n),l.closePath()}function v(l,o,n,t){l.arc(0,0,n,0,2*Math.PI,!1),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}function d(l,o,n,t){T(l,n),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}function _(l,o,n,t){!function(l,o){l.beginPath(),l.arc(0,0,o/4,0,2*Math.PI,!1),l.closePath()}(l,n),t.line.set_vectorize(l,o),l.fillStyle=l.strokeStyle,l.fill()}function P(l,o,n,t){!function(l,o){const n=o/2,t=e*n;l.moveTo(o,0),l.lineTo(n,-t),l.lineTo(-n,-t),l.lineTo(-o,0),l.lineTo(-n,t),l.lineTo(n,t),l.closePath()}(l,n),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}function m(l,o,n,t){const i=2*n;l.rect(-n,-n,i,i),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}function q(l,o,n,t){!function(l,o){const n=Math.sqrt(5-2*a)*o;l.moveTo(0,-o),l.lineTo(n*r,n*h-o),l.lineTo(n*(1+r),n*h-o),l.lineTo(n*(1+r-c),n*(h+p)-o),l.lineTo(n*(1+2*r-c),n*(2*h+p)-o),l.lineTo(0,2*n*h-o),l.lineTo(-n*(1+2*r-c),n*(2*h+p)-o),l.lineTo(-n*(1+r-c),n*(h+p)-o),l.lineTo(-n*(1+r),n*h-o),l.lineTo(-n*r,n*h-o),l.closePath()}(l,n),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}function M(l,o,n,t){y(l,n),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)}n.marker_funcs={asterisk:function(l,o,n,t){s(l,n),u(l,n),t.line.apply(l,o)},circle:v,circle_cross:function(l,o,n,t){l.arc(0,0,n,0,2*Math.PI,!1),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),s(l,n),l.stroke())},circle_dot:function(l,o,n,t){v(l,o,n,t),_(l,o,n,t)},circle_y:function(l,o,n,t){l.arc(0,0,n,0,2*Math.PI,!1),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),f(l,n),l.stroke())},circle_x:function(l,o,n,t){l.arc(0,0,n,0,2*Math.PI,!1),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),u(l,n),l.stroke())},cross:function(l,o,n,t){s(l,n),t.line.apply(l,o)},diamond:d,diamond_dot:function(l,o,n,t){d(l,o,n,t),_(l,o,n,t)},diamond_cross:function(l,o,n,t){T(l,n),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),l.moveTo(0,n),l.lineTo(0,-n),l.moveTo(-n/1.5,0),l.lineTo(n/1.5,0),l.stroke())},dot:_,hex:P,hex_dot:function(l,o,n,t){P(l,o,n,t),_(l,o,n,t)},inverted_triangle:function(l,o,n,t){l.rotate(Math.PI),y(l,n),l.rotate(-Math.PI),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)},plus:function(l,o,n,t){const i=3*n/8,e=[i,i,n,n,i,i,-i,-i,-n,-n,-i,-i],a=[n,i,i,-i,-i,-n,-n,-i,-i,i,i,n];l.beginPath();for(let o=0;o<12;o++)l.lineTo(e[o],a[o]);l.closePath(),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)},square:m,square_cross:function(l,o,n,t){const i=2*n;l.rect(-n,-n,i,i),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),s(l,n),l.stroke())},square_dot:function(l,o,n,t){m(l,o,n,t),_(l,o,n,t)},square_pin:function(l,o,n,t){const i=3*n/8;l.moveTo(-n,-n),l.quadraticCurveTo(0,-i,n,-n),l.quadraticCurveTo(i,0,n,n),l.quadraticCurveTo(0,i,-n,n),l.quadraticCurveTo(-i,0,-n,-n),l.closePath(),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)},square_x:function(l,o,n,t){const i=2*n;l.rect(-n,-n,i,i),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.doit&&(t.line.set_vectorize(l,o),l.moveTo(-n,n),l.lineTo(n,-n),l.moveTo(-n,-n),l.lineTo(n,n),l.stroke())},star:q,star_dot:function(l,o,n,t){q(l,o,n,t),_(l,o,n,t)},triangle:M,triangle_dot:function(l,o,n,t){M(l,o,n,t),_(l,o,n,t)},triangle_pin:function(l,o,n,t){const i=n*e,a=i/3,c=3*a/8;l.moveTo(-n,a),l.quadraticCurveTo(0,c,n,a),l.quadraticCurveTo(e*c/2,c/2,0,a-i),l.quadraticCurveTo(-e*c/2,c/2,-n,a),l.closePath(),t.fill.apply(l,o),t.hatch.apply(l,o),t.line.apply(l,o)},dash:function(l,o,n,t){!function(l,o){l.moveTo(-o,0),l.lineTo(o,0)}(l,n),t.line.apply(l,o)},x:function(l,o,n,t){u(l,n),t.line.apply(l,o)},y:function(l,o,n,t){f(l,n),t.line.apply(l,o)}}},\n", - " function _(e,t,s,i,n){i();const r=e(1);var o;const _=(0,r.__importStar)(e(185)),h=(0,r.__importStar)(e(18)),c=e(48),a=e(78),d=e(179),x=e(184),l=e(72);class y extends d.GlyphView{_project_data(){a.inplace.project_xy(this._x0,this._y0),a.inplace.project_xy(this._x1,this._y1)}_index_data(e){const{min:t,max:s}=Math,{_x0:i,_x1:n,_y0:r,_y1:o,data_size:_}=this;for(let h=0;h<_;h++){const _=i[h],c=n[h],a=r[h],d=o[h];e.add_rect(t(_,c),t(a,d),s(_,c),s(a,d))}}_render(e,t,s){if(this.visuals.line.doit){const{sx0:i,sy0:n,sx1:r,sy1:o}=null!=s?s:this;for(const s of t){const t=i[s],_=n[s],h=r[s],c=o[s];isFinite(t+_+h+c)&&(e.beginPath(),e.moveTo(t,_),e.lineTo(h,c),this.visuals.line.set_vectorize(e,s),e.stroke())}}}_hit_point(e){const{sx:t,sy:s}=e,i={x:t,y:s},[n,r]=this.renderer.xscale.r_invert(t-2,t+2),[o,h]=this.renderer.yscale.r_invert(s-2,s+2),c=this.index.indices({x0:n,y0:o,x1:r,y1:h}),a=[];for(const e of c){const t=Math.max(2,this.line_width.get(e)/2)**2,s={x:this.sx0[e],y:this.sy0[e]},n={x:this.sx1[e],y:this.sy1[e]};_.dist_to_segment_squared(i,s,n)({x0:[h.XCoordinateSpec,{field:\"x0\"}],y0:[h.YCoordinateSpec,{field:\"y0\"}],x1:[h.XCoordinateSpec,{field:\"x1\"}],y1:[h.YCoordinateSpec,{field:\"y1\"}]}))),o.mixins(c.LineVector)},\n", - " function _(t,e,s,i,n){i();const o=t(1);var _;const l=t(178),a=(0,o.__importStar)(t(48)),c=t(296);class r extends l.XYGlyphView{_set_data(){const{tension:t,closed:e}=this.model;[this._xt,this._yt]=(0,c.catmullrom_spline)(this._x,this._y,20,t,e)}_map_data(){const{x_scale:t,y_scale:e}=this.renderer.coordinates;this.sxt=t.v_compute(this._xt),this.syt=e.v_compute(this._yt)}_render(t,e,s){const{sxt:i,syt:n}=null!=s?s:this;let o=!0;t.beginPath();const _=i.length;for(let e=0;e<_;e++){const s=i[e],_=n[e];isFinite(s+_)?o?(t.moveTo(s,_),o=!1):t.lineTo(s,_):o=!0}this.visuals.line.set_value(t),t.stroke()}}s.SplineView=r,r.__name__=\"SplineView\";class h extends l.XYGlyph{constructor(t){super(t)}}s.Spline=h,_=h,h.__name__=\"Spline\",_.prototype.default_view=r,_.mixins(a.LineScalar),_.define((({Boolean:t,Number:e})=>({tension:[e,.5],closed:[t,!1]})))},\n", - " function _(n,t,e,o,s){o();const c=n(24),l=n(11);e.catmullrom_spline=function(n,t,e=10,o=.5,s=!1){(0,l.assert)(n.length==t.length);const r=n.length,f=s?r+1:r,w=(0,c.infer_type)(n,t),i=new w(f+2),u=new w(f+2);i.set(n,1),u.set(t,1),s?(i[0]=n[r-1],u[0]=t[r-1],i[f]=n[0],u[f]=t[0],i[f+1]=n[1],u[f+1]=t[1]):(i[0]=n[0],u[0]=t[0],i[f+1]=n[r-1],u[f+1]=t[r-1]);const g=new w(4*(e+1));for(let n=0,t=0;n<=e;n++){const o=n/e,s=o**2,c=o*s;g[t++]=2*c-3*s+1,g[t++]=-2*c+3*s,g[t++]=c-2*s+o,g[t++]=c-s}const h=new w((f-1)*(e+1)),_=new w((f-1)*(e+1));for(let n=1,t=0;n1&&(e.stroke(),o=!1)}o?(e.lineTo(t,r),e.lineTo(a,c)):(e.beginPath(),e.moveTo(s[n],i[n]),o=!0),l=n}e.lineTo(s[a-1],i[a-1]),e.stroke()}}draw_legend_for_index(e,t,n){(0,r.generic_line_scalar_legend)(this.visuals,e,t)}}n.StepView=f,f.__name__=\"StepView\";class u extends a.XYGlyph{constructor(e){super(e)}}n.Step=u,l=u,u.__name__=\"Step\",l.prototype.default_view=f,l.mixins(c.LineScalar),l.define((()=>({mode:[_.StepMode,\"before\"]})))},\n", - " function _(t,e,s,i,n){i();const o=t(1);var _;const h=t(178),l=t(48),r=(0,o.__importStar)(t(185)),a=(0,o.__importStar)(t(18)),c=t(121),x=t(11),u=t(72);class f extends h.XYGlyphView{_rotate_point(t,e,s,i,n){return[(t-s)*Math.cos(n)-(e-i)*Math.sin(n)+s,(t-s)*Math.sin(n)+(e-i)*Math.cos(n)+i]}_text_bounds(t,e,s,i){return[[t,t+s,t+s,t,t],[e,e,e-i,e-i,e]]}_render(t,e,s){const{sx:i,sy:n,x_offset:o,y_offset:_,angle:h,text:l}=null!=s?s:this;this._sys=[],this._sxs=[];for(const s of e){const e=this._sxs[s]=[],r=this._sys[s]=[],a=i[s],x=n[s],u=o.get(s),f=_.get(s),p=h.get(s),g=l.get(s);if(isFinite(a+x+u+f+p)&&null!=g&&this.visuals.text.doit){const i=`${g}`;t.save(),t.translate(a+u,x+f),t.rotate(p),this.visuals.text.set_vectorize(t,s);const n=this.visuals.text.font_value(s),{height:o}=(0,c.font_metrics)(n),_=this.text_line_height.get(s)*o;if(-1==i.indexOf(\"\\n\")){t.fillText(i,0,0);const s=a+u,n=x+f,o=t.measureText(i).width,[h,l]=this._text_bounds(s,n,o,_);e.push(h),r.push(l)}else{const n=i.split(\"\\n\"),o=_*n.length,h=this.text_baseline.get(s);let l;switch(h){case\"top\":l=0;break;case\"middle\":l=-o/2+_/2;break;case\"bottom\":l=-o+_;break;default:l=0,console.warn(`'${h}' baseline not supported with multi line text`)}for(const s of n){t.fillText(s,0,l);const i=a+u,n=l+x+f,o=t.measureText(s).width,[h,c]=this._text_bounds(i,n,o,_);e.push(h),r.push(c),l+=_}}t.restore()}}}_hit_point(t){const{sx:e,sy:s}=t,i=[];for(let t=0;t({text:[a.NullStringSpec,{field:\"text\"}],angle:[a.AngleSpec,0],x_offset:[a.NumberSpec,0],y_offset:[a.NumberSpec,0]})))},\n", - " function _(t,e,s,i,r){i();const h=t(1);var o;const a=t(277),n=t(24),_=(0,h.__importStar)(t(18));class l extends a.BoxView{async lazy_initialize(){await super.lazy_initialize();const{webgl:e}=this.renderer.plot_view.canvas_view;if(null!=e&&e.regl_wrapper.has_webgl){const{LRTBGL:s}=await Promise.resolve().then((()=>(0,h.__importStar)(t(427))));this.glglyph=new s(e.regl_wrapper,this)}}scenterxy(t){return[this.sx[t],(this.stop[t]+this.sbottom[t])/2]}_lrtb(t){const e=this.width.get(t)/2,s=this._x[t],i=this._top[t],r=this._bottom[t];return[s-e,s+e,Math.max(i,r),Math.min(i,r)]}_map_data(){this.sx=this.renderer.xscale.v_compute(this._x),this.sw=this.sdist(this.renderer.xscale,this._x,this.width,\"center\"),this.stop=this.renderer.yscale.v_compute(this._top),this.sbottom=this.renderer.yscale.v_compute(this._bottom);const t=this.sx.length;this.sleft=new n.ScreenArray(t),this.sright=new n.ScreenArray(t);for(let e=0;e({x:[_.XCoordinateSpec,{field:\"x\"}],bottom:[_.YCoordinateSpec,{value:0}],width:[_.NumberSpec,{value:1}],top:[_.YCoordinateSpec,{field:\"top\"}]})))},\n", - " function _(e,s,t,i,n){i();const r=e(1);var a;const c=e(178),d=e(184),l=e(48),h=e(24),o=e(20),_=(0,r.__importStar)(e(18)),u=e(10),g=e(72),x=e(12);class p extends c.XYGlyphView{_map_data(){\"data\"==this.model.properties.radius.units?this.sradius=this.sdist(this.renderer.xscale,this._x,this.radius):this.sradius=(0,h.to_screen)(this.radius),this.max_sradius=(0,x.max)(this.sradius)}_render(e,s,t){const{sx:i,sy:n,sradius:r,start_angle:a,end_angle:c}=null!=t?t:this,d=\"anticlock\"==this.model.direction;for(const t of s){const s=i[t],l=n[t],h=r[t],o=a.get(t),_=c.get(t);isFinite(s+l+h+o+_)&&(e.beginPath(),e.arc(s,l,h,o,_,d),e.lineTo(s,l),e.closePath(),this.visuals.fill.apply(e,t),this.visuals.hatch.apply(e,t),this.visuals.line.apply(e,t))}}_hit_point(e){let s,t,i,n,r;const{sx:a,sy:c}=e,d=this.renderer.xscale.invert(a),l=this.renderer.yscale.invert(c);t=a-this.max_sradius,i=a+this.max_sradius;const[h,o]=this.renderer.xscale.r_invert(t,i);n=c-this.max_sradius,r=c+this.max_sradius;const[_,x]=this.renderer.yscale.r_invert(n,r),p=[];for(const e of this.index.indices({x0:h,x1:o,y0:_,y1:x})){const a=this.sradius[e]**2;[t,i]=this.renderer.xscale.r_compute(d,this._x[e]),[n,r]=this.renderer.yscale.r_compute(l,this._y[e]),s=(t-i)**2+(n-r)**2,s<=a&&p.push(e)}const y=\"anticlock\"==this.model.direction,m=[];for(const e of p){const s=Math.atan2(c-this.sy[e],a-this.sx[e]);(0,u.angle_between)(-s,-this.start_angle.get(e),-this.end_angle.get(e),y)&&m.push(e)}return new g.Selection({indices:m})}draw_legend_for_index(e,s,t){(0,d.generic_area_vector_legend)(this.visuals,e,s,t)}scenterxy(e){const s=this.sradius[e]/2,t=(this.start_angle.get(e)+this.end_angle.get(e))/2;return[this.sx[e]+s*Math.cos(t),this.sy[e]+s*Math.sin(t)]}}t.WedgeView=p,p.__name__=\"WedgeView\";class y extends c.XYGlyph{constructor(e){super(e)}}t.Wedge=y,a=y,y.__name__=\"Wedge\",a.prototype.default_view=p,a.mixins([l.LineVector,l.FillVector,l.HatchVector]),a.define((({})=>({direction:[o.Direction,\"anticlock\"],radius:[_.DistanceSpec,{field:\"radius\"}],start_angle:[_.AngleSpec,{field:\"start_angle\"}],end_angle:[_.AngleSpec,{field:\"end_angle\"}]})))},\n", - " function _(t,_,r,o,a){o();const e=t(1);(0,e.__exportStar)(t(302),r),(0,e.__exportStar)(t(303),r),(0,e.__exportStar)(t(304),r)},\n", - " function _(e,t,d,n,s){n();const o=e(53),r=e(12),_=e(9),i=e(72);class c extends o.Model{constructor(e){super(e)}_hit_test(e,t,d){if(!t.model.visible)return null;const n=d.glyph.hit_test(e);return null==n?null:d.model.view.convert_selection_from_subset(n)}}d.GraphHitTestPolicy=c,c.__name__=\"GraphHitTestPolicy\";class a extends c{constructor(e){super(e)}hit_test(e,t){return this._hit_test(e,t,t.edge_view)}do_selection(e,t,d,n){if(null==e)return!1;const s=t.edge_renderer.data_source.selected;return s.update(e,d,n),t.edge_renderer.data_source._select.emit(),!s.is_empty()}do_inspection(e,t,d,n,s){if(null==e)return!1;const{edge_renderer:o}=d.model,r=o.get_selection_manager().get_or_create_inspector(d.edge_view.model);return r.update(e,n,s),d.edge_view.model.data_source.setv({inspected:r},{silent:!0}),d.edge_view.model.data_source.inspect.emit([d.edge_view.model,{geometry:t}]),!r.is_empty()}}d.EdgesOnly=a,a.__name__=\"EdgesOnly\";class l extends c{constructor(e){super(e)}hit_test(e,t){return this._hit_test(e,t,t.node_view)}do_selection(e,t,d,n){if(null==e)return!1;const s=t.node_renderer.data_source.selected;return s.update(e,d,n),t.node_renderer.data_source._select.emit(),!s.is_empty()}do_inspection(e,t,d,n,s){if(null==e)return!1;const{node_renderer:o}=d.model,r=o.get_selection_manager().get_or_create_inspector(d.node_view.model);return r.update(e,n,s),d.node_view.model.data_source.setv({inspected:r},{silent:!0}),d.node_view.model.data_source.inspect.emit([d.node_view.model,{geometry:t}]),!r.is_empty()}}d.NodesOnly=l,l.__name__=\"NodesOnly\";class u extends c{constructor(e){super(e)}hit_test(e,t){return this._hit_test(e,t,t.node_view)}get_linked_edges(e,t,d){let n=[];\"selection\"==d?n=e.selected.indices.map((t=>e.data.index[t])):\"inspection\"==d&&(n=e.inspected.indices.map((t=>e.data.index[t])));const s=[];for(let e=0;e(0,r.indexOf)(e.data.index,t)));return new i.Selection({indices:o})}do_selection(e,t,d,n){if(null==e)return!1;const s=t.edge_renderer.data_source.selected;s.update(e,d,n);const o=t.node_renderer.data_source.selected,r=this.get_linked_nodes(t.node_renderer.data_source,t.edge_renderer.data_source,\"selection\");return o.update(r,d,n),t.edge_renderer.data_source._select.emit(),!s.is_empty()}do_inspection(e,t,d,n,s){if(null==e)return!1;const o=d.edge_view.model.data_source.selection_manager.get_or_create_inspector(d.edge_view.model);o.update(e,n,s),d.edge_view.model.data_source.setv({inspected:o},{silent:!0});const r=d.node_view.model.data_source.selection_manager.get_or_create_inspector(d.node_view.model),_=this.get_linked_nodes(d.node_view.model.data_source,d.edge_view.model.data_source,\"inspection\");return r.update(_,n,s),d.node_view.model.data_source.setv({inspected:r},{silent:!0}),d.edge_view.model.data_source.inspect.emit([d.edge_view.model,{geometry:t}]),!o.is_empty()}}d.EdgesAndLinkedNodes=m,m.__name__=\"EdgesAndLinkedNodes\"},\n", - " function _(e,o,t,r,n){var s;r();const a=e(53),d=e(260);class _ extends a.Model{constructor(e){super(e)}get node_coordinates(){return new u({layout:this})}get edge_coordinates(){return new i({layout:this})}}t.LayoutProvider=_,_.__name__=\"LayoutProvider\";class c extends d.CoordinateTransform{constructor(e){super(e)}}t.GraphCoordinates=c,s=c,c.__name__=\"GraphCoordinates\",s.define((({Ref:e})=>({layout:[e(_)]})));class u extends c{constructor(e){super(e)}_v_compute(e){const[o,t]=this.layout.get_node_coordinates(e);return{x:o,y:t}}}t.NodeCoordinates=u,u.__name__=\"NodeCoordinates\";class i extends c{constructor(e){super(e)}_v_compute(e){const[o,t]=this.layout.get_edge_coordinates(e);return{x:o,y:t}}}t.EdgeCoordinates=i,i.__name__=\"EdgeCoordinates\"},\n", - " function _(t,a,l,e,n){var o;e();const r=t(303);class u extends r.LayoutProvider{constructor(t){super(t)}get_node_coordinates(t){var a;const l=null!==(a=t.data.index)&&void 0!==a?a:[],e=l.length,n=new Float64Array(e),o=new Float64Array(e);for(let t=0;t({graph_layout:[l(a(t,t)),{}]})))},\n", - " function _(i,d,n,r,G){r(),G(\"Grid\",i(306).Grid)},\n", - " function _(i,e,n,s,t){s();const r=i(1);var o;const d=i(127),_=i(129),a=i(130),l=(0,r.__importStar)(i(48)),h=i(8);class c extends _.GuideRendererView{_render(){const i=this.layer.ctx;i.save(),this._draw_regions(i),this._draw_minor_grids(i),this._draw_grids(i),i.restore()}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render()))}_draw_regions(i){if(!this.visuals.band_fill.doit&&!this.visuals.band_hatch.doit)return;const[e,n]=this.grid_coords(\"major\",!1);for(let s=0;sn[1]&&(t=n[1]);else{[s,t]=n;for(const i of this.plot_view.axis_views)i.dimension==this.model.dimension&&i.model.x_range_name==this.model.x_range_name&&i.model.y_range_name==this.model.y_range_name&&([s,t]=i.computed_bounds)}return[s,t]}grid_coords(i,e=!0){const n=this.model.dimension,s=(n+1)%2,[t,r]=this.ranges();let[o,d]=this.computed_bounds();[o,d]=[Math.min(o,d),Math.max(o,d)];const _=[[],[]],a=this.model.get_ticker();if(null==a)return _;const l=a.get_ticks(o,d,t,r.min)[i],h=t.min,c=t.max,u=r.min,m=r.max;e||(l[0]!=h&&l.splice(0,0,h),l[l.length-1]!=c&&l.push(c));for(let i=0;i({bounds:[r(t(i,i),e),\"auto\"],dimension:[n(0,1),0],axis:[o(s(d.Axis)),null],ticker:[o(s(a.Ticker)),null]}))),o.override({level:\"underlay\",band_fill_color:null,band_fill_alpha:0,grid_line_color:\"#e5e5e5\",minor_grid_line_color:null})},\n", - " function _(o,a,x,B,e){B(),e(\"Box\",o(308).Box),e(\"Column\",o(310).Column),e(\"GridBox\",o(311).GridBox),e(\"HTMLBox\",o(312).HTMLBox),e(\"LayoutDOM\",o(309).LayoutDOM),e(\"Panel\",o(313).Panel),e(\"Row\",o(314).Row),e(\"Spacer\",o(315).Spacer),e(\"Tabs\",o(316).Tabs),e(\"WidgetBox\",o(319).WidgetBox)},\n", - " function _(e,n,s,t,c){var i;t();const o=e(309);class r extends o.LayoutDOMView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.children.change,(()=>this.rebuild()))}get child_models(){return this.model.children}}s.BoxView=r,r.__name__=\"BoxView\";class a extends o.LayoutDOM{constructor(e){super(e)}}s.Box=a,i=a,a.__name__=\"Box\",i.define((({Number:e,Array:n,Ref:s})=>({children:[n(s(o.LayoutDOM)),[]],spacing:[e,0]})))},\n", - " function _(t,i,e,s,o){var l;s();const n=t(53),h=t(20),a=t(43),r=t(19),_=t(8),c=t(22),u=t(121),d=t(113),p=t(226),m=t(207),g=t(44),w=t(235);class f extends p.DOMView{constructor(){super(...arguments),this._offset_parent=null,this._viewport={}}get is_layout_root(){return this.is_root||!(this.parent instanceof f)}get base_font_size(){const t=getComputedStyle(this.el).fontSize,i=(0,u.parse_css_font_size)(t);if(null!=i){const{value:t,unit:e}=i;if(\"px\"==e)return t}return null}initialize(){super.initialize(),this.el.style.position=this.is_layout_root?\"relative\":\"absolute\",this._child_views=new Map}async lazy_initialize(){await super.lazy_initialize(),await this.build_child_views()}remove(){for(const t of this.child_views)t.remove();this._child_views.clear(),super.remove()}connect_signals(){super.connect_signals(),this.is_layout_root&&(this._on_resize=()=>this.resize_layout(),window.addEventListener(\"resize\",this._on_resize),this._parent_observer=setInterval((()=>{const t=this.el.offsetParent;this._offset_parent!=t&&(this._offset_parent=t,null!=t&&(this.compute_viewport(),this.invalidate_layout()))}),250));const t=this.model.properties;this.on_change([t.width,t.height,t.min_width,t.min_height,t.max_width,t.max_height,t.margin,t.width_policy,t.height_policy,t.sizing_mode,t.aspect_ratio,t.visible],(()=>this.invalidate_layout())),this.on_change([t.background,t.css_classes],(()=>this.invalidate_render()))}disconnect_signals(){null!=this._parent_observer&&clearTimeout(this._parent_observer),null!=this._on_resize&&window.removeEventListener(\"resize\",this._on_resize),super.disconnect_signals()}css_classes(){return super.css_classes().concat(this.model.css_classes)}get child_views(){return this.child_models.map((t=>this._child_views.get(t)))}async build_child_views(){await(0,d.build_views)(this._child_views,this.child_models,{parent:this})}render(){super.render(),(0,a.empty)(this.el);const{background:t}=this.model;this.el.style.backgroundColor=null!=t?(0,c.color2css)(t):\"\",(0,a.classes)(this.el).clear().add(...this.css_classes());for(const t of this.child_views)this.el.appendChild(t.el),t.render()}update_layout(){for(const t of this.child_views)t.update_layout();this._update_layout()}update_position(){this.el.style.display=this.model.visible?\"block\":\"none\";const t=this.is_layout_root?this.layout.sizing.margin:void 0;(0,a.position)(this.el,this.layout.bbox,t);for(const t of this.child_views)t.update_position()}after_layout(){for(const t of this.child_views)t.after_layout();this._has_finished=!0}compute_viewport(){this._viewport=this._viewport_size()}renderTo(t){t.appendChild(this.el),this._offset_parent=this.el.offsetParent,this.compute_viewport(),this.build(),this.notify_finished()}build(){if(!this.is_layout_root)throw new Error(`${this.toString()} is not a root layout`);return this.render(),this.update_layout(),this.compute_layout(),this}async rebuild(){await this.build_child_views(),this.invalidate_render()}compute_layout(){const t=Date.now();this.layout.compute(this._viewport),this.update_position(),this.after_layout(),r.logger.debug(`layout computed in ${Date.now()-t} ms`)}resize_layout(){this.root.compute_viewport(),this.root.compute_layout()}invalidate_layout(){this.root.update_layout(),this.root.compute_layout()}invalidate_render(){this.render(),this.invalidate_layout()}has_finished(){if(!super.has_finished())return!1;for(const t of this.child_views)if(!t.has_finished())return!1;return!0}_width_policy(){return null!=this.model.width?\"fixed\":\"fit\"}_height_policy(){return null!=this.model.height?\"fixed\":\"fit\"}box_sizing(){let{width_policy:t,height_policy:i,aspect_ratio:e}=this.model;\"auto\"==t&&(t=this._width_policy()),\"auto\"==i&&(i=this._height_policy());const{sizing_mode:s}=this.model;if(null!=s)if(\"fixed\"==s)t=i=\"fixed\";else if(\"stretch_both\"==s)t=i=\"max\";else if(\"stretch_width\"==s)t=\"max\";else if(\"stretch_height\"==s)i=\"max\";else switch(null==e&&(e=\"auto\"),s){case\"scale_width\":t=\"max\",i=\"min\";break;case\"scale_height\":t=\"min\",i=\"max\";break;case\"scale_both\":t=\"max\",i=\"max\"}const o={width_policy:t,height_policy:i},{min_width:l,min_height:n}=this.model;null!=l&&(o.min_width=l),null!=n&&(o.min_height=n);const{width:h,height:a}=this.model;null!=h&&(o.width=h),null!=a&&(o.height=a);const{max_width:r,max_height:c}=this.model;null!=r&&(o.max_width=r),null!=c&&(o.max_height=c),\"auto\"==e&&null!=h&&null!=a?o.aspect=h/a:(0,_.isNumber)(e)&&(o.aspect=e);const{margin:u}=this.model;if(null!=u)if((0,_.isNumber)(u))o.margin={top:u,right:u,bottom:u,left:u};else if(2==u.length){const[t,i]=u;o.margin={top:t,right:i,bottom:t,left:i}}else{const[t,i,e,s]=u;o.margin={top:t,right:i,bottom:e,left:s}}o.visible=this.model.visible;const{align:d}=this.model;return(0,_.isArray)(d)?[o.halign,o.valign]=d:o.halign=o.valign=d,o}_viewport_size(){return(0,a.undisplayed)(this.el,(()=>{let t=this.el;for(;t=t.parentElement;){if(t.classList.contains(g.root))continue;if(t==document.body){const{margin:{left:t,right:i,top:e,bottom:s}}=(0,a.extents)(document.body);return{width:Math.ceil(document.documentElement.clientWidth-t-i),height:Math.ceil(document.documentElement.clientHeight-e-s)}}const{padding:{left:i,right:e,top:s,bottom:o}}=(0,a.extents)(t),{width:l,height:n}=t.getBoundingClientRect(),h=Math.ceil(l-i-e),r=Math.ceil(n-s-o);if(h>0||r>0)return{width:h>0?h:void 0,height:r>0?r:void 0}}return{}}))}export(t,i=!0){const e=\"png\"==t?\"canvas\":\"svg\",s=new w.CanvasLayer(e,i),{width:o,height:l}=this.layout.bbox;s.resize(o,l);for(const e of this.child_views){const o=e.export(t,i),{x:l,y:n}=e.layout.bbox;s.ctx.drawImage(o.canvas,l,n)}return s}serializable_state(){return Object.assign(Object.assign({},super.serializable_state()),{bbox:this.layout.bbox.box,children:this.child_views.map((t=>t.serializable_state()))})}}e.LayoutDOMView=f,f.__name__=\"LayoutDOMView\";class y extends n.Model{constructor(t){super(t)}}e.LayoutDOM=y,l=y,y.__name__=\"LayoutDOM\",l.define((t=>{const{Boolean:i,Number:e,String:s,Auto:o,Color:l,Array:n,Tuple:a,Or:r,Null:_,Nullable:c}=t,u=a(e,e),d=a(e,e,e,e);return{width:[c(e),null],height:[c(e),null],min_width:[c(e),null],min_height:[c(e),null],max_width:[c(e),null],max_height:[c(e),null],margin:[c(r(e,u,d)),[0,0,0,0]],width_policy:[r(m.SizingPolicy,o),\"auto\"],height_policy:[r(m.SizingPolicy,o),\"auto\"],aspect_ratio:[r(e,o,_),null],sizing_mode:[c(h.SizingMode),null],visible:[i,!0],disabled:[i,!1],align:[r(h.Align,a(h.Align,h.Align)),\"start\"],background:[c(l),null],css_classes:[n(s),[]]}}))},\n", - " function _(o,s,t,i,e){var n;i();const a=o(308),l=o(209);class u extends a.BoxView{_update_layout(){const o=this.child_views.map((o=>o.layout));this.layout=new l.Column(o),this.layout.rows=this.model.rows,this.layout.spacing=[this.model.spacing,0],this.layout.set_sizing(this.box_sizing())}}t.ColumnView=u,u.__name__=\"ColumnView\";class _ extends a.Box{constructor(o){super(o)}}t.Column=_,n=_,_.__name__=\"Column\",n.prototype.default_view=u,n.define((({Any:o})=>({rows:[o,\"auto\"]})))},\n", - " function _(s,o,t,i,e){var n;i();const l=s(309),a=s(209);class r extends l.LayoutDOMView{connect_signals(){super.connect_signals();const{children:s,rows:o,cols:t,spacing:i}=this.model.properties;this.on_change([s,o,t,i],(()=>this.rebuild()))}get child_models(){return this.model.children.map((([s])=>s))}_update_layout(){this.layout=new a.Grid,this.layout.rows=this.model.rows,this.layout.cols=this.model.cols,this.layout.spacing=this.model.spacing;for(const[s,o,t,i,e]of this.model.children){const n=this._child_views.get(s);this.layout.items.push({layout:n.layout,row:o,col:t,row_span:i,col_span:e})}this.layout.set_sizing(this.box_sizing())}}t.GridBoxView=r,r.__name__=\"GridBoxView\";class c extends l.LayoutDOM{constructor(s){super(s)}}t.GridBox=c,n=c,c.__name__=\"GridBox\",n.prototype.default_view=r,n.define((({Any:s,Int:o,Number:t,Tuple:i,Array:e,Ref:n,Or:a,Opt:r})=>({children:[e(i(n(l.LayoutDOM),o,o,r(o),r(o))),[]],rows:[s,\"auto\"],cols:[s,\"auto\"],spacing:[a(t,i(t,t)),0]})))},\n", - " function _(t,e,o,s,n){s();const _=t(309),i=t(207);class a extends _.LayoutDOMView{get child_models(){return[]}_update_layout(){this.layout=new i.ContentBox(this.el),this.layout.set_sizing(this.box_sizing())}}o.HTMLBoxView=a,a.__name__=\"HTMLBoxView\";class u extends _.LayoutDOM{constructor(t){super(t)}}o.HTMLBox=u,u.__name__=\"HTMLBox\"},\n", - " function _(e,n,l,a,o){var t;a();const s=e(53),c=e(309);class d extends s.Model{constructor(e){super(e)}}l.Panel=d,t=d,d.__name__=\"Panel\",t.define((({Boolean:e,String:n,Ref:l})=>({title:[n,\"\"],child:[l(c.LayoutDOM)],closable:[e,!1],disabled:[e,!1]})))},\n", - " function _(o,s,t,i,e){var a;i();const n=o(308),l=o(209);class _ extends n.BoxView{_update_layout(){const o=this.child_views.map((o=>o.layout));this.layout=new l.Row(o),this.layout.cols=this.model.cols,this.layout.spacing=[0,this.model.spacing],this.layout.set_sizing(this.box_sizing())}}t.RowView=_,_.__name__=\"RowView\";class c extends n.Box{constructor(o){super(o)}}t.Row=c,a=c,c.__name__=\"Row\",a.prototype.default_view=_,a.define((({Any:o})=>({cols:[o,\"auto\"]})))},\n", - " function _(e,t,a,s,_){var o;s();const i=e(309),n=e(207);class u extends i.LayoutDOMView{get child_models(){return[]}_update_layout(){this.layout=new n.LayoutItem,this.layout.set_sizing(this.box_sizing())}}a.SpacerView=u,u.__name__=\"SpacerView\";class c extends i.LayoutDOM{constructor(e){super(e)}}a.Spacer=c,o=c,c.__name__=\"Spacer\",o.prototype.default_view=u},\n", - " function _(e,t,s,i,l){i();const h=e(1);var a;const o=e(207),d=e(43),r=e(9),c=e(10),n=e(20),_=e(309),p=e(313),b=(0,h.__importStar)(e(317)),m=b,u=(0,h.__importStar)(e(318)),g=u,v=(0,h.__importStar)(e(229)),w=v;class f extends _.LayoutDOMView{constructor(){super(...arguments),this._scroll_index=0}connect_signals(){super.connect_signals(),this.connect(this.model.properties.tabs.change,(()=>this.rebuild())),this.connect(this.model.properties.active.change,(()=>this.on_active_change()))}styles(){return[...super.styles(),u.default,v.default,b.default]}get child_models(){return this.model.tabs.map((e=>e.child))}_update_layout(){const e=this.model.tabs_location,t=\"above\"==e||\"below\"==e,{scroll_el:s,headers_el:i}=this;this.header=new class extends o.ContentBox{_measure(e){const l=(0,d.size)(s),h=(0,d.children)(i).slice(0,3).map((e=>(0,d.size)(e))),{width:a,height:o}=super._measure(e);if(t){const t=l.width+(0,r.sum)(h.map((e=>e.width)));return{width:e.width!=1/0?e.width:t,height:o}}{const t=l.height+(0,r.sum)(h.map((e=>e.height)));return{width:a,height:e.height!=1/0?e.height:t}}}}(this.header_el),t?this.header.set_sizing({width_policy:\"fit\",height_policy:\"fixed\"}):this.header.set_sizing({width_policy:\"fixed\",height_policy:\"fit\"});let l=1,h=1;switch(e){case\"above\":l-=1;break;case\"below\":l+=1;break;case\"left\":h-=1;break;case\"right\":h+=1}const a={layout:this.header,row:l,col:h},c=this.child_views.map((e=>({layout:e.layout,row:1,col:1})));this.layout=new o.Grid([a,...c]),this.layout.set_sizing(this.box_sizing())}update_position(){super.update_position(),this.header_el.style.position=\"absolute\",(0,d.position)(this.header_el,this.header.bbox);const e=this.model.tabs_location,t=\"above\"==e||\"below\"==e,s=(0,d.size)(this.scroll_el),i=(0,d.scroll_size)(this.headers_el);if(t){const{width:e}=this.header.bbox;i.width>e?(this.wrapper_el.style.maxWidth=e-s.width+\"px\",(0,d.display)(this.scroll_el),this.do_scroll(this.model.active)):(this.wrapper_el.style.maxWidth=\"\",(0,d.undisplay)(this.scroll_el))}else{const{height:e}=this.header.bbox;i.height>e?(this.wrapper_el.style.maxHeight=e-s.height+\"px\",(0,d.display)(this.scroll_el),this.do_scroll(this.model.active)):(this.wrapper_el.style.maxHeight=\"\",(0,d.undisplay)(this.scroll_el))}const{child_views:l}=this;for(const e of l)(0,d.hide)(e.el);const h=l[this.model.active];null!=h&&(0,d.show)(h.el)}render(){super.render();const{active:e}=this.model,t=this.model.tabs.map(((t,s)=>{const i=(0,d.div)({class:[m.tab,s==e?m.active:null]},t.title);if(i.addEventListener(\"click\",(e=>{this.model.disabled||e.target==e.currentTarget&&this.change_active(s)})),t.closable){const e=(0,d.div)({class:m.close});e.addEventListener(\"click\",(e=>{if(e.target==e.currentTarget){this.model.tabs=(0,r.remove_at)(this.model.tabs,s);const e=this.model.tabs.length;this.model.active>e-1&&(this.model.active=e-1)}})),i.appendChild(e)}return(this.model.disabled||t.disabled)&&i.classList.add(m.disabled),i}));this.headers_el=(0,d.div)({class:[m.headers]},t),this.wrapper_el=(0,d.div)({class:m.headers_wrapper},this.headers_el),this.left_el=(0,d.div)({class:[g.btn,g.btn_default],disabled:\"\"},(0,d.div)({class:[w.caret,m.left]})),this.right_el=(0,d.div)({class:[g.btn,g.btn_default]},(0,d.div)({class:[w.caret,m.right]})),this.left_el.addEventListener(\"click\",(()=>this.do_scroll(\"left\"))),this.right_el.addEventListener(\"click\",(()=>this.do_scroll(\"right\"))),this.scroll_el=(0,d.div)({class:g.btn_group},this.left_el,this.right_el);const s=this.model.tabs_location;this.header_el=(0,d.div)({class:[m.tabs_header,m[s]]},this.scroll_el,this.wrapper_el),this.el.appendChild(this.header_el)}do_scroll(e){const t=this.model.tabs.length;\"left\"==e?this._scroll_index-=1:\"right\"==e?this._scroll_index+=1:this._scroll_index=e,this._scroll_index=(0,c.clamp)(this._scroll_index,0,t-1),0==this._scroll_index?this.left_el.setAttribute(\"disabled\",\"\"):this.left_el.removeAttribute(\"disabled\"),this._scroll_index==t-1?this.right_el.setAttribute(\"disabled\",\"\"):this.right_el.removeAttribute(\"disabled\");const s=(0,d.children)(this.headers_el).slice(0,this._scroll_index).map((e=>e.getBoundingClientRect())),i=this.model.tabs_location;if(\"above\"==i||\"below\"==i){const e=-(0,r.sum)(s.map((e=>e.width)));this.headers_el.style.left=`${e}px`}else{const e=-(0,r.sum)(s.map((e=>e.height)));this.headers_el.style.top=`${e}px`}}change_active(e){e!=this.model.active&&(this.model.active=e)}on_active_change(){const e=this.model.active,t=(0,d.children)(this.headers_el);for(const e of t)e.classList.remove(m.active);t[e].classList.add(m.active);const{child_views:s}=this;for(const e of s)(0,d.hide)(e.el);(0,d.show)(s[e].el)}}s.TabsView=f,f.__name__=\"TabsView\";class x extends _.LayoutDOM{constructor(e){super(e)}}s.Tabs=x,a=x,x.__name__=\"Tabs\",a.prototype.default_view=f,a.define((({Int:e,Array:t,Ref:s})=>({tabs:[t(s(p.Panel)),[]],tabs_location:[n.Location,\"above\"],active:[e,0]})))},\n", - " function _(e,r,b,o,t){o(),b.root=\"bk-root\",b.tabs_header=\"bk-tabs-header\",b.btn_group=\"bk-btn-group\",b.btn=\"bk-btn\",b.headers_wrapper=\"bk-headers-wrapper\",b.above=\"bk-above\",b.right=\"bk-right\",b.below=\"bk-below\",b.left=\"bk-left\",b.headers=\"bk-headers\",b.tab=\"bk-tab\",b.active=\"bk-active\",b.close=\"bk-close\",b.disabled=\"bk-disabled\",b.default='.bk-root .bk-tabs-header{display:flex;flex-wrap:nowrap;align-items:center;overflow:hidden;user-select:none;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;}.bk-root .bk-tabs-header .bk-btn-group{height:auto;margin-right:5px;}.bk-root .bk-tabs-header .bk-btn-group > .bk-btn{flex-grow:0;height:auto;padding:4px 4px;}.bk-root .bk-tabs-header .bk-headers-wrapper{flex-grow:1;overflow:hidden;color:#666666;}.bk-root .bk-tabs-header.bk-above .bk-headers-wrapper{border-bottom:1px solid #e6e6e6;}.bk-root .bk-tabs-header.bk-right .bk-headers-wrapper{border-left:1px solid #e6e6e6;}.bk-root .bk-tabs-header.bk-below .bk-headers-wrapper{border-top:1px solid #e6e6e6;}.bk-root .bk-tabs-header.bk-left .bk-headers-wrapper{border-right:1px solid #e6e6e6;}.bk-root .bk-tabs-header.bk-above,.bk-root .bk-tabs-header.bk-below{flex-direction:row;}.bk-root .bk-tabs-header.bk-above .bk-headers,.bk-root .bk-tabs-header.bk-below .bk-headers{flex-direction:row;}.bk-root .bk-tabs-header.bk-left,.bk-root .bk-tabs-header.bk-right{flex-direction:column;}.bk-root .bk-tabs-header.bk-left .bk-headers,.bk-root .bk-tabs-header.bk-right .bk-headers{flex-direction:column;}.bk-root .bk-tabs-header .bk-headers{position:relative;display:flex;flex-wrap:nowrap;align-items:center;}.bk-root .bk-tabs-header .bk-tab{padding:4px 8px;border:solid transparent;white-space:nowrap;cursor:pointer;}.bk-root .bk-tabs-header .bk-tab:hover{background-color:#f2f2f2;}.bk-root .bk-tabs-header .bk-tab.bk-active{color:#4d4d4d;background-color:white;border-color:#e6e6e6;}.bk-root .bk-tabs-header .bk-tab .bk-close{margin-left:10px;}.bk-root .bk-tabs-header .bk-tab.bk-disabled{cursor:not-allowed;pointer-events:none;opacity:0.65;}.bk-root .bk-tabs-header.bk-above .bk-tab{border-width:3px 1px 0px 1px;border-radius:4px 4px 0 0;}.bk-root .bk-tabs-header.bk-right .bk-tab{border-width:1px 3px 1px 0px;border-radius:0 4px 4px 0;}.bk-root .bk-tabs-header.bk-below .bk-tab{border-width:0px 1px 3px 1px;border-radius:0 0 4px 4px;}.bk-root .bk-tabs-header.bk-left .bk-tab{border-width:1px 0px 1px 3px;border-radius:4px 0 0 4px;}.bk-root .bk-close{display:inline-block;width:10px;height:10px;vertical-align:middle;background-image:url(\\'data:image/svg+xml;utf8, \\');}.bk-root .bk-close:hover{background-image:url(\\'data:image/svg+xml;utf8, \\');}'},\n", - " function _(o,b,r,t,e){t(),r.root=\"bk-root\",r.btn=\"bk-btn\",r.active=\"bk-active\",r.btn_default=\"bk-btn-default\",r.btn_primary=\"bk-btn-primary\",r.btn_success=\"bk-btn-success\",r.btn_warning=\"bk-btn-warning\",r.btn_danger=\"bk-btn-danger\",r.btn_light=\"bk-btn-light\",r.btn_group=\"bk-btn-group\",r.vertical=\"bk-vertical\",r.horizontal=\"bk-horizontal\",r.dropdown_toggle=\"bk-dropdown-toggle\",r.default=\".bk-root .bk-btn{height:100%;display:inline-block;text-align:center;vertical-align:middle;white-space:nowrap;cursor:pointer;padding:6px 12px;font-size:12px;border:1px solid transparent;border-radius:4px;outline:0;user-select:none;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;}.bk-root .bk-btn:hover,.bk-root .bk-btn:focus{text-decoration:none;}.bk-root .bk-btn:active,.bk-root .bk-btn.bk-active{background-image:none;box-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);}.bk-root .bk-btn[disabled]{cursor:not-allowed;pointer-events:none;opacity:0.65;box-shadow:none;}.bk-root .bk-btn-default{color:#333;background-color:#fff;border-color:#ccc;}.bk-root .bk-btn-default:hover{background-color:#f5f5f5;border-color:#b8b8b8;}.bk-root .bk-btn-default.bk-active{background-color:#ebebeb;border-color:#adadad;}.bk-root .bk-btn-default[disabled],.bk-root .bk-btn-default[disabled]:hover,.bk-root .bk-btn-default[disabled]:focus,.bk-root .bk-btn-default[disabled]:active,.bk-root .bk-btn-default[disabled].bk-active{background-color:#e6e6e6;border-color:#ccc;}.bk-root .bk-btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd;}.bk-root .bk-btn-primary:hover{background-color:#3681c1;border-color:#2c699e;}.bk-root .bk-btn-primary.bk-active{background-color:#3276b1;border-color:#285e8e;}.bk-root .bk-btn-primary[disabled],.bk-root .bk-btn-primary[disabled]:hover,.bk-root .bk-btn-primary[disabled]:focus,.bk-root .bk-btn-primary[disabled]:active,.bk-root .bk-btn-primary[disabled].bk-active{background-color:#506f89;border-color:#357ebd;}.bk-root .bk-btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c;}.bk-root .bk-btn-success:hover{background-color:#4eb24e;border-color:#409240;}.bk-root .bk-btn-success.bk-active{background-color:#47a447;border-color:#398439;}.bk-root .bk-btn-success[disabled],.bk-root .bk-btn-success[disabled]:hover,.bk-root .bk-btn-success[disabled]:focus,.bk-root .bk-btn-success[disabled]:active,.bk-root .bk-btn-success[disabled].bk-active{background-color:#667b66;border-color:#4cae4c;}.bk-root .bk-btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236;}.bk-root .bk-btn-warning:hover{background-color:#eea43b;border-color:#e89014;}.bk-root .bk-btn-warning.bk-active{background-color:#ed9c28;border-color:#d58512;}.bk-root .bk-btn-warning[disabled],.bk-root .bk-btn-warning[disabled]:hover,.bk-root .bk-btn-warning[disabled]:focus,.bk-root .bk-btn-warning[disabled]:active,.bk-root .bk-btn-warning[disabled].bk-active{background-color:#c89143;border-color:#eea236;}.bk-root .bk-btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a;}.bk-root .bk-btn-danger:hover{background-color:#d5433e;border-color:#bd2d29;}.bk-root .bk-btn-danger.bk-active{background-color:#d2322d;border-color:#ac2925;}.bk-root .bk-btn-danger[disabled],.bk-root .bk-btn-danger[disabled]:hover,.bk-root .bk-btn-danger[disabled]:focus,.bk-root .bk-btn-danger[disabled]:active,.bk-root .bk-btn-danger[disabled].bk-active{background-color:#a55350;border-color:#d43f3a;}.bk-root .bk-btn-light{color:#333;background-color:#fff;border-color:#ccc;border-color:transparent;}.bk-root .bk-btn-light:hover{background-color:#f5f5f5;border-color:#b8b8b8;}.bk-root .bk-btn-light.bk-active{background-color:#ebebeb;border-color:#adadad;}.bk-root .bk-btn-light[disabled],.bk-root .bk-btn-light[disabled]:hover,.bk-root .bk-btn-light[disabled]:focus,.bk-root .bk-btn-light[disabled]:active,.bk-root .bk-btn-light[disabled].bk-active{background-color:#e6e6e6;border-color:#ccc;}.bk-root .bk-btn-group{height:100%;display:flex;flex-wrap:nowrap;align-items:center;}.bk-root .bk-btn-group:not(.bk-vertical),.bk-root .bk-btn-group.bk-horizontal{flex-direction:row;}.bk-root .bk-btn-group.bk-vertical{flex-direction:column;}.bk-root .bk-btn-group > .bk-btn{flex-grow:1;}.bk-root .bk-btn-group:not(.bk-vertical) > .bk-btn + .bk-btn{margin-left:-1px;}.bk-root .bk-btn-group.bk-vertical > .bk-btn + .bk-btn{margin-top:-1px;}.bk-root .bk-btn-group:not(.bk-vertical) > .bk-btn:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;}.bk-root .bk-btn-group.bk-vertical > .bk-btn:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0;}.bk-root .bk-btn-group:not(.bk-vertical) > .bk-btn:not(:first-child):last-child{border-bottom-left-radius:0;border-top-left-radius:0;}.bk-root .bk-btn-group.bk-vertical > .bk-btn:not(:first-child):last-child{border-top-left-radius:0;border-top-right-radius:0;}.bk-root .bk-btn-group > .bk-btn:not(:first-child):not(:last-child){border-radius:0;}.bk-root .bk-btn-group.bk-vertical > .bk-btn{width:100%;}.bk-root .bk-btn-group .bk-dropdown-toggle{flex:0 0 0;padding:6px 6px;}\"},\n", - " function _(e,t,o,n,_){var i;n();const s=e(310);class d extends s.ColumnView{}o.WidgetBoxView=d,d.__name__=\"WidgetBoxView\";class a extends s.Column{constructor(e){super(e)}}o.WidgetBox=a,i=a,a.__name__=\"WidgetBox\",i.prototype.default_view=d},\n", - " function _(t,a,i,e,M){e();var T=t(135);M(\"MathText\",T.MathText),M(\"Ascii\",T.Ascii),M(\"MathML\",T.MathML),M(\"TeX\",T.TeX),M(\"PlainText\",t(139).PlainText)},\n", - " function _(r,o,t,e,n){e(),n(\"CustomJSTransform\",r(322).CustomJSTransform),n(\"Dodge\",r(323).Dodge),n(\"Interpolator\",r(325).Interpolator),n(\"Jitter\",r(326).Jitter),n(\"LinearInterpolator\",r(327).LinearInterpolator),n(\"StepInterpolator\",r(328).StepInterpolator),n(\"Transform\",r(56).Transform)},\n", - " function _(r,t,s,n,e){var a;n();const u=r(56),o=r(13),m=r(34);class _ extends u.Transform{constructor(r){super(r)}get names(){return(0,o.keys)(this.args)}get values(){return(0,o.values)(this.args)}_make_transform(r,t){return new Function(...this.names,r,(0,m.use_strict)(t))}get scalar_transform(){return this._make_transform(\"x\",this.func)}get vector_transform(){return this._make_transform(\"xs\",this.v_func)}compute(r){return this.scalar_transform(...this.values,r)}v_compute(r){return this.vector_transform(...this.values,r)}}s.CustomJSTransform=_,a=_,_.__name__=\"CustomJSTransform\",a.define((({Unknown:r,String:t,Dict:s})=>({args:[s(r),{}],func:[t,\"\"],v_func:[t,\"\"]})))},\n", - " function _(e,n,r,o,s){var t;o();const u=e(324);class a extends u.RangeTransform{constructor(e){super(e)}_compute(e){return e+this.value}}r.Dodge=a,t=a,a.__name__=\"Dodge\",t.define((({Number:e})=>({value:[e,0]})))},\n", - " function _(e,n,t,r,a){var s;r();const c=e(56),o=e(57),i=e(67),u=e(24),h=e(8),l=e(11);class g extends c.Transform{constructor(e){super(e)}v_compute(e){let n;this.range instanceof i.FactorRange?n=this.range.v_synthetic(e):(0,h.isArrayableOf)(e,h.isNumber)?n=e:(0,l.unreachable)();const t=new((0,u.infer_type)(n))(n.length);for(let e=0;e({range:[n(e(o.Range)),null]})))},\n", - " function _(t,e,r,n,s){var o;n();const i=t(56),a=t(70),h=t(24),l=t(9),d=t(8);class c extends i.Transform{constructor(t){super(t),this._sorted_dirty=!0}connect_signals(){super.connect_signals(),this.connect(this.change,(()=>this._sorted_dirty=!0))}v_compute(t){const e=new((0,h.infer_type)(t))(t.length);for(let r=0;ro*(e[t]-e[r]))),this._x_sorted=new((0,h.infer_type)(e))(n),this._y_sorted=new((0,h.infer_type)(r))(n);for(let t=0;t({x:[o(r,s(e))],y:[o(r,s(e))],data:[i(n(a.ColumnarDataSource)),null],clip:[t,!0]})))},\n", - " function _(t,s,e,i,r){i();const n=t(1);var o;const a=t(324),u=t(67),h=t(20),c=t(8),m=t(12),f=(0,n.__importStar)(t(10)),_=t(11);class p extends a.RangeTransform{constructor(t){super(t)}v_compute(t){var s;let e;this.range instanceof u.FactorRange?e=this.range.v_synthetic(t):(0,c.isArrayableOf)(t,c.isNumber)?e=t:(0,_.unreachable)();const i=e.length;(null===(s=this.previous_offsets)||void 0===s?void 0:s.length)!=i&&(this.previous_offsets=new Array(i),this.previous_offsets=(0,m.map)(this.previous_offsets,(()=>this._compute())));const r=this.previous_offsets;return(0,m.map)(e,((t,s)=>r[s]+t))}_compute(){switch(this.distribution){case\"uniform\":return this.mean+(f.random()-.5)*this.width;case\"normal\":return f.rnorm(this.mean,this.width)}}}e.Jitter=p,o=p,p.__name__=\"Jitter\",o.define((({Number:t})=>({mean:[t,0],width:[t,1],distribution:[h.Distribution,\"uniform\"]})))},\n", - " function _(t,s,_,r,e){r();const i=t(9),o=t(325);class n extends o.Interpolator{constructor(t){super(t)}compute(t){if(this.sort(!1),this.clip){if(tthis._x_sorted[this._x_sorted.length-1])return NaN}else{if(tthis._x_sorted[this._x_sorted.length-1])return this._y_sorted[this._y_sorted.length-1]}if(t==this._x_sorted[0])return this._y_sorted[0];const s=(0,i.find_last_index)(this._x_sorted,(s=>sthis._x_sorted[this._x_sorted.length-1])return NaN}else{if(tthis._x_sorted[this._x_sorted.length-1])return this._y_sorted[this._y_sorted.length-1]}let e;switch(this.mode){case\"after\":e=(0,d.find_last_index)(this._x_sorted,(e=>t>=e));break;case\"before\":e=(0,d.find_index)(this._x_sorted,(e=>t<=e));break;case\"center\":{const s=(0,d.map)(this._x_sorted,(e=>Math.abs(e-t))),r=(0,d.min)(s);e=(0,d.find_index)(s,(t=>r===t));break}default:throw new Error(`unknown mode: ${this.mode}`)}return-1!=e?this._y_sorted[e]:NaN}}s.StepInterpolator=h,_=h,h.__name__=\"StepInterpolator\",_.define((()=>({mode:[n.StepMode,\"after\"]})))},\n", - " function _(p,o,t,a,n){a(),n(\"MapOptions\",p(330).MapOptions),n(\"GMapOptions\",p(330).GMapOptions),n(\"GMapPlot\",p(330).GMapPlot),n(\"Plot\",p(331).Plot)},\n", - " function _(e,t,n,o,a){var s,p,_;o();const i=e(331),r=e(53),l=e(58),c=e(336);a(\"GMapPlotView\",c.GMapPlotView);class d extends r.Model{constructor(e){super(e)}}n.MapOptions=d,s=d,d.__name__=\"MapOptions\",s.define((({Int:e,Number:t})=>({lat:[t],lng:[t],zoom:[e,12]})));class u extends d{constructor(e){super(e)}}n.GMapOptions=u,p=u,u.__name__=\"GMapOptions\",p.define((({Boolean:e,Int:t,String:n})=>({map_type:[n,\"roadmap\"],scale_control:[e,!1],styles:[n],tilt:[t,45]})));class M extends i.Plot{constructor(e){super(e),this.use_map=!0}}n.GMapPlot=M,_=M,M.__name__=\"GMapPlot\",_.prototype.default_view=c.GMapPlotView,_.define((({String:e,Ref:t})=>({map_options:[t(u)],api_key:[e],api_version:[e,\"weekly\"]}))),_.override({x_range:()=>new l.Range1d,y_range:()=>new l.Range1d})},\n", - " function _(e,t,r,n,i){n();const o=e(1);var a;const s=(0,o.__importStar)(e(48)),l=(0,o.__importStar)(e(18)),_=e(15),c=e(20),h=e(9),d=e(13),u=e(8),g=e(309),p=e(128),f=e(306),b=e(40),w=e(118),y=e(59),m=e(221),x=e(57),v=e(55),A=e(75),S=e(41),R=e(176),D=e(175),L=e(63),P=e(332);i(\"PlotView\",P.PlotView);class k extends g.LayoutDOM{constructor(e){super(e),this.use_map=!1}_doc_attached(){super._doc_attached(),this._push_changes([[this.properties.inner_height,null,this.inner_height],[this.properties.inner_width,null,this.inner_width]])}initialize(){super.initialize(),this.reset=new _.Signal0(this,\"reset\");for(const e of(0,d.values)(this.extra_x_ranges).concat(this.x_range)){let t=e.plots;(0,u.isArray)(t)&&(t=t.concat(this),e.setv({plots:t},{silent:!0}))}for(const e of(0,d.values)(this.extra_y_ranges).concat(this.y_range)){let t=e.plots;(0,u.isArray)(t)&&(t=t.concat(this),e.setv({plots:t},{silent:!0}))}}add_layout(e,t=\"center\"){const r=this.properties[t].get_value();this.setv({[t]:[...r,e]})}remove_layout(e){const t=t=>{(0,h.remove_by)(t,(t=>t==e))};t(this.left),t(this.right),t(this.above),t(this.below),t(this.center)}get data_renderers(){return this.renderers.filter((e=>e instanceof R.DataRenderer))}add_renderers(...e){this.renderers=this.renderers.concat(e)}add_glyph(e,t=new A.ColumnDataSource,r={}){const n=new D.GlyphRenderer(Object.assign(Object.assign({},r),{data_source:t,glyph:e}));return this.add_renderers(n),n}add_tools(...e){this.toolbar.tools=this.toolbar.tools.concat(e)}get panels(){return[...this.side_panels,...this.center]}get side_panels(){const{above:e,below:t,left:r,right:n}=this;return(0,h.concat)([e,t,r,n])}}r.Plot=k,a=k,k.__name__=\"Plot\",a.prototype.default_view=P.PlotView,a.mixins([[\"outline_\",s.Line],[\"background_\",s.Fill],[\"border_\",s.Fill]]),a.define((({Boolean:e,Number:t,String:r,Array:n,Dict:i,Or:o,Ref:a,Null:s,Nullable:_})=>({toolbar:[a(m.Toolbar),()=>new m.Toolbar],toolbar_location:[_(c.Location),\"right\"],toolbar_sticky:[e,!0],plot_width:[l.Alias(\"width\")],plot_height:[l.Alias(\"height\")],frame_width:[_(t),null],frame_height:[_(t),null],title:[o(a(w.Title),r,s),\"\",{convert:e=>(0,u.isString)(e)?new w.Title({text:e}):e}],title_location:[_(c.Location),\"above\"],above:[n(o(a(b.Annotation),a(p.Axis))),[]],below:[n(o(a(b.Annotation),a(p.Axis))),[]],left:[n(o(a(b.Annotation),a(p.Axis))),[]],right:[n(o(a(b.Annotation),a(p.Axis))),[]],center:[n(o(a(b.Annotation),a(f.Grid))),[]],renderers:[n(a(S.Renderer)),[]],x_range:[a(x.Range),()=>new L.DataRange1d],y_range:[a(x.Range),()=>new L.DataRange1d],x_scale:[a(v.Scale),()=>new y.LinearScale],y_scale:[a(v.Scale),()=>new y.LinearScale],extra_x_ranges:[i(a(x.Range)),{}],extra_y_ranges:[i(a(x.Range)),{}],extra_x_scales:[i(a(v.Scale)),{}],extra_y_scales:[i(a(v.Scale)),{}],lod_factor:[t,10],lod_interval:[t,300],lod_threshold:[_(t),2e3],lod_timeout:[t,500],hidpi:[e,!0],output_backend:[c.OutputBackend,\"canvas\"],min_border:[_(t),5],min_border_top:[_(t),null],min_border_left:[_(t),null],min_border_bottom:[_(t),null],min_border_right:[_(t),null],inner_width:[t,0],inner_height:[t,0],outer_width:[t,0],outer_height:[t,0],match_aspect:[e,!1],aspect_scale:[t,1],reset_policy:[c.ResetPolicy,\"standard\"]}))),a.override({width:600,height:600,outline_line_color:\"#e5e5e5\",border_fill_color:\"#ffffff\",background_fill_color:\"#ffffff\"})},\n", - " function _(e,t,i,s,a){s();const n=e(1),o=e(126),l=e(249),r=e(309),_=e(40),h=e(118),d=e(128),u=e(220),c=e(251),p=e(113),v=e(45),g=e(19),b=e(251),m=e(333),y=e(8),w=e(9),f=e(235),x=e(208),z=e(211),k=e(209),q=e(123),M=e(65),R=e(334),V=e(335),S=e(28);class O extends r.LayoutDOMView{constructor(){super(...arguments),this._outer_bbox=new M.BBox,this._inner_bbox=new M.BBox,this._needs_paint=!0,this._needs_layout=!1,this._invalidated_painters=new Set,this._invalidate_all=!0,this._needs_notify=!1}get canvas(){return this.canvas_view}get state(){return this._state_manager}set invalidate_dataranges(e){this._range_manager.invalidate_dataranges=e}renderer_view(e){const t=this.renderer_views.get(e);if(null==t)for(const[,t]of this.renderer_views){const i=t.renderer_view(e);if(null!=i)return i}return t}get is_paused(){return null!=this._is_paused&&0!==this._is_paused}get child_models(){return[]}pause(){null==this._is_paused?this._is_paused=1:this._is_paused+=1}unpause(e=!1){if(null==this._is_paused)throw new Error(\"wasn't paused\");this._is_paused-=1,0!=this._is_paused||e||this.request_paint(\"everything\")}notify_finished_after_paint(){this._needs_notify=!0}request_render(){this.request_paint(\"everything\")}request_paint(e){this.invalidate_painters(e),this.schedule_paint()}invalidate_painters(e){if(\"everything\"==e)this._invalidate_all=!0;else if((0,y.isArray)(e))for(const t of e)this._invalidated_painters.add(t);else this._invalidated_painters.add(e)}schedule_paint(){if(!this.is_paused){const e=this.throttled_paint();this._ready=this._ready.then((()=>e))}}request_layout(){this._needs_layout=!0,this.request_paint(\"everything\")}reset(){\"standard\"==this.model.reset_policy&&(this.state.clear(),this.reset_range(),this.reset_selection()),this.model.trigger_event(new c.Reset)}remove(){(0,p.remove_views)(this.renderer_views),(0,p.remove_views)(this.tool_views),this.canvas_view.remove(),super.remove()}render(){super.render(),this.el.appendChild(this.canvas_view.el),this.canvas_view.render()}initialize(){this.pause(),super.initialize(),this.lod_started=!1,this.visuals=new v.Visuals(this),this._initial_state={selection:new Map,dimensions:{width:0,height:0}},this.visibility_callbacks=[],this.renderer_views=new Map,this.tool_views=new Map,this.frame=new o.CartesianFrame(this.model.x_scale,this.model.y_scale,this.model.x_range,this.model.y_range,this.model.extra_x_ranges,this.model.extra_y_ranges,this.model.extra_x_scales,this.model.extra_y_scales),this._range_manager=new R.RangeManager(this),this._state_manager=new V.StateManager(this,this._initial_state),this.throttled_paint=(0,m.throttle)((()=>this.repaint()),1e3/60);const{title_location:e,title:t}=this.model;null!=e&&null!=t&&(this._title=t instanceof h.Title?t:new h.Title({text:t}));const{toolbar_location:i,toolbar:s}=this.model;null!=i&&null!=s&&(this._toolbar=new u.ToolbarPanel({toolbar:s}),s.toolbar_location=i)}async lazy_initialize(){await super.lazy_initialize();const{hidpi:e,output_backend:t}=this.model,i=new l.Canvas({hidpi:e,output_backend:t});this.canvas_view=await(0,p.build_view)(i,{parent:this}),this.canvas_view.plot_views=[this],await this.build_renderer_views(),await this.build_tool_views(),this._range_manager.update_dataranges(),this.unpause(!0),g.logger.debug(\"PlotView initialized\")}_width_policy(){return null==this.model.frame_width?super._width_policy():\"min\"}_height_policy(){return null==this.model.frame_height?super._height_policy():\"min\"}_update_layout(){var e,t,i,s,a;this.layout=new z.BorderLayout,this.layout.set_sizing(this.box_sizing());const n=(0,w.copy)(this.model.above),o=(0,w.copy)(this.model.below),l=(0,w.copy)(this.model.left),r=(0,w.copy)(this.model.right),d=e=>{switch(e){case\"above\":return n;case\"below\":return o;case\"left\":return l;case\"right\":return r}},{title_location:c,title:p}=this.model;null!=c&&null!=p&&d(c).push(this._title);const{toolbar_location:v,toolbar:g}=this.model;if(null!=v&&null!=g){const e=d(v);let t=!0;if(this.model.toolbar_sticky)for(let i=0;i{var i;const s=this.renderer_view(t);return s.panel=new q.Panel(e),null===(i=s.update_layout)||void 0===i||i.call(s),s.layout},m=(e,t)=>{const i=\"above\"==e||\"below\"==e,s=[];for(const a of t)if((0,y.isArray)(a)){const t=a.map((t=>{const s=b(e,t);if(t instanceof u.ToolbarPanel){const e=i?\"width_policy\":\"height_policy\";s.set_sizing(Object.assign(Object.assign({},s.sizing),{[e]:\"min\"}))}return s}));let n;i?(n=new k.Row(t),n.set_sizing({width_policy:\"max\",height_policy:\"min\"})):(n=new k.Column(t),n.set_sizing({width_policy:\"min\",height_policy:\"max\"})),n.absolute=!0,s.push(n)}else s.push(b(e,a));return s},f=null!==(e=this.model.min_border)&&void 0!==e?e:0;this.layout.min_border={left:null!==(t=this.model.min_border_left)&&void 0!==t?t:f,top:null!==(i=this.model.min_border_top)&&void 0!==i?i:f,right:null!==(s=this.model.min_border_right)&&void 0!==s?s:f,bottom:null!==(a=this.model.min_border_bottom)&&void 0!==a?a:f};const M=new x.NodeLayout,R=new x.VStack,V=new x.VStack,S=new x.HStack,O=new x.HStack;M.absolute=!0,R.absolute=!0,V.absolute=!0,S.absolute=!0,O.absolute=!0,M.children=this.model.center.filter((e=>e instanceof _.Annotation)).map((e=>{var t;const i=this.renderer_view(e);return null===(t=i.update_layout)||void 0===t||t.call(i),i.layout})).filter((e=>null!=e));const{frame_width:P,frame_height:j}=this.model;M.set_sizing(Object.assign(Object.assign({},null!=P?{width_policy:\"fixed\",width:P}:{width_policy:\"fit\"}),null!=j?{height_policy:\"fixed\",height:j}:{height_policy:\"fit\"})),M.on_resize((e=>this.frame.set_geometry(e))),R.children=(0,w.reversed)(m(\"above\",n)),V.children=m(\"below\",o),S.children=(0,w.reversed)(m(\"left\",l)),O.children=m(\"right\",r),R.set_sizing({width_policy:\"fit\",height_policy:\"min\"}),V.set_sizing({width_policy:\"fit\",height_policy:\"min\"}),S.set_sizing({width_policy:\"min\",height_policy:\"fit\"}),O.set_sizing({width_policy:\"min\",height_policy:\"fit\"}),this.layout.center_panel=M,this.layout.top_panel=R,this.layout.bottom_panel=V,this.layout.left_panel=S,this.layout.right_panel=O}get axis_views(){const e=[];for(const[,t]of this.renderer_views)t instanceof d.AxisView&&e.push(t);return e}set_toolbar_visibility(e){for(const t of this.visibility_callbacks)t(e)}update_range(e,t){this.pause(),this._range_manager.update(e,t),this.unpause()}reset_range(){this.update_range(null),this.trigger_ranges_update_event()}trigger_ranges_update_event(){const{x_range:e,y_range:t}=this.model;this.model.trigger_event(new b.RangesUpdate(e.start,e.end,t.start,t.end))}get_selection(){const e=new Map;for(const t of this.model.data_renderers){const{selected:i}=t.selection_manager.source;e.set(t,i)}return e}update_selection(e){for(const t of this.model.data_renderers){const i=t.selection_manager.source;if(null!=e){const s=e.get(t);null!=s&&i.selected.update(s,!0)}else i.selection_manager.clear()}}reset_selection(){this.update_selection(null)}_invalidate_layout(){(()=>{var e;for(const t of this.model.side_panels){const i=this.renderer_views.get(t);if(null===(e=i.layout)||void 0===e?void 0:e.has_size_changed())return this.invalidate_painters(i),!0}return!1})()&&this.root.compute_layout()}get_renderer_views(){return this.computed_renderers.map((e=>this.renderer_views.get(e)))}*_compute_renderers(){const{above:e,below:t,left:i,right:s,center:a,renderers:n}=this.model;yield*n,yield*e,yield*t,yield*i,yield*s,yield*a,null!=this._title&&(yield this._title),null!=this._toolbar&&(yield this._toolbar);for(const e of this.model.toolbar.tools)null!=e.overlay&&(yield e.overlay),yield*e.synthetic_renderers}async build_renderer_views(){this.computed_renderers=[...this._compute_renderers()],await(0,p.build_views)(this.renderer_views,this.computed_renderers,{parent:this})}async build_tool_views(){const e=this.model.toolbar.tools;(await(0,p.build_views)(this.tool_views,e,{parent:this})).map((e=>this.canvas_view.ui_event_bus.register_tool(e)))}connect_signals(){super.connect_signals();const{x_ranges:e,y_ranges:t}=this.frame;for(const[,t]of e)this.connect(t.change,(()=>{this._needs_layout=!0,this.request_paint(\"everything\")}));for(const[,e]of t)this.connect(e.change,(()=>{this._needs_layout=!0,this.request_paint(\"everything\")}));const{above:i,below:s,left:a,right:n,center:o,renderers:l}=this.model.properties;this.on_change([i,s,a,n,o,l],(async()=>await this.build_renderer_views())),this.connect(this.model.toolbar.properties.tools.change,(async()=>{await this.build_renderer_views(),await this.build_tool_views()})),this.connect(this.model.change,(()=>this.request_paint(\"everything\"))),this.connect(this.model.reset,(()=>this.reset()))}has_finished(){if(!super.has_finished())return!1;if(this.model.visible)for(const[,e]of this.renderer_views)if(!e.has_finished())return!1;return!0}after_layout(){var e;super.after_layout();for(const[,t]of this.renderer_views)t instanceof _.AnnotationView&&(null===(e=t.after_layout)||void 0===e||e.call(t));if(this._needs_layout=!1,this.model.setv({inner_width:Math.round(this.frame.bbox.width),inner_height:Math.round(this.frame.bbox.height),outer_width:Math.round(this.layout.bbox.width),outer_height:Math.round(this.layout.bbox.height)},{no_change:!0}),!1!==this.model.match_aspect&&(this.pause(),this._range_manager.update_dataranges(),this.unpause(!0)),!this._outer_bbox.equals(this.layout.bbox)){const{width:e,height:t}=this.layout.bbox;this.canvas_view.resize(e,t),this._outer_bbox=this.layout.bbox,this._invalidate_all=!0,this._needs_paint=!0}const{inner_bbox:t}=this.layout;this._inner_bbox.equals(t)||(this._inner_bbox=t,this._needs_paint=!0),this._needs_paint&&this.paint()}repaint(){this._needs_layout&&this._invalidate_layout(),this.paint()}paint(){this.is_paused||(this.model.visible&&(g.logger.trace(`${this.toString()}.paint()`),this._actual_paint()),this._needs_notify&&(this._needs_notify=!1,this.notify_finished()))}_actual_paint(){var e;const{document:t}=this.model;if(null!=t){const e=t.interactive_duration();e>=0&&e{t.interactive_duration()>this.model.lod_timeout&&t.interactive_stop(),this.request_paint(\"everything\")}),this.model.lod_timeout):t.interactive_stop()}this._range_manager.invalidate_dataranges&&(this._range_manager.update_dataranges(),this._invalidate_layout());let i=!1,s=!1;if(this._invalidate_all)i=!0,s=!0;else for(const e of this._invalidated_painters){const{level:t}=e.model;if(\"overlay\"!=t?i=!0:s=!0,i&&s)break}this._invalidated_painters.clear(),this._invalidate_all=!1;const a=[this.frame.bbox.left,this.frame.bbox.top,this.frame.bbox.width,this.frame.bbox.height],{primary:n,overlays:o}=this.canvas_view;i&&(n.prepare(),this.canvas_view.prepare_webgl(a),this._map_hook(n.ctx,a),this._paint_empty(n.ctx,a),this._paint_outline(n.ctx,a),this._paint_levels(n.ctx,\"image\",a,!0),this._paint_levels(n.ctx,\"underlay\",a,!0),this._paint_levels(n.ctx,\"glyph\",a,!0),this._paint_levels(n.ctx,\"guide\",a,!1),this._paint_levels(n.ctx,\"annotation\",a,!1),n.finish()),(s||S.settings.wireframe)&&(o.prepare(),this._paint_levels(o.ctx,\"overlay\",a,!1),S.settings.wireframe&&this._paint_layout(o.ctx,this.layout),o.finish()),null==this._initial_state.range&&(this._initial_state.range=null!==(e=this._range_manager.compute_initial())&&void 0!==e?e:void 0),this._needs_paint=!1}_paint_levels(e,t,i,s){for(const a of this.computed_renderers){if(a.level!=t)continue;const n=this.renderer_views.get(a);e.save(),(s||n.needs_clip)&&(e.beginPath(),e.rect(...i),e.clip()),n.render(),e.restore(),n.has_webgl&&n.needs_webgl_blit&&this.canvas_view.blit_webgl(e)}}_paint_layout(e,t){const{x:i,y:s,width:a,height:n}=t.bbox;e.strokeStyle=\"blue\",e.strokeRect(i,s,a,n);for(const a of t)e.save(),t.absolute||e.translate(i,s),this._paint_layout(e,a),e.restore()}_map_hook(e,t){}_paint_empty(e,t){const[i,s,a,n]=[0,0,this.layout.bbox.width,this.layout.bbox.height],[o,l,r,_]=t;this.visuals.border_fill.doit&&(this.visuals.border_fill.set_value(e),e.fillRect(i,s,a,n),e.clearRect(o,l,r,_)),this.visuals.background_fill.doit&&(this.visuals.background_fill.set_value(e),e.fillRect(o,l,r,_))}_paint_outline(e,t){if(this.visuals.outline_line.doit){e.save(),this.visuals.outline_line.set_value(e);let[i,s,a,n]=t;i+a==this.layout.bbox.width&&(a-=1),s+n==this.layout.bbox.height&&(n-=1),e.strokeRect(i,s,a,n),e.restore()}}to_blob(){return this.canvas_view.to_blob()}export(e,t=!0){const i=\"png\"==e?\"canvas\":\"svg\",s=new f.CanvasLayer(i,t),{width:a,height:n}=this.layout.bbox;s.resize(a,n);const{canvas:o}=this.canvas_view.compose();return s.ctx.drawImage(o,0,0),s}serializable_state(){const e=super.serializable_state(),{children:t}=e,i=(0,n.__rest)(e,[\"children\"]),s=this.get_renderer_views().map((e=>e.serializable_state())).filter((e=>null!=e.bbox));return Object.assign(Object.assign({},i),{children:[...null!=t?t:[],...s]})}}i.PlotView=O,O.__name__=\"PlotView\"},\n", - " function _(t,n,e,o,u){o(),e.throttle=function(t,n){let e=null,o=0,u=!1;return function(){return new Promise(((r,i)=>{const l=function(){o=Date.now(),e=null,u=!1;try{t(),r()}catch(t){i(t)}},a=Date.now(),c=n-(a-o);c<=0&&!u?(null!=e&&clearTimeout(e),u=!0,requestAnimationFrame(l)):e||u?r():e=setTimeout((()=>requestAnimationFrame(l)),c)}))}}},\n", - " function _(t,n,e,a,s){a();const o=t(63),r=t(19);class l{constructor(t){this.parent=t,this.invalidate_dataranges=!0}get frame(){return this.parent.frame}update(t,n){const{x_ranges:e,y_ranges:a}=this.frame;if(null==t){for(const[,t]of e)t.reset();for(const[,t]of a)t.reset();this.update_dataranges()}else{const s=[];for(const[n,a]of e)s.push([a,t.xrs.get(n)]);for(const[n,e]of a)s.push([e,t.yrs.get(n)]);(null==n?void 0:n.scrolling)&&this._update_ranges_together(s),this._update_ranges_individually(s,n)}}reset(){this.update(null)}_update_dataranges(t){const n=new Map,e=new Map;let a=!1;for(const[,n]of t.x_ranges)n instanceof o.DataRange1d&&\"log\"==n.scale_hint&&(a=!0);for(const[,n]of t.y_ranges)n instanceof o.DataRange1d&&\"log\"==n.scale_hint&&(a=!0);for(const t of this.parent.model.data_renderers){const s=this.parent.renderer_view(t);if(null==s)continue;const o=s.glyph_view.bounds();if(null!=o&&n.set(t,o),a){const n=s.glyph_view.log_bounds();null!=n&&e.set(t,n)}}let s=!1,l=!1;const i=t.x_target.span,d=t.y_target.span;let u;!1!==this.parent.model.match_aspect&&0!=i&&0!=d&&(u=1/this.parent.model.aspect_scale*(i/d));for(const[,a]of t.x_ranges){if(a instanceof o.DataRange1d){const t=\"log\"==a.scale_hint?e:n;a.update(t,0,this.parent.model,u),a.follow&&(s=!0)}null!=a.bounds&&(l=!0)}for(const[,a]of t.y_ranges){if(a instanceof o.DataRange1d){const t=\"log\"==a.scale_hint?e:n;a.update(t,1,this.parent.model,u),a.follow&&(s=!0)}null!=a.bounds&&(l=!0)}if(s&&l){r.logger.warn(\"Follow enabled so bounds are unset.\");for(const[,n]of t.x_ranges)n.bounds=null;for(const[,n]of t.y_ranges)n.bounds=null}}update_dataranges(){this._update_dataranges(this.frame);for(const t of this.parent.model.renderers){const{coordinates:n}=t;null!=n&&this._update_dataranges(n)}null!=this.compute_initial()&&(this.invalidate_dataranges=!1)}compute_initial(){let t=!0;const{x_ranges:n,y_ranges:e}=this.frame,a=new Map,s=new Map;for(const[e,s]of n){const{start:n,end:o}=s;if(null==n||null==o||isNaN(n+o)){t=!1;break}a.set(e,{start:n,end:o})}if(t)for(const[n,a]of e){const{start:e,end:o}=a;if(null==e||null==o||isNaN(e+o)){t=!1;break}s.set(n,{start:e,end:o})}return t?{xrs:a,yrs:s}:(r.logger.warn(\"could not set initial ranges\"),null)}_update_ranges_together(t){let n=1;for(const[e,a]of t)n=Math.min(n,this._get_weight_to_constrain_interval(e,a));if(n<1)for(const[e,a]of t)a.start=n*a.start+(1-n)*e.start,a.end=n*a.end+(1-n)*e.end}_update_ranges_individually(t,n){const e=!!(null==n?void 0:n.panning),a=!!(null==n?void 0:n.scrolling);let s=!1;for(const[n,o]of t){if(!a){const t=this._get_weight_to_constrain_interval(n,o);t<1&&(o.start=t*o.start+(1-t)*n.start,o.end=t*o.end+(1-t)*n.end)}if(null!=n.bounds&&\"auto\"!=n.bounds){const[t,r]=n.bounds,l=Math.abs(o.end-o.start);n.is_reversed?(null!=t&&t>o.end&&(s=!0,o.end=t,(e||a)&&(o.start=t+l)),null!=r&&ro.start&&(s=!0,o.start=t,(e||a)&&(o.end=t+l)),null!=r&&r0&&r0&&r>a&&(s=(a-o)/(r-o)),s=Math.max(0,Math.min(1,s))}return s}}e.RangeManager=l,l.__name__=\"RangeManager\"},\n", - " function _(t,i,s,e,n){e();const h=t(15);class a{constructor(t,i){this.parent=t,this.initial_state=i,this.changed=new h.Signal0(this.parent,\"state_changed\"),this.history=[],this.index=-1}_do_state_change(t){const i=null!=this.history[t]?this.history[t].state:this.initial_state;return null!=i.range&&this.parent.update_range(i.range),null!=i.selection&&this.parent.update_selection(i.selection),i}push(t,i){const{history:s,index:e}=this,n=null!=s[e]?s[e].state:{},h=Object.assign(Object.assign(Object.assign({},this.initial_state),n),i);this.history=this.history.slice(0,this.index+1),this.history.push({type:t,state:h}),this.index=this.history.length-1,this.changed.emit()}clear(){this.history=[],this.index=-1,this.changed.emit()}undo(){if(this.can_undo){this.index-=1;const t=this._do_state_change(this.index);return this.changed.emit(),t}return null}redo(){if(this.can_redo){this.index+=1;const t=this._do_state_change(this.index);return this.changed.emit(),t}return null}get can_undo(){return this.index>=0}get can_redo(){return this.indexm.emit();const s=encodeURIComponent,o=document.createElement(\"script\");o.type=\"text/javascript\",o.src=`https://maps.googleapis.com/maps/api/js?v=${s(e)}&key=${s(t)}&callback=_bokeh_gmaps_callback`,document.body.appendChild(o)}(t,e)}m.connect((()=>this.request_paint(\"everything\")))}this.unpause()}remove(){(0,p.remove)(this.map_el),super.remove()}update_range(t,e){var s,o;if(null==t)this.map.setCenter({lat:this.initial_lat,lng:this.initial_lng}),this.map.setOptions({zoom:this.initial_zoom}),super.update_range(null,e);else if(null!=t.sdx||null!=t.sdy)this.map.panBy(null!==(s=t.sdx)&&void 0!==s?s:0,null!==(o=t.sdy)&&void 0!==o?o:0),super.update_range(t,e);else if(null!=t.factor){if(10!==this.zoom_count)return void(this.zoom_count+=1);this.zoom_count=0,this.pause(),super.update_range(t,e);const s=t.factor<0?-1:1,o=this.map.getZoom();if(null!=o){const t=o+s;if(t>=2){this.map.setZoom(t);const[e,s]=this._get_projected_bounds();s-e<0&&this.map.setZoom(o)}}this.unpause()}this._set_bokeh_ranges()}_build_map(){const{maps:t}=google;this.map_types={satellite:t.MapTypeId.SATELLITE,terrain:t.MapTypeId.TERRAIN,roadmap:t.MapTypeId.ROADMAP,hybrid:t.MapTypeId.HYBRID};const e=this.model.map_options,s={center:new t.LatLng(e.lat,e.lng),zoom:e.zoom,disableDefaultUI:!0,mapTypeId:this.map_types[e.map_type],scaleControl:e.scale_control,tilt:e.tilt};null!=e.styles&&(s.styles=JSON.parse(e.styles)),this.map_el=(0,p.div)({style:{position:\"absolute\"}}),this.canvas_view.add_underlay(this.map_el),this.map=new t.Map(this.map_el,s),t.event.addListener(this.map,\"idle\",(()=>this._set_bokeh_ranges())),t.event.addListener(this.map,\"bounds_changed\",(()=>this._set_bokeh_ranges())),t.event.addListenerOnce(this.map,\"tilesloaded\",(()=>this._render_finished())),this.connect(this.model.properties.map_options.change,(()=>this._update_options())),this.connect(this.model.map_options.properties.styles.change,(()=>this._update_styles())),this.connect(this.model.map_options.properties.lat.change,(()=>this._update_center(\"lat\"))),this.connect(this.model.map_options.properties.lng.change,(()=>this._update_center(\"lng\"))),this.connect(this.model.map_options.properties.zoom.change,(()=>this._update_zoom())),this.connect(this.model.map_options.properties.map_type.change,(()=>this._update_map_type())),this.connect(this.model.map_options.properties.scale_control.change,(()=>this._update_scale_control())),this.connect(this.model.map_options.properties.tilt.change,(()=>this._update_tilt()))}_render_finished(){this._tiles_loaded=!0,this.notify_finished()}has_finished(){return super.has_finished()&&!0===this._tiles_loaded}_get_latlon_bounds(){const t=this.map.getBounds(),e=t.getNorthEast(),s=t.getSouthWest();return[s.lng(),e.lng(),s.lat(),e.lat()]}_get_projected_bounds(){const[t,e,s,o]=this._get_latlon_bounds(),[i,a]=l.wgs84_mercator.compute(t,s),[n,p]=l.wgs84_mercator.compute(e,o);return[i,n,a,p]}_set_bokeh_ranges(){const[t,e,s,o]=this._get_projected_bounds();this.frame.x_range.setv({start:t,end:e}),this.frame.y_range.setv({start:s,end:o})}_update_center(t){var e;const s=null===(e=this.map.getCenter())||void 0===e?void 0:e.toJSON();null!=s&&(s[t]=this.model.map_options[t],this.map.setCenter(s),this._set_bokeh_ranges())}_update_map_type(){this.map.setOptions({mapTypeId:this.map_types[this.model.map_options.map_type]})}_update_scale_control(){this.map.setOptions({scaleControl:this.model.map_options.scale_control})}_update_tilt(){this.map.setOptions({tilt:this.model.map_options.tilt})}_update_options(){this._update_styles(),this._update_center(\"lat\"),this._update_center(\"lng\"),this._update_zoom(),this._update_map_type()}_update_styles(){this.map.setOptions({styles:JSON.parse(this.model.map_options.styles)})}_update_zoom(){this.map.setOptions({zoom:this.model.map_options.zoom}),this._set_bokeh_ranges()}_map_hook(t,e){if(null==this.map&&\"undefined\"!=typeof google&&null!=google.maps&&this._build_map(),null!=this.map_el){const[t,s,o,i]=e;this.map_el.style.top=`${s}px`,this.map_el.style.left=`${t}px`,this.map_el.style.width=`${o}px`,this.map_el.style.height=`${i}px`}}_paint_empty(t,e){const s=this.layout.bbox.width,o=this.layout.bbox.height,[i,a,n,p]=e;t.clearRect(0,0,s,o),t.beginPath(),t.moveTo(0,0),t.lineTo(0,o),t.lineTo(s,o),t.lineTo(s,0),t.lineTo(0,0),t.moveTo(i,a),t.lineTo(i+n,a),t.lineTo(i+n,a+p),t.lineTo(i,a+p),t.lineTo(i,a),t.closePath(),null!=this.model.border_fill_color&&(t.fillStyle=(0,_.color2css)(this.model.border_fill_color),t.fill())}}s.GMapPlotView=d,d.__name__=\"GMapPlotView\"},\n", - " function _(t,_,n,o,r){o();(0,t(1).__exportStar)(t(132),n)},\n", - " function _(e,r,d,n,R){n(),R(\"GlyphRenderer\",e(175).GlyphRenderer),R(\"GraphRenderer\",e(339).GraphRenderer),R(\"GuideRenderer\",e(129).GuideRenderer);var G=e(41);R(\"Renderer\",G.Renderer),R(\"RendererGroup\",G.RendererGroup)},\n", - " function _(e,r,i,n,t){var o;n();const s=e(176),d=e(175),a=e(303),p=e(302),l=e(113),_=e(178),h=e(283),y=e(286);class c extends s.DataRendererView{get glyph_view(){return this.node_view.glyph}async lazy_initialize(){await super.lazy_initialize(),this.apply_coordinates();const{parent:e}=this,{edge_renderer:r,node_renderer:i}=this.model;this.edge_view=await(0,l.build_view)(r,{parent:e}),this.node_view=await(0,l.build_view)(i,{parent:e})}connect_signals(){super.connect_signals(),this.connect(this.model.layout_provider.change,(()=>{this.apply_coordinates(),this.edge_view.set_data(),this.node_view.set_data(),this.request_render()}))}apply_coordinates(){const{edge_renderer:e,node_renderer:r}=this.model;if(!(e.glyph instanceof h.MultiLine||e.glyph instanceof y.Patches))throw new Error(`${this}.edge_renderer.glyph must be a MultiLine glyph`);if(!(r.glyph instanceof _.XYGlyph))throw new Error(`${this}.node_renderer.glyph must be a XYGlyph glyph`);const i=this.model.layout_provider.edge_coordinates,n=this.model.layout_provider.node_coordinates;e.glyph.properties.xs.internal=!0,e.glyph.properties.ys.internal=!0,r.glyph.properties.x.internal=!0,r.glyph.properties.y.internal=!0,e.glyph.xs={expr:i.x},e.glyph.ys={expr:i.y},r.glyph.x={expr:n.x},r.glyph.y={expr:n.y}}remove(){this.edge_view.remove(),this.node_view.remove(),super.remove()}_render(){this.edge_view.render(),this.node_view.render()}renderer_view(e){if(e instanceof d.GlyphRenderer){if(e==this.edge_view.model)return this.edge_view;if(e==this.node_view.model)return this.node_view}return super.renderer_view(e)}}i.GraphRendererView=c,c.__name__=\"GraphRendererView\";class g extends s.DataRenderer{constructor(e){super(e)}get_selection_manager(){return this.node_renderer.data_source.selection_manager}}i.GraphRenderer=g,o=g,g.__name__=\"GraphRenderer\",o.prototype.default_view=c,o.define((({Ref:e})=>({layout_provider:[e(a.LayoutProvider)],node_renderer:[e(d.GlyphRenderer)],edge_renderer:[e(d.GlyphRenderer)],selection_policy:[e(p.GraphHitTestPolicy),()=>new p.NodesOnly],inspection_policy:[e(p.GraphHitTestPolicy),()=>new p.NodesOnly]})))},\n", - " function _(e,t,n,o,c){o();(0,e(1).__exportStar)(e(74),n),c(\"Selection\",e(72).Selection)},\n", - " function _(a,e,S,o,r){o(),r(\"ServerSentDataSource\",a(342).ServerSentDataSource),r(\"AjaxDataSource\",a(344).AjaxDataSource),r(\"ColumnDataSource\",a(75).ColumnDataSource),r(\"ColumnarDataSource\",a(70).ColumnarDataSource),r(\"CDSView\",a(190).CDSView),r(\"DataSource\",a(71).DataSource),r(\"GeoJSONDataSource\",a(345).GeoJSONDataSource),r(\"WebDataSource\",a(343).WebDataSource)},\n", - " function _(e,t,i,a,s){a();const n=e(343);class r extends n.WebDataSource{constructor(e){super(e),this.initialized=!1}setup(){if(!this.initialized){this.initialized=!0;new EventSource(this.data_url).onmessage=e=>{var t;this.load_data(JSON.parse(e.data),this.mode,null!==(t=this.max_size)&&void 0!==t?t:void 0)}}}}i.ServerSentDataSource=r,r.__name__=\"ServerSentDataSource\"},\n", - " function _(e,t,a,n,r){var s;n();const l=e(75),o=e(20);class c extends l.ColumnDataSource{constructor(e){super(e)}get_column(e){const t=this.data[e];return null!=t?t:[]}get_length(){var e;return null!==(e=super.get_length())&&void 0!==e?e:0}initialize(){super.initialize(),this.setup()}load_data(e,t,a){const{adapter:n}=this;let r;switch(r=null!=n?n.execute(this,{response:e}):e,t){case\"replace\":this.data=r;break;case\"append\":{const e=this.data;for(const t of this.columns()){const n=Array.from(e[t]),s=Array.from(r[t]),l=n.concat(s);r[t]=null!=a?l.slice(-a):l}this.data=r;break}}}}a.WebDataSource=c,s=c,c.__name__=\"WebDataSource\",s.define((({Any:e,Int:t,String:a,Nullable:n})=>({max_size:[n(t),null],mode:[o.UpdateMode,\"replace\"],adapter:[n(e),null],data_url:[a]})))},\n", - " function _(t,e,i,s,a){var n;s();const r=t(343),o=t(20),l=t(19),d=t(13);class h extends r.WebDataSource{constructor(t){super(t),this.interval=null,this.initialized=!1}destroy(){null!=this.interval&&clearInterval(this.interval),super.destroy()}setup(){if(!this.initialized&&(this.initialized=!0,this.get_data(this.mode),null!=this.polling_interval)){const t=()=>this.get_data(this.mode,this.max_size,this.if_modified);this.interval=setInterval(t,this.polling_interval)}}get_data(t,e=null,i=!1){const s=this.prepare_request();s.addEventListener(\"load\",(()=>this.do_load(s,t,null!=e?e:void 0))),s.addEventListener(\"error\",(()=>this.do_error(s))),s.send()}prepare_request(){const t=new XMLHttpRequest;t.open(this.method,this.data_url,!0),t.withCredentials=!1,t.setRequestHeader(\"Content-Type\",this.content_type);const e=this.http_headers;for(const[i,s]of(0,d.entries)(e))t.setRequestHeader(i,s);return t}do_load(t,e,i){if(200===t.status){const s=JSON.parse(t.responseText);this.load_data(s,e,i)}}do_error(t){l.logger.error(`Failed to fetch JSON from ${this.data_url} with code ${t.status}`)}}i.AjaxDataSource=h,n=h,h.__name__=\"AjaxDataSource\",n.define((({Boolean:t,Int:e,String:i,Dict:s,Nullable:a})=>({polling_interval:[a(e),null],content_type:[i,\"application/json\"],http_headers:[s(i),{}],method:[o.HTTPMethod,\"POST\"],if_modified:[t,!1]})))},\n", - " function _(e,t,o,r,n){var s;r();const a=e(70),i=e(19),l=e(9),c=e(13);function _(e){return null!=e?e:NaN}const{hasOwnProperty:g}=Object.prototype;class u extends a.ColumnarDataSource{constructor(e){super(e)}initialize(){super.initialize(),this._update_data()}connect_signals(){super.connect_signals(),this.connect(this.properties.geojson.change,(()=>this._update_data()))}_update_data(){this.data=this.geojson_to_column_data()}_get_new_list_array(e){return(0,l.range)(0,e).map((e=>[]))}_get_new_nan_array(e){return(0,l.range)(0,e).map((e=>NaN))}_add_properties(e,t,o,r){var n;const s=null!==(n=e.properties)&&void 0!==n?n:{};for(const[e,n]of(0,c.entries)(s))g.call(t,e)||(t[e]=this._get_new_nan_array(r)),t[e][o]=_(n)}_add_geometry(e,t,o){function r(e,t){return e.concat([[NaN,NaN,NaN]]).concat(t)}switch(e.type){case\"Point\":{const[r,n,s]=e.coordinates;t.x[o]=r,t.y[o]=n,t.z[o]=_(s);break}case\"LineString\":{const{coordinates:r}=e;for(let e=0;e1&&i.logger.warn(\"Bokeh does not support Polygons with holes in, only exterior ring used.\");const r=e.coordinates[0];for(let e=0;e1&&i.logger.warn(\"Bokeh does not support Polygons with holes in, only exterior ring used.\"),n.push(t[0]);const s=n.reduce(r);for(let e=0;e({geojson:[e]}))),s.internal((({Dict:e,Arrayable:t})=>({data:[e(t),{}]})))},\n", - " function _(e,r,T,o,S){o(),S(\"BBoxTileSource\",e(347).BBoxTileSource),S(\"MercatorTileSource\",e(348).MercatorTileSource),S(\"QUADKEYTileSource\",e(351).QUADKEYTileSource),S(\"TileRenderer\",e(352).TileRenderer),S(\"TileSource\",e(349).TileSource),S(\"TMSTileSource\",e(355).TMSTileSource),S(\"WMTSTileSource\",e(353).WMTSTileSource)},\n", - " function _(e,t,r,o,l){var i;o();const n=e(348);class s extends n.MercatorTileSource{constructor(e){super(e)}get_image_url(e,t,r){const o=this.string_lookup_replace(this.url,this.extra_url_vars);let l,i,n,s;return this.use_latlon?[i,s,l,n]=this.get_tile_geographic_bounds(e,t,r):[i,s,l,n]=this.get_tile_meter_bounds(e,t,r),o.replace(\"{XMIN}\",i.toString()).replace(\"{YMIN}\",s.toString()).replace(\"{XMAX}\",l.toString()).replace(\"{YMAX}\",n.toString())}}r.BBoxTileSource=s,i=s,s.__name__=\"BBoxTileSource\",i.define((({Boolean:e})=>({use_latlon:[e,!1]})))},\n", - " function _(t,e,i,_,s){var r;_();const o=t(349),n=t(9),l=t(350);class u extends o.TileSource{constructor(t){super(t)}initialize(){super.initialize(),this._resolutions=(0,n.range)(this.min_zoom,this.max_zoom+1).map((t=>this.get_resolution(t)))}_computed_initial_resolution(){return null!=this.initial_resolution?this.initial_resolution:2*Math.PI*6378137/this.tile_size}is_valid_tile(t,e,i){return!(!this.wrap_around&&(t<0||t>=2**i))&&!(e<0||e>=2**i)}parent_by_tile_xyz(t,e,i){const _=this.tile_xyz_to_quadkey(t,e,i),s=_.substring(0,_.length-1);return this.quadkey_to_tile_xyz(s)}get_resolution(t){return this._computed_initial_resolution()/2**t}get_resolution_by_extent(t,e,i){return[(t[2]-t[0])/i,(t[3]-t[1])/e]}get_level_by_extent(t,e,i){const _=(t[2]-t[0])/i,s=(t[3]-t[1])/e,r=Math.max(_,s);let o=0;for(const t of this._resolutions){if(r>t){if(0==o)return 0;if(o>0)return o-1}o+=1}return o-1}get_closest_level_by_extent(t,e,i){const _=(t[2]-t[0])/i,s=(t[3]-t[1])/e,r=Math.max(_,s),o=this._resolutions.reduce((function(t,e){return Math.abs(e-r)e?(u=o-s,a*=t):(u*=e,a=n-r)}const h=(u-(o-s))/2,c=(a-(n-r))/2;return[s-h,r-c,o+h,n+c]}tms_to_wmts(t,e,i){return[t,2**i-1-e,i]}wmts_to_tms(t,e,i){return[t,2**i-1-e,i]}pixels_to_meters(t,e,i){const _=this.get_resolution(i);return[t*_-this.x_origin_offset,e*_-this.y_origin_offset]}meters_to_pixels(t,e,i){const _=this.get_resolution(i);return[(t+this.x_origin_offset)/_,(e+this.y_origin_offset)/_]}pixels_to_tile(t,e){let i=Math.ceil(t/this.tile_size);i=0===i?i:i-1;return[i,Math.max(Math.ceil(e/this.tile_size)-1,0)]}pixels_to_raster(t,e,i){return[t,(this.tile_size<=l;t--)for(let i=n;i<=u;i++)this.is_valid_tile(i,t,e)&&h.push([i,t,e,this.get_tile_meter_bounds(i,t,e)]);return this.sort_tiles_from_center(h,[n,l,u,a]),h}quadkey_to_tile_xyz(t){let e=0,i=0;const _=t.length;for(let s=_;s>0;s--){const r=1<0;s--){const i=1<0;)if(s=s.substring(0,s.length-1),[t,e,i]=this.quadkey_to_tile_xyz(s),[t,e,i]=this.denormalize_xyz(t,e,i,_),this.tiles.has(this.tile_xyz_to_key(t,e,i)))return[t,e,i];return[0,0,0]}normalize_xyz(t,e,i){if(this.wrap_around){const _=2**i;return[(t%_+_)%_,e,i]}return[t,e,i]}denormalize_xyz(t,e,i,_){return[t+_*2**i,e,i]}denormalize_meters(t,e,i,_){return[t+2*_*Math.PI*6378137,e]}calculate_world_x_by_tile_xyz(t,e,i){return Math.floor(t/2**i)}}i.MercatorTileSource=u,r=u,u.__name__=\"MercatorTileSource\",r.define((({Boolean:t})=>({snap_to_zoom:[t,!1],wrap_around:[t,!0]}))),r.override({x_origin_offset:20037508.34,y_origin_offset:20037508.34,initial_resolution:156543.03392804097})},\n", - " function _(e,t,r,i,n){var l;i();const a=e(53),s=e(13);class c extends a.Model{constructor(e){super(e)}initialize(){super.initialize(),this.tiles=new Map,this._normalize_case()}connect_signals(){super.connect_signals(),this.connect(this.change,(()=>this._clear_cache()))}string_lookup_replace(e,t){let r=e;for(const[e,i]of(0,s.entries)(t))r=r.replace(`{${e}}`,i);return r}_normalize_case(){const e=this.url.replace(\"{x}\",\"{X}\").replace(\"{y}\",\"{Y}\").replace(\"{z}\",\"{Z}\").replace(\"{q}\",\"{Q}\").replace(\"{xmin}\",\"{XMIN}\").replace(\"{ymin}\",\"{YMIN}\").replace(\"{xmax}\",\"{XMAX}\").replace(\"{ymax}\",\"{YMAX}\");this.url=e}_clear_cache(){this.tiles=new Map}tile_xyz_to_key(e,t,r){return`${e}:${t}:${r}`}key_to_tile_xyz(e){const[t,r,i]=e.split(\":\").map((e=>parseInt(e)));return[t,r,i]}sort_tiles_from_center(e,t){const[r,i,n,l]=t,a=(n-r)/2+r,s=(l-i)/2+i;e.sort((function(e,t){return Math.sqrt((a-e[0])**2+(s-e[1])**2)-Math.sqrt((a-t[0])**2+(s-t[1])**2)}))}get_image_url(e,t,r){return this.string_lookup_replace(this.url,this.extra_url_vars).replace(\"{X}\",e.toString()).replace(\"{Y}\",t.toString()).replace(\"{Z}\",r.toString())}}r.TileSource=c,l=c,c.__name__=\"TileSource\",l.define((({Number:e,String:t,Dict:r,Nullable:i})=>({url:[t,\"\"],tile_size:[e,256],max_zoom:[e,30],min_zoom:[e,0],extra_url_vars:[r(t),{}],attribution:[t,\"\"],x_origin_offset:[e],y_origin_offset:[e],initial_resolution:[i(e),null]})))},\n", - " function _(t,e,r,n,o){n();const c=t(78);function _(t,e){return c.wgs84_mercator.compute(t,e)}function g(t,e){return c.wgs84_mercator.invert(t,e)}r.geographic_to_meters=_,r.meters_to_geographic=g,r.geographic_extent_to_meters=function(t){const[e,r,n,o]=t,[c,g]=_(e,r),[i,u]=_(n,o);return[c,g,i,u]},r.meters_extent_to_geographic=function(t){const[e,r,n,o]=t,[c,_]=g(e,r),[i,u]=g(n,o);return[c,_,i,u]}},\n", - " function _(e,t,r,s,_){s();const o=e(348);class c extends o.MercatorTileSource{constructor(e){super(e)}get_image_url(e,t,r){const s=this.string_lookup_replace(this.url,this.extra_url_vars),[_,o,c]=this.tms_to_wmts(e,t,r),i=this.tile_xyz_to_quadkey(_,o,c);return s.replace(\"{Q}\",i)}}r.QUADKEYTileSource=c,c.__name__=\"QUADKEYTileSource\"},\n", - " function _(t,e,i,s,_){s();const n=t(1);var a;const o=t(349),r=t(353),h=t(41),l=t(58),d=t(43),m=t(136),c=t(9),u=t(8),p=(0,n.__importStar)(t(354));class g extends h.RendererView{initialize(){this._tiles=[],super.initialize()}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.request_render())),this.connect(this.model.tile_source.change,(()=>this.request_render()))}remove(){null!=this.attribution_el&&(0,d.removeElement)(this.attribution_el),super.remove()}styles(){return[...super.styles(),p.default]}get_extent(){return[this.x_range.start,this.y_range.start,this.x_range.end,this.y_range.end]}get map_plot(){return this.plot_model}get map_canvas(){return this.layer.ctx}get map_frame(){return this.plot_view.frame}get x_range(){return this.map_plot.x_range}get y_range(){return this.map_plot.y_range}_set_data(){this.extent=this.get_extent(),this._last_height=void 0,this._last_width=void 0}_update_attribution(){null!=this.attribution_el&&(0,d.removeElement)(this.attribution_el);const{attribution:t}=this.model.tile_source;if((0,u.isString)(t)&&t.length>0){const{layout:e,frame:i}=this.plot_view,s=e.bbox.width-i.bbox.right,_=e.bbox.height-i.bbox.bottom,n=i.bbox.width;this.attribution_el=(0,d.div)({class:p.tile_attribution,style:{position:\"absolute\",right:`${s}px`,bottom:`${_}px`,\"max-width\":n-4+\"px\",padding:\"2px\",\"background-color\":\"rgba(255,255,255,0.5)\",\"font-size\":\"9px\",\"line-height\":\"1.05\",\"white-space\":\"nowrap\",overflow:\"hidden\",\"text-overflow\":\"ellipsis\"}}),this.plot_view.canvas_view.add_event(this.attribution_el),this.attribution_el.innerHTML=t,this.attribution_el.title=this.attribution_el.textContent.replace(/\\s*\\n\\s*/g,\" \")}}_map_data(){this.initial_extent=this.get_extent();const t=this.model.tile_source.get_level_by_extent(this.initial_extent,this.map_frame.bbox.height,this.map_frame.bbox.width),e=this.model.tile_source.snap_to_zoom_level(this.initial_extent,this.map_frame.bbox.height,this.map_frame.bbox.width,t);this.x_range.start=e[0],this.y_range.start=e[1],this.x_range.end=e[2],this.y_range.end=e[3],this.x_range instanceof l.Range1d&&(this.x_range.reset_start=e[0],this.x_range.reset_end=e[2]),this.y_range instanceof l.Range1d&&(this.y_range.reset_start=e[1],this.y_range.reset_end=e[3]),this._update_attribution()}_create_tile(t,e,i,s,_=!1){const n=this.model.tile_source.tile_xyz_to_quadkey(t,e,i),a=this.model.tile_source.tile_xyz_to_key(t,e,i);if(this.model.tile_source.tiles.has(a))return;const[o,r,h]=this.model.tile_source.normalize_xyz(t,e,i),l=this.model.tile_source.get_image_url(o,r,h),d={img:void 0,tile_coords:[t,e,i],normalized_coords:[o,r,h],quadkey:n,cache_key:a,bounds:s,loaded:!1,finished:!1,x_coord:s[0],y_coord:s[3]};this.model.tile_source.tiles.set(a,d),this._tiles.push(d),new m.ImageLoader(l,{loaded:t=>{Object.assign(d,{img:t,loaded:!0}),_?(d.finished=!0,this.notify_finished()):this.request_render()},failed(){d.finished=!0}})}_enforce_aspect_ratio(){if(this._last_height!==this.map_frame.bbox.height||this._last_width!==this.map_frame.bbox.width){const t=this.get_extent(),e=this.model.tile_source.get_level_by_extent(t,this.map_frame.bbox.height,this.map_frame.bbox.width),i=this.model.tile_source.snap_to_zoom_level(t,this.map_frame.bbox.height,this.map_frame.bbox.width,e);this.x_range.setv({start:i[0],end:i[2]}),this.y_range.setv({start:i[1],end:i[3]}),this.extent=i,this._last_height=this.map_frame.bbox.height,this._last_width=this.map_frame.bbox.width}}has_finished(){if(!super.has_finished())return!1;if(0==this._tiles.length)return!1;for(const t of this._tiles)if(!t.finished)return!1;return!0}_render(){null==this.map_initialized&&(this._set_data(),this._map_data(),this.map_initialized=!0),this._enforce_aspect_ratio(),this._update(),null!=this.prefetch_timer&&clearTimeout(this.prefetch_timer),this.prefetch_timer=setTimeout(this._prefetch_tiles.bind(this),500),this.has_finished()&&this.notify_finished()}_draw_tile(t){const e=this.model.tile_source.tiles.get(t);if(null!=e&&e.loaded){const[[t],[i]]=this.coordinates.map_to_screen([e.bounds[0]],[e.bounds[3]]),[[s],[_]]=this.coordinates.map_to_screen([e.bounds[2]],[e.bounds[1]]),n=s-t,a=_-i,o=t,r=i,h=this.map_canvas.getImageSmoothingEnabled();this.map_canvas.setImageSmoothingEnabled(this.model.smoothing),this.map_canvas.drawImage(e.img,o,r,n,a),this.map_canvas.setImageSmoothingEnabled(h),e.finished=!0}}_set_rect(){const t=this.plot_model.outline_line_width,e=this.map_frame.bbox.left+t/2,i=this.map_frame.bbox.top+t/2,s=this.map_frame.bbox.width-t,_=this.map_frame.bbox.height-t;this.map_canvas.rect(e,i,s,_),this.map_canvas.clip()}_render_tiles(t){this.map_canvas.save(),this._set_rect(),this.map_canvas.globalAlpha=this.model.alpha;for(const e of t)this._draw_tile(e);this.map_canvas.restore()}_prefetch_tiles(){const{tile_source:t}=this.model,e=this.get_extent(),i=this.map_frame.bbox.height,s=this.map_frame.bbox.width,_=this.model.tile_source.get_level_by_extent(e,i,s),n=this.model.tile_source.get_tiles_by_extent(e,_);for(let e=0,i=Math.min(10,n.length);ei&&(s=this.extent,o=i,r=!0),r&&(this.x_range.setv({start:s[0],end:s[2]}),this.y_range.setv({start:s[1],end:s[3]})),this.extent=s;const h=t.get_tiles_by_extent(s,o),l=[],d=[],m=[],u=[];for(const e of h){const[i,s,n]=e,a=t.tile_xyz_to_key(i,s,n),o=t.tiles.get(a);if(null!=o&&o.loaded)d.push(a);else if(this.model.render_parents){const[e,a,o]=t.get_closest_parent_by_tile_xyz(i,s,n),r=t.tile_xyz_to_key(e,a,o),h=t.tiles.get(r);if(null!=h&&h.loaded&&!(0,c.includes)(m,r)&&m.push(r),_){const e=t.children_by_tile_xyz(i,s,n);for(const[i,s,_]of e){const e=t.tile_xyz_to_key(i,s,_);t.tiles.has(e)&&u.push(e)}}}null==o&&l.push(e)}this._render_tiles(m),this._render_tiles(u),this._render_tiles(d),null!=this.render_timer&&clearTimeout(this.render_timer),this.render_timer=setTimeout((()=>this._fetch_tiles(l)),65)}}i.TileRendererView=g,g.__name__=\"TileRendererView\";class b extends h.Renderer{constructor(t){super(t)}}i.TileRenderer=b,a=b,b.__name__=\"TileRenderer\",a.prototype.default_view=g,a.define((({Boolean:t,Number:e,Ref:i})=>({alpha:[e,1],smoothing:[t,!0],tile_source:[i(o.TileSource),()=>new r.WMTSTileSource],render_parents:[t,!0]}))),a.override({level:\"image\"})},\n", - " function _(t,e,r,o,s){o();const c=t(348);class i extends c.MercatorTileSource{constructor(t){super(t)}get_image_url(t,e,r){const o=this.string_lookup_replace(this.url,this.extra_url_vars),[s,c,i]=this.tms_to_wmts(t,e,r);return o.replace(\"{X}\",s.toString()).replace(\"{Y}\",c.toString()).replace(\"{Z}\",i.toString())}}r.WMTSTileSource=i,i.__name__=\"WMTSTileSource\"},\n", - " function _(t,o,i,b,r){b(),i.root=\"bk-root\",i.tile_attribution=\"bk-tile-attribution\",i.default=\".bk-root .bk-tile-attribution a{color:black;}\"},\n", - " function _(e,r,t,c,o){c();const i=e(348);class l extends i.MercatorTileSource{constructor(e){super(e)}get_image_url(e,r,t){return this.string_lookup_replace(this.url,this.extra_url_vars).replace(\"{X}\",e.toString()).replace(\"{Y}\",r.toString()).replace(\"{Z}\",t.toString())}}t.TMSTileSource=l,l.__name__=\"TMSTileSource\"},\n", - " function _(e,t,u,a,r){a(),r(\"CanvasTexture\",e(357).CanvasTexture),r(\"ImageURLTexture\",e(359).ImageURLTexture),r(\"Texture\",e(358).Texture)},\n", - " function _(t,e,n,c,s){var r;c();const o=t(358),a=t(34);class u extends o.Texture{constructor(t){super(t)}get func(){const t=(0,a.use_strict)(this.code);return new Function(\"ctx\",\"color\",\"scale\",\"weight\",t)}get_pattern(t,e,n){const c=document.createElement(\"canvas\");c.width=e,c.height=e;const s=c.getContext(\"2d\");return this.func.call(this,s,t,e,n),c}}n.CanvasTexture=u,r=u,u.__name__=\"CanvasTexture\",r.define((({String:t})=>({code:[t]})))},\n", - " function _(e,t,n,r,o){var i;r();const s=e(53),u=e(20);class c extends s.Model{constructor(e){super(e)}}n.Texture=c,i=c,c.__name__=\"Texture\",i.define((()=>({repetition:[u.TextureRepetition,\"repeat\"]})))},\n", - " function _(e,t,i,r,n){var a;r();const s=e(358),o=e(136);class u extends s.Texture{constructor(e){super(e)}initialize(){super.initialize(),this._loader=new o.ImageLoader(this.url)}get_pattern(e,t,i){const{_loader:r}=this;return this._loader.finished?r.image:r.promise}}i.ImageURLTexture=u,a=u,u.__name__=\"ImageURLTexture\",a.define((({String:e})=>({url:[e]})))},\n", - " function _(o,l,T,e,t){e(),t(\"ActionTool\",o(238).ActionTool),t(\"CustomAction\",o(361).CustomAction),t(\"HelpTool\",o(239).HelpTool),t(\"RedoTool\",o(362).RedoTool),t(\"ResetTool\",o(363).ResetTool),t(\"SaveTool\",o(364).SaveTool),t(\"UndoTool\",o(365).UndoTool),t(\"ZoomInTool\",o(366).ZoomInTool),t(\"ZoomOutTool\",o(369).ZoomOutTool),t(\"ButtonTool\",o(224).ButtonTool),t(\"EditTool\",o(370).EditTool),t(\"BoxEditTool\",o(371).BoxEditTool),t(\"FreehandDrawTool\",o(372).FreehandDrawTool),t(\"PointDrawTool\",o(373).PointDrawTool),t(\"PolyDrawTool\",o(374).PolyDrawTool),t(\"PolyTool\",o(375).PolyTool),t(\"PolyEditTool\",o(376).PolyEditTool),t(\"BoxSelectTool\",o(377).BoxSelectTool),t(\"BoxZoomTool\",o(379).BoxZoomTool),t(\"GestureTool\",o(223).GestureTool),t(\"LassoSelectTool\",o(380).LassoSelectTool),t(\"LineEditTool\",o(382).LineEditTool),t(\"PanTool\",o(384).PanTool),t(\"PolySelectTool\",o(381).PolySelectTool),t(\"RangeTool\",o(385).RangeTool),t(\"SelectTool\",o(378).SelectTool),t(\"TapTool\",o(386).TapTool),t(\"WheelPanTool\",o(387).WheelPanTool),t(\"WheelZoomTool\",o(388).WheelZoomTool),t(\"CrosshairTool\",o(389).CrosshairTool),t(\"CustomJSHover\",o(390).CustomJSHover),t(\"HoverTool\",o(391).HoverTool),t(\"InspectTool\",o(232).InspectTool),t(\"Tool\",o(222).Tool),t(\"ToolProxy\",o(394).ToolProxy),t(\"Toolbar\",o(221).Toolbar),t(\"ToolbarBase\",o(233).ToolbarBase),t(\"ProxyToolbar\",o(395).ProxyToolbar),t(\"ToolbarBox\",o(395).ToolbarBox)},\n", - " function _(t,o,e,s,n){var c;s();const i=t(238);class u extends i.ActionToolButtonView{css_classes(){return super.css_classes().concat(\"bk-toolbar-button-custom-action\")}}e.CustomActionButtonView=u,u.__name__=\"CustomActionButtonView\";class l extends i.ActionToolView{doit(){var t;null===(t=this.model.callback)||void 0===t||t.execute(this.model)}}e.CustomActionView=l,l.__name__=\"CustomActionView\";class a extends i.ActionTool{constructor(t){super(t),this.tool_name=\"Custom Action\",this.button_view=u}}e.CustomAction=a,c=a,a.__name__=\"CustomAction\",c.prototype.default_view=l,c.define((({Any:t,String:o,Nullable:e})=>({callback:[e(t)],icon:[o]}))),c.override({description:\"Perform a Custom Action\"})},\n", - " function _(e,o,t,i,s){var n;i();const l=e(238),_=e(228);class d extends l.ActionToolView{connect_signals(){super.connect_signals(),this.connect(this.plot_view.state.changed,(()=>this.model.disabled=!this.plot_view.state.can_redo))}doit(){const e=this.plot_view.state.redo();null!=(null==e?void 0:e.range)&&this.plot_view.trigger_ranges_update_event()}}t.RedoToolView=d,d.__name__=\"RedoToolView\";class a extends l.ActionTool{constructor(e){super(e),this.tool_name=\"Redo\",this.icon=_.tool_icon_redo}}t.RedoTool=a,n=a,a.__name__=\"RedoTool\",n.prototype.default_view=d,n.override({disabled:!0}),n.register_alias(\"redo\",(()=>new a))},\n", - " function _(e,o,t,s,i){var _;s();const n=e(238),l=e(228);class c extends n.ActionToolView{doit(){this.plot_view.reset()}}t.ResetToolView=c,c.__name__=\"ResetToolView\";class r extends n.ActionTool{constructor(e){super(e),this.tool_name=\"Reset\",this.icon=l.tool_icon_reset}}t.ResetTool=r,_=r,r.__name__=\"ResetTool\",_.prototype.default_view=c,_.register_alias(\"reset\",(()=>new r))},\n", - " function _(e,o,t,a,i){var s;a();const c=e(238),n=e(228);class l extends c.ActionToolView{async copy(){const e=await this.plot_view.to_blob(),o=new ClipboardItem({[e.type]:Promise.resolve(e)});await navigator.clipboard.write([o])}async save(e){const o=await this.plot_view.to_blob(),t=document.createElement(\"a\");t.href=URL.createObjectURL(o),t.download=e,t.target=\"_blank\",t.dispatchEvent(new MouseEvent(\"click\"))}doit(e=\"save\"){switch(e){case\"save\":this.save(\"bokeh_plot\");break;case\"copy\":this.copy()}}}t.SaveToolView=l,l.__name__=\"SaveToolView\";class r extends c.ActionTool{constructor(e){super(e),this.tool_name=\"Save\",this.icon=n.tool_icon_save}get menu(){return[{icon:\"bk-tool-icon-copy-to-clipboard\",tooltip:\"Copy image to clipboard\",if:()=>\"undefined\"!=typeof ClipboardItem,handler:()=>{this.do.emit(\"copy\")}}]}}t.SaveTool=r,s=r,r.__name__=\"SaveTool\",s.prototype.default_view=l,s.register_alias(\"save\",(()=>new r))},\n", - " function _(o,e,t,n,i){var s;n();const l=o(238),_=o(228);class d extends l.ActionToolView{connect_signals(){super.connect_signals(),this.connect(this.plot_view.state.changed,(()=>this.model.disabled=!this.plot_view.state.can_undo))}doit(){const o=this.plot_view.state.undo();null!=(null==o?void 0:o.range)&&this.plot_view.trigger_ranges_update_event()}}t.UndoToolView=d,d.__name__=\"UndoToolView\";class a extends l.ActionTool{constructor(o){super(o),this.tool_name=\"Undo\",this.icon=_.tool_icon_undo}}t.UndoTool=a,s=a,a.__name__=\"UndoTool\",s.prototype.default_view=d,s.override({disabled:!0}),s.register_alias(\"undo\",(()=>new a))},\n", - " function _(o,n,e,i,s){var t;i();const _=o(367),m=o(228);class a extends _.ZoomBaseToolView{}e.ZoomInToolView=a,a.__name__=\"ZoomInToolView\";class l extends _.ZoomBaseTool{constructor(o){super(o),this.sign=1,this.tool_name=\"Zoom In\",this.icon=m.tool_icon_zoom_in}}e.ZoomInTool=l,t=l,l.__name__=\"ZoomInTool\",t.prototype.default_view=a,t.register_alias(\"zoom_in\",(()=>new l({dimensions:\"both\"}))),t.register_alias(\"xzoom_in\",(()=>new l({dimensions:\"width\"}))),t.register_alias(\"yzoom_in\",(()=>new l({dimensions:\"height\"})))},\n", - " function _(o,t,e,i,s){var n;i();const a=o(238),_=o(20),l=o(368);class m extends a.ActionToolView{doit(){var o;const t=this.plot_view.frame,e=this.model.dimensions,i=\"width\"==e||\"both\"==e,s=\"height\"==e||\"both\"==e,n=(0,l.scale_range)(t,this.model.sign*this.model.factor,i,s);this.plot_view.state.push(\"zoom_out\",{range:n}),this.plot_view.update_range(n,{scrolling:!0,maintain_focus:this.model.maintain_focus}),null===(o=this.model.document)||void 0===o||o.interactive_start(this.plot_model),this.plot_view.trigger_ranges_update_event()}}e.ZoomBaseToolView=m,m.__name__=\"ZoomBaseToolView\";class h extends a.ActionTool{constructor(o){super(o),this.maintain_focus=!0}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}e.ZoomBaseTool=h,n=h,h.__name__=\"ZoomBaseTool\",n.define((({Percent:o})=>({factor:[o,.1],dimensions:[_.Dimensions,\"both\"]})))},\n", - " function _(n,t,o,r,s){r();const c=n(10);function e(n,t,o){const[r,s]=[n.start,n.end],c=null!=o?o:(s+r)/2;return[r-(r-c)*t,s-(s-c)*t]}function a(n,[t,o]){const r=new Map;for(const[s,c]of n){const[n,e]=c.r_invert(t,o);r.set(s,{start:n,end:e})}return r}o.scale_highlow=e,o.get_info=a,o.scale_range=function(n,t,o=!0,r=!0,s){t=(0,c.clamp)(t,-.9,.9);const l=o?t:0,[u,i]=e(n.bbox.h_range,l,null!=s?s.x:void 0),_=a(n.x_scales,[u,i]),f=r?t:0,[g,x]=e(n.bbox.v_range,f,null!=s?s.y:void 0);return{xrs:_,yrs:a(n.y_scales,[g,x]),factor:t}}},\n", - " function _(o,e,t,i,s){var n;i();const _=o(367),a=o(228);class m extends _.ZoomBaseToolView{}t.ZoomOutToolView=m,m.__name__=\"ZoomOutToolView\";class l extends _.ZoomBaseTool{constructor(o){super(o),this.sign=-1,this.tool_name=\"Zoom Out\",this.icon=a.tool_icon_zoom_out}}t.ZoomOutTool=l,n=l,l.__name__=\"ZoomOutTool\",n.prototype.default_view=m,n.define((({Boolean:o})=>({maintain_focus:[o,!0]}))),n.register_alias(\"zoom_out\",(()=>new l({dimensions:\"both\"}))),n.register_alias(\"xzoom_out\",(()=>new l({dimensions:\"width\"}))),n.register_alias(\"yzoom_out\",(()=>new l({dimensions:\"height\"})))},\n", - " function _(e,t,s,o,n){var r;o();const i=e(9),c=e(8),a=e(11),_=e(175),l=e(223);class d extends l.GestureToolView{constructor(){super(...arguments),this._mouse_in_frame=!0}_select_mode(e){const{shiftKey:t,ctrlKey:s}=e;return t||s?t&&!s?\"append\":!t&&s?\"intersect\":t&&s?\"subtract\":void(0,a.unreachable)():\"replace\"}_move_enter(e){this._mouse_in_frame=!0}_move_exit(e){this._mouse_in_frame=!1}_map_drag(e,t,s){if(!this.plot_view.frame.bbox.contains(e,t))return null;const o=this.plot_view.renderer_view(s);if(null==o)return null;return[o.coordinates.x_scale.invert(e),o.coordinates.y_scale.invert(t)]}_delete_selected(e){const t=e.data_source,s=t.selected.indices;s.sort();for(const e of t.columns()){const o=t.get_array(e);for(let e=0;e({custom_icon:[n(t),null],empty_value:[e],renderers:[s(o(_.GlyphRenderer)),[]]})))},\n", - " function _(e,t,s,i,_){var o;i();const n=e(43),a=e(20),d=e(370),l=e(228);class r extends d.EditToolView{_tap(e){null==this._draw_basepoint&&null==this._basepoint&&this._select_event(e,this._select_mode(e),this.model.renderers)}_keyup(e){if(this.model.active&&this._mouse_in_frame)for(const t of this.model.renderers)if(e.keyCode===n.Keys.Backspace)this._delete_selected(t);else if(e.keyCode==n.Keys.Esc){t.data_source.selection_manager.clear()}}_set_extent([e,t],[s,i],_,o=!1){const n=this.model.renderers[0],a=this.plot_view.renderer_view(n);if(null==a)return;const d=n.glyph,l=n.data_source,[r,h]=a.coordinates.x_scale.r_invert(e,t),[p,u]=a.coordinates.y_scale.r_invert(s,i),[c,m]=[(r+h)/2,(p+u)/2],[f,b]=[h-r,u-p],[y,x]=[d.x.field,d.y.field],[w,v]=[d.width.field,d.height.field];if(_)this._pop_glyphs(l,this.model.num_objects),y&&l.get_array(y).push(c),x&&l.get_array(x).push(m),w&&l.get_array(w).push(f),v&&l.get_array(v).push(b),this._pad_empty_columns(l,[y,x,w,v]);else{const e=l.data[y].length-1;y&&(l.data[y][e]=c),x&&(l.data[x][e]=m),w&&(l.data[w][e]=f),v&&(l.data[v][e]=b)}this._emit_cds_changes(l,!0,!1,o)}_update_box(e,t=!1,s=!1){if(null==this._draw_basepoint)return;const i=[e.sx,e.sy],_=this.plot_view.frame,o=this.model.dimensions,n=this.model._get_dim_limits(this._draw_basepoint,i,_,o);if(null!=n){const[e,i]=n;this._set_extent(e,i,t,s)}}_doubletap(e){this.model.active&&(null!=this._draw_basepoint?(this._update_box(e,!1,!0),this._draw_basepoint=null):(this._draw_basepoint=[e.sx,e.sy],this._select_event(e,\"append\",this.model.renderers),this._update_box(e,!0,!1)))}_move(e){this._update_box(e,!1,!1)}_pan_start(e){if(e.shiftKey){if(null!=this._draw_basepoint)return;this._draw_basepoint=[e.sx,e.sy],this._update_box(e,!0,!1)}else{if(null!=this._basepoint)return;this._select_event(e,\"append\",this.model.renderers),this._basepoint=[e.sx,e.sy]}}_pan(e,t=!1,s=!1){if(e.shiftKey){if(null==this._draw_basepoint)return;this._update_box(e,t,s)}else{if(null==this._basepoint)return;this._drag_points(e,this.model.renderers)}}_pan_end(e){if(this._pan(e,!1,!0),e.shiftKey)this._draw_basepoint=null;else{this._basepoint=null;for(const e of this.model.renderers)this._emit_cds_changes(e.data_source,!1,!0,!0)}}}s.BoxEditToolView=r,r.__name__=\"BoxEditToolView\";class h extends d.EditTool{constructor(e){super(e),this.tool_name=\"Box Edit Tool\",this.icon=l.tool_icon_box_edit,this.event_type=[\"tap\",\"pan\",\"move\"],this.default_order=1}}s.BoxEditTool=h,o=h,h.__name__=\"BoxEditTool\",o.prototype.default_view=r,o.define((({Int:e})=>({dimensions:[a.Dimensions,\"both\"],num_objects:[e,0]})))},\n", - " function _(e,t,a,s,r){var _;s();const d=e(43),o=e(8),n=e(370),i=e(228);class l extends n.EditToolView{_draw(e,t,a=!1){if(!this.model.active)return;const s=this.model.renderers[0],r=this._map_drag(e.sx,e.sy,s);if(null==r)return;const[_,d]=r,n=s.data_source,i=s.glyph,[l,h]=[i.xs.field,i.ys.field];if(\"new\"==t)this._pop_glyphs(n,this.model.num_objects),l&&n.get_array(l).push([_]),h&&n.get_array(h).push([d]),this._pad_empty_columns(n,[l,h]);else if(\"add\"==t){if(l){const e=n.data[l].length-1;let t=n.get_array(l)[e];(0,o.isArray)(t)||(t=Array.from(t),n.data[l][e]=t),t.push(_)}if(h){const e=n.data[h].length-1;let t=n.get_array(h)[e];(0,o.isArray)(t)||(t=Array.from(t),n.data[h][e]=t),t.push(d)}}this._emit_cds_changes(n,!0,!0,a)}_pan_start(e){this._draw(e,\"new\")}_pan(e){this._draw(e,\"add\")}_pan_end(e){this._draw(e,\"add\",!0)}_tap(e){this._select_event(e,this._select_mode(e),this.model.renderers)}_keyup(e){if(this.model.active&&this._mouse_in_frame)for(const t of this.model.renderers)e.keyCode===d.Keys.Esc?t.data_source.selection_manager.clear():e.keyCode===d.Keys.Backspace&&this._delete_selected(t)}}a.FreehandDrawToolView=l,l.__name__=\"FreehandDrawToolView\";class h extends n.EditTool{constructor(e){super(e),this.tool_name=\"Freehand Draw Tool\",this.icon=i.tool_icon_freehand_draw,this.event_type=[\"pan\",\"tap\"],this.default_order=3}}a.FreehandDrawTool=h,_=h,h.__name__=\"FreehandDrawTool\",_.prototype.default_view=l,_.define((({Int:e})=>({num_objects:[e,0]}))),_.register_alias(\"freehand_draw\",(()=>new h))},\n", - " function _(e,t,s,o,a){var i;o();const n=e(43),_=e(370),r=e(228);class d extends _.EditToolView{_tap(e){if(this._select_event(e,this._select_mode(e),this.model.renderers).length||!this.model.add)return;const t=this.model.renderers[0],s=this._map_drag(e.sx,e.sy,t);if(null==s)return;const o=t.glyph,a=t.data_source,[i,n]=[o.x.field,o.y.field],[_,r]=s;this._pop_glyphs(a,this.model.num_objects),i&&a.get_array(i).push(_),n&&a.get_array(n).push(r),this._pad_empty_columns(a,[i,n]),a.change.emit(),a.data=a.data,a.properties.data.change.emit()}_keyup(e){if(this.model.active&&this._mouse_in_frame)for(const t of this.model.renderers)e.keyCode===n.Keys.Backspace?this._delete_selected(t):e.keyCode==n.Keys.Esc&&t.data_source.selection_manager.clear()}_pan_start(e){this.model.drag&&(this._select_event(e,\"append\",this.model.renderers),this._basepoint=[e.sx,e.sy])}_pan(e){this.model.drag&&null!=this._basepoint&&this._drag_points(e,this.model.renderers)}_pan_end(e){if(this.model.drag){this._pan(e);for(const e of this.model.renderers)this._emit_cds_changes(e.data_source,!1,!0,!0);this._basepoint=null}}}s.PointDrawToolView=d,d.__name__=\"PointDrawToolView\";class l extends _.EditTool{constructor(e){super(e),this.tool_name=\"Point Draw Tool\",this.icon=r.tool_icon_point_draw,this.event_type=[\"tap\",\"pan\",\"move\"],this.default_order=2}}s.PointDrawTool=l,i=l,l.__name__=\"PointDrawTool\",i.prototype.default_view=d,i.define((({Boolean:e,Int:t})=>({add:[e,!0],drag:[e,!0],num_objects:[t,0]})))},\n", - " function _(e,t,s,i,a){var r;i();const o=e(43),n=e(8),d=e(375),_=e(228);class h extends d.PolyToolView{constructor(){super(...arguments),this._drawing=!1,this._initialized=!1}_tap(e){this._drawing?this._draw(e,\"add\",!0):this._select_event(e,this._select_mode(e),this.model.renderers)}_draw(e,t,s=!1){const i=this.model.renderers[0],a=this._map_drag(e.sx,e.sy,i);if(this._initialized||this.activate(),null==a)return;const[r,o]=this._snap_to_vertex(e,...a),d=i.data_source,_=i.glyph,[h,l]=[_.xs.field,_.ys.field];if(\"new\"==t)this._pop_glyphs(d,this.model.num_objects),h&&d.get_array(h).push([r,r]),l&&d.get_array(l).push([o,o]),this._pad_empty_columns(d,[h,l]);else if(\"edit\"==t){if(h){const e=d.data[h][d.data[h].length-1];e[e.length-1]=r}if(l){const e=d.data[l][d.data[l].length-1];e[e.length-1]=o}}else if(\"add\"==t){if(h){const e=d.data[h].length-1;let t=d.get_array(h)[e];const s=t[t.length-1];t[t.length-1]=r,(0,n.isArray)(t)||(t=Array.from(t),d.data[h][e]=t),t.push(s)}if(l){const e=d.data[l].length-1;let t=d.get_array(l)[e];const s=t[t.length-1];t[t.length-1]=o,(0,n.isArray)(t)||(t=Array.from(t),d.data[l][e]=t),t.push(s)}}this._emit_cds_changes(d,!0,!1,s)}_show_vertices(){if(!this.model.active)return;const e=[],t=[];for(let s=0;sthis._show_vertices()))}this._initialized=!0}}deactivate(){this._drawing&&(this._remove(),this._drawing=!1),this.model.vertex_renderer&&this._hide_vertices()}}s.PolyDrawToolView=h,h.__name__=\"PolyDrawToolView\";class l extends d.PolyTool{constructor(e){super(e),this.tool_name=\"Polygon Draw Tool\",this.icon=_.tool_icon_poly_draw,this.event_type=[\"pan\",\"tap\",\"move\"],this.default_order=3}}s.PolyDrawTool=l,r=l,l.__name__=\"PolyDrawTool\",r.prototype.default_view=h,r.define((({Boolean:e,Int:t})=>({drag:[e,!0],num_objects:[t,0]})))},\n", - " function _(e,r,t,s,o){var _;s();const d=e(8),i=e(370);class l extends i.EditToolView{_set_vertices(e,r){const t=this.model.vertex_renderer.glyph,s=this.model.vertex_renderer.data_source,[o,_]=[t.x.field,t.y.field];o&&((0,d.isArray)(e)?s.data[o]=e:t.x={value:e}),_&&((0,d.isArray)(r)?s.data[_]=r:t.y={value:r}),this._emit_cds_changes(s,!0,!0,!1)}_hide_vertices(){this._set_vertices([],[])}_snap_to_vertex(e,r,t){if(this.model.vertex_renderer){const s=this._select_event(e,\"replace\",[this.model.vertex_renderer]),o=this.model.vertex_renderer.data_source,_=this.model.vertex_renderer.glyph,[d,i]=[_.x.field,_.y.field];if(s.length){const e=o.selected.indices[0];d&&(r=o.data[d][e]),i&&(t=o.data[i][e]),o.selection_manager.clear()}}return[r,t]}}t.PolyToolView=l,l.__name__=\"PolyToolView\";class n extends i.EditTool{constructor(e){super(e)}}t.PolyTool=n,_=n,n.__name__=\"PolyTool\",_.define((({AnyRef:e})=>({vertex_renderer:[e()]})))},\n", - " function _(e,t,s,r,i){var _;r();const d=e(43),n=e(8),l=e(375),a=e(228);class c extends l.PolyToolView{constructor(){super(...arguments),this._drawing=!1,this._cur_index=null}_doubletap(e){if(!this.model.active)return;const t=this._map_drag(e.sx,e.sy,this.model.vertex_renderer);if(null==t)return;const[s,r]=t,i=this._select_event(e,\"replace\",[this.model.vertex_renderer]),_=this.model.vertex_renderer.data_source,d=this.model.vertex_renderer.glyph,[n,l]=[d.x.field,d.y.field];if(i.length&&null!=this._selected_renderer){const e=_.selected.indices[0];this._drawing?(this._drawing=!1,_.selection_manager.clear()):(_.selected.indices=[e+1],n&&_.get_array(n).splice(e+1,0,s),l&&_.get_array(l).splice(e+1,0,r),this._drawing=!0),_.change.emit(),this._emit_cds_changes(this._selected_renderer.data_source)}else this._show_vertices(e)}_show_vertices(e){if(!this.model.active)return;const t=this.model.renderers[0],s=()=>this._update_vertices(t),r=null==t?void 0:t.data_source,i=this._select_event(e,\"replace\",this.model.renderers);if(!i.length)return this._set_vertices([],[]),this._selected_renderer=null,this._drawing=!1,this._cur_index=null,void(null!=r&&r.disconnect(r.properties.data.change,s));null!=r&&r.connect(r.properties.data.change,s),this._cur_index=i[0].data_source.selected.indices[0],this._update_vertices(i[0])}_update_vertices(e){const t=e.glyph,s=e.data_source,r=this._cur_index,[i,_]=[t.xs.field,t.ys.field];if(this._drawing)return;if(null==r&&(i||_))return;let d,l;i&&null!=r?(d=s.data[i][r],(0,n.isArray)(d)||(s.data[i][r]=d=Array.from(d))):d=t.xs.value,_&&null!=r?(l=s.data[_][r],(0,n.isArray)(l)||(s.data[_][r]=l=Array.from(l))):l=t.ys.value,this._selected_renderer=e,this._set_vertices(d,l)}_move(e){if(this._drawing&&null!=this._selected_renderer){const t=this.model.vertex_renderer,s=t.data_source,r=t.glyph,i=this._map_drag(e.sx,e.sy,t);if(null==i)return;let[_,d]=i;const n=s.selected.indices;[_,d]=this._snap_to_vertex(e,_,d),s.selected.indices=n;const[l,a]=[r.x.field,r.y.field],c=n[0];l&&(s.data[l][c]=_),a&&(s.data[a][c]=d),s.change.emit(),this._selected_renderer.data_source.change.emit()}}_tap(e){const t=this.model.vertex_renderer,s=this._map_drag(e.sx,e.sy,t);if(null==s)return;if(this._drawing&&this._selected_renderer){let[r,i]=s;const _=t.data_source,d=t.glyph,[n,l]=[d.x.field,d.y.field],a=_.selected.indices;[r,i]=this._snap_to_vertex(e,r,i);const c=a[0];if(_.selected.indices=[c+1],n){const e=_.get_array(n),t=e[c];e[c]=r,e.splice(c+1,0,t)}if(l){const e=_.get_array(l),t=e[c];e[c]=i,e.splice(c+1,0,t)}return _.change.emit(),void this._emit_cds_changes(this._selected_renderer.data_source,!0,!1,!0)}const r=this._select_mode(e);this._select_event(e,r,[t]),this._select_event(e,r,this.model.renderers)}_remove_vertex(){if(!this._drawing||!this._selected_renderer)return;const e=this.model.vertex_renderer,t=e.data_source,s=e.glyph,r=t.selected.indices[0],[i,_]=[s.x.field,s.y.field];i&&t.get_array(i).splice(r,1),_&&t.get_array(_).splice(r,1),t.change.emit(),this._emit_cds_changes(this._selected_renderer.data_source)}_pan_start(e){this._select_event(e,\"append\",[this.model.vertex_renderer]),this._basepoint=[e.sx,e.sy]}_pan(e){null!=this._basepoint&&(this._drag_points(e,[this.model.vertex_renderer]),this._selected_renderer&&this._selected_renderer.data_source.change.emit())}_pan_end(e){null!=this._basepoint&&(this._drag_points(e,[this.model.vertex_renderer]),this._emit_cds_changes(this.model.vertex_renderer.data_source,!1,!0,!0),this._selected_renderer&&this._emit_cds_changes(this._selected_renderer.data_source),this._basepoint=null)}_keyup(e){if(!this.model.active||!this._mouse_in_frame)return;let t;t=this._selected_renderer?[this.model.vertex_renderer]:this.model.renderers;for(const s of t)e.keyCode===d.Keys.Backspace?(this._delete_selected(s),this._selected_renderer&&this._emit_cds_changes(this._selected_renderer.data_source)):e.keyCode==d.Keys.Esc&&(this._drawing?(this._remove_vertex(),this._drawing=!1):this._selected_renderer&&this._hide_vertices(),s.data_source.selection_manager.clear())}deactivate(){this._selected_renderer&&(this._drawing&&(this._remove_vertex(),this._drawing=!1),this._hide_vertices())}}s.PolyEditToolView=c,c.__name__=\"PolyEditToolView\";class o extends l.PolyTool{constructor(e){super(e),this.tool_name=\"Poly Edit Tool\",this.icon=a.tool_icon_poly_edit,this.event_type=[\"tap\",\"pan\",\"move\"],this.default_order=4}}s.PolyEditTool=o,_=o,o.__name__=\"PolyEditTool\",_.prototype.default_view=c},\n", - " function _(e,t,o,s,i){var l;s();const n=e(378),_=e(116),c=e(20),r=e(228);class a extends n.SelectToolView{_compute_limits(e){const t=this.plot_view.frame,o=this.model.dimensions;let s=this._base_point;if(\"center\"==this.model.origin){const[t,o]=s,[i,l]=e;s=[t-(i-t),o-(l-o)]}return this.model._get_dim_limits(s,e,t,o)}_pan_start(e){const{sx:t,sy:o}=e;this._base_point=[t,o]}_pan(e){const{sx:t,sy:o}=e,s=[t,o],[i,l]=this._compute_limits(s);this.model.overlay.update({left:i[0],right:i[1],top:l[0],bottom:l[1]}),this.model.select_every_mousemove&&this._do_select(i,l,!1,this._select_mode(e))}_pan_end(e){const{sx:t,sy:o}=e,s=[t,o],[i,l]=this._compute_limits(s);this._do_select(i,l,!0,this._select_mode(e)),this.model.overlay.update({left:null,right:null,top:null,bottom:null}),this._base_point=null,this.plot_view.state.push(\"box_select\",{selection:this.plot_view.get_selection()})}_do_select([e,t],[o,s],i,l=\"replace\"){const n={type:\"rect\",sx0:e,sx1:t,sy0:o,sy1:s};this._select(n,i,l)}}o.BoxSelectToolView=a,a.__name__=\"BoxSelectToolView\";const h=()=>new _.BoxAnnotation({level:\"overlay\",top_units:\"screen\",left_units:\"screen\",bottom_units:\"screen\",right_units:\"screen\",fill_color:\"lightgrey\",fill_alpha:.5,line_color:\"black\",line_alpha:1,line_width:2,line_dash:[4,4]});class m extends n.SelectTool{constructor(e){super(e),this.tool_name=\"Box Select\",this.icon=r.tool_icon_box_select,this.event_type=\"pan\",this.default_order=30}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}o.BoxSelectTool=m,l=m,m.__name__=\"BoxSelectTool\",l.prototype.default_view=a,l.define((({Boolean:e,Ref:t})=>({dimensions:[c.Dimensions,\"both\"],select_every_mousemove:[e,!1],overlay:[t(_.BoxAnnotation),h],origin:[c.BoxOrigin,\"corner\"]}))),l.register_alias(\"box_select\",(()=>new m)),l.register_alias(\"xbox_select\",(()=>new m({dimensions:\"width\"}))),l.register_alias(\"ybox_select\",(()=>new m({dimensions:\"height\"})))},\n", - " function _(e,t,s,n,r){var o;n();const c=e(223),i=e(175),a=e(339),l=e(176),d=e(66),_=e(20),h=e(43),p=e(251),u=e(15),m=e(11);class v extends c.GestureToolView{connect_signals(){super.connect_signals(),this.model.clear.connect((()=>this._clear()))}get computed_renderers(){const{renderers:e,names:t}=this.model,s=this.plot_model.data_renderers;return(0,d.compute_renderers)(e,s,t)}_computed_renderers_by_data_source(){var e;const t=new Map;for(const s of this.computed_renderers){let n;if(s instanceof i.GlyphRenderer)n=s.data_source;else{if(!(s instanceof a.GraphRenderer))continue;n=s.node_renderer.data_source}const r=null!==(e=t.get(n))&&void 0!==e?e:[];t.set(n,[...r,s])}return t}_select_mode(e){const{shiftKey:t,ctrlKey:s}=e;return t||s?t&&!s?\"append\":!t&&s?\"intersect\":t&&s?\"subtract\":void(0,m.unreachable)():this.model.mode}_keyup(e){e.keyCode==h.Keys.Esc&&this._clear()}_clear(){for(const e of this.computed_renderers)e.get_selection_manager().clear();const e=this.computed_renderers.map((e=>this.plot_view.renderer_view(e)));this.plot_view.request_paint(e)}_select(e,t,s){const n=this._computed_renderers_by_data_source();for(const[,r]of n){const n=r[0].get_selection_manager(),o=[];for(const e of r){const t=this.plot_view.renderer_view(e);null!=t&&o.push(t)}n.select(o,e,t,s)}null!=this.model.callback&&this._emit_callback(e),this._emit_selection_event(e,t)}_emit_selection_event(e,t=!0){const{x_scale:s,y_scale:n}=this.plot_view.frame;let r;switch(e.type){case\"point\":{const{sx:t,sy:o}=e,c=s.invert(t),i=n.invert(o);r=Object.assign(Object.assign({},e),{x:c,y:i});break}case\"span\":{const{sx:t,sy:o}=e,c=s.invert(t),i=n.invert(o);r=Object.assign(Object.assign({},e),{x:c,y:i});break}case\"rect\":{const{sx0:t,sx1:o,sy0:c,sy1:i}=e,[a,l]=s.r_invert(t,o),[d,_]=n.r_invert(c,i);r=Object.assign(Object.assign({},e),{x0:a,y0:d,x1:l,y1:_});break}case\"poly\":{const{sx:t,sy:o}=e,c=s.v_invert(t),i=n.v_invert(o);r=Object.assign(Object.assign({},e),{x:c,y:i});break}}this.plot_model.trigger_event(new p.SelectionGeometry(r,t))}}s.SelectToolView=v,v.__name__=\"SelectToolView\";class b extends c.GestureTool{constructor(e){super(e)}initialize(){super.initialize(),this.clear=new u.Signal0(this,\"clear\")}get menu(){return[{icon:\"bk-tool-icon-replace-mode\",tooltip:\"Replace the current selection\",active:()=>\"replace\"==this.mode,handler:()=>{this.mode=\"replace\",this.active=!0}},{icon:\"bk-tool-icon-append-mode\",tooltip:\"Append to the current selection (Shift)\",active:()=>\"append\"==this.mode,handler:()=>{this.mode=\"append\",this.active=!0}},{icon:\"bk-tool-icon-intersect-mode\",tooltip:\"Intersect with the current selection (Ctrl)\",active:()=>\"intersect\"==this.mode,handler:()=>{this.mode=\"intersect\",this.active=!0}},{icon:\"bk-tool-icon-subtract-mode\",tooltip:\"Subtract from the current selection (Shift+Ctrl)\",active:()=>\"subtract\"==this.mode,handler:()=>{this.mode=\"subtract\",this.active=!0}},null,{icon:\"bk-tool-icon-clear-selection\",tooltip:\"Clear the current selection (Esc)\",handler:()=>{this.clear.emit()}}]}}s.SelectTool=b,o=b,b.__name__=\"SelectTool\",o.define((({String:e,Array:t,Ref:s,Or:n,Auto:r})=>({renderers:[n(t(s(l.DataRenderer)),r),\"auto\"],names:[t(e),[]],mode:[_.SelectionMode,\"replace\"]})))},\n", - " function _(t,o,e,s,i){var n;s();const _=t(223),a=t(116),l=t(20),r=t(228);class h extends _.GestureToolView{_match_aspect(t,o,e){const s=e.bbox.aspect,i=e.bbox.h_range.end,n=e.bbox.h_range.start,_=e.bbox.v_range.end,a=e.bbox.v_range.start;let l=Math.abs(t[0]-o[0]),r=Math.abs(t[1]-o[1]);const h=0==r?0:l/r,[c]=h>=s?[1,h/s]:[s/h,1];let m,p,d,b;return t[0]<=o[0]?(m=t[0],p=t[0]+l*c,p>i&&(p=i)):(p=t[0],m=t[0]-l*c,m_&&(d=_)):(d=t[1],b=t[1]-l/s,bnew a.BoxAnnotation({level:\"overlay\",top_units:\"screen\",left_units:\"screen\",bottom_units:\"screen\",right_units:\"screen\",fill_color:\"lightgrey\",fill_alpha:.5,line_color:\"black\",line_alpha:1,line_width:2,line_dash:[4,4]});class m extends _.GestureTool{constructor(t){super(t),this.tool_name=\"Box Zoom\",this.icon=r.tool_icon_box_zoom,this.event_type=\"pan\",this.default_order=20}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}e.BoxZoomTool=m,n=m,m.__name__=\"BoxZoomTool\",n.prototype.default_view=h,n.define((({Boolean:t,Ref:o})=>({dimensions:[l.Dimensions,\"both\"],overlay:[o(a.BoxAnnotation),c],match_aspect:[t,!1],origin:[l.BoxOrigin,\"corner\"]}))),n.register_alias(\"box_zoom\",(()=>new m({dimensions:\"both\"}))),n.register_alias(\"xbox_zoom\",(()=>new m({dimensions:\"width\"}))),n.register_alias(\"ybox_zoom\",(()=>new m({dimensions:\"height\"})))},\n", - " function _(s,e,t,o,_){var l;o();const i=s(378),a=s(217),c=s(381),n=s(43),h=s(228);class r extends i.SelectToolView{constructor(){super(...arguments),this.sxs=[],this.sys=[]}connect_signals(){super.connect_signals(),this.connect(this.model.properties.active.change,(()=>this._active_change()))}_active_change(){this.model.active||this._clear_overlay()}_keyup(s){s.keyCode==n.Keys.Enter&&this._clear_overlay()}_pan_start(s){this.sxs=[],this.sys=[];const{sx:e,sy:t}=s;this._append_overlay(e,t)}_pan(s){const[e,t]=this.plot_view.frame.bbox.clip(s.sx,s.sy);this._append_overlay(e,t),this.model.select_every_mousemove&&this._do_select(this.sxs,this.sys,!1,this._select_mode(s))}_pan_end(s){const{sxs:e,sys:t}=this;this._clear_overlay(),this._do_select(e,t,!0,this._select_mode(s)),this.plot_view.state.push(\"lasso_select\",{selection:this.plot_view.get_selection()})}_append_overlay(s,e){const{sxs:t,sys:o}=this;t.push(s),o.push(e),this.model.overlay.update({xs:t,ys:o})}_clear_overlay(){this.sxs=[],this.sys=[],this.model.overlay.update({xs:this.sxs,ys:this.sys})}_do_select(s,e,t,o){const _={type:\"poly\",sx:s,sy:e};this._select(_,t,o)}}t.LassoSelectToolView=r,r.__name__=\"LassoSelectToolView\";class y extends i.SelectTool{constructor(s){super(s),this.tool_name=\"Lasso Select\",this.icon=h.tool_icon_lasso_select,this.event_type=\"pan\",this.default_order=12}}t.LassoSelectTool=y,l=y,y.__name__=\"LassoSelectTool\",l.prototype.default_view=r,l.define((({Boolean:s,Ref:e})=>({select_every_mousemove:[s,!0],overlay:[e(a.PolyAnnotation),c.DEFAULT_POLY_OVERLAY]}))),l.register_alias(\"lasso_select\",(()=>new y))},\n", - " function _(e,t,s,l,o){var i;l();const a=e(378),_=e(217),c=e(43),n=e(9),h=e(228);class y extends a.SelectToolView{initialize(){super.initialize(),this.data={sx:[],sy:[]}}connect_signals(){super.connect_signals(),this.connect(this.model.properties.active.change,(()=>this._active_change()))}_active_change(){this.model.active||this._clear_data()}_keyup(e){e.keyCode==c.Keys.Enter&&this._clear_data()}_doubletap(e){this._do_select(this.data.sx,this.data.sy,!0,this._select_mode(e)),this.plot_view.state.push(\"poly_select\",{selection:this.plot_view.get_selection()}),this._clear_data()}_clear_data(){this.data={sx:[],sy:[]},this.model.overlay.update({xs:[],ys:[]})}_tap(e){const{sx:t,sy:s}=e;this.plot_view.frame.bbox.contains(t,s)&&(this.data.sx.push(t),this.data.sy.push(s),this.model.overlay.update({xs:(0,n.copy)(this.data.sx),ys:(0,n.copy)(this.data.sy)}))}_do_select(e,t,s,l){const o={type:\"poly\",sx:e,sy:t};this._select(o,s,l)}}s.PolySelectToolView=y,y.__name__=\"PolySelectToolView\";s.DEFAULT_POLY_OVERLAY=()=>new _.PolyAnnotation({level:\"overlay\",xs_units:\"screen\",ys_units:\"screen\",fill_color:\"lightgrey\",fill_alpha:.5,line_color:\"black\",line_alpha:1,line_width:2,line_dash:[4,4]});class d extends a.SelectTool{constructor(e){super(e),this.tool_name=\"Poly Select\",this.icon=h.tool_icon_polygon_select,this.event_type=\"tap\",this.default_order=11}}s.PolySelectTool=d,i=d,d.__name__=\"PolySelectTool\",i.prototype.default_view=y,i.define((({Ref:e})=>({overlay:[e(_.PolyAnnotation),s.DEFAULT_POLY_OVERLAY]}))),i.register_alias(\"poly_select\",(()=>new d))},\n", - " function _(e,t,s,i,r){var n;i();const _=e(20),d=e(383),o=e(228);class l extends d.LineToolView{constructor(){super(...arguments),this._drawing=!1}_doubletap(e){if(!this.model.active)return;const t=this.model.renderers;for(const s of t){1==this._select_event(e,\"replace\",[s]).length&&(this._selected_renderer=s)}this._show_intersections(),this._update_line_cds()}_show_intersections(){if(!this.model.active)return;if(null==this._selected_renderer)return;if(!this.model.renderers.length)return this._set_intersection([],[]),this._selected_renderer=null,void(this._drawing=!1);const e=this._selected_renderer.data_source,t=this._selected_renderer.glyph,[s,i]=[t.x.field,t.y.field],r=e.get_array(s),n=e.get_array(i);this._set_intersection(r,n)}_tap(e){const t=this.model.intersection_renderer;if(null==this._map_drag(e.sx,e.sy,t))return;if(this._drawing&&this._selected_renderer){const s=this._select_mode(e);if(0==this._select_event(e,s,[t]).length)return}const s=this._select_mode(e);this._select_event(e,s,[t]),this._select_event(e,s,this.model.renderers)}_update_line_cds(){if(null==this._selected_renderer)return;const e=this.model.intersection_renderer.glyph,t=this.model.intersection_renderer.data_source,[s,i]=[e.x.field,e.y.field];if(s&&i){const e=t.data[s],r=t.data[i];this._selected_renderer.data_source.data[s]=e,this._selected_renderer.data_source.data[i]=r}this._emit_cds_changes(this._selected_renderer.data_source,!0,!0,!1)}_pan_start(e){this._select_event(e,\"append\",[this.model.intersection_renderer]),this._basepoint=[e.sx,e.sy]}_pan(e){null!=this._basepoint&&(this._drag_points(e,[this.model.intersection_renderer],this.model.dimensions),this._selected_renderer&&this._selected_renderer.data_source.change.emit())}_pan_end(e){null!=this._basepoint&&(this._drag_points(e,[this.model.intersection_renderer]),this._emit_cds_changes(this.model.intersection_renderer.data_source,!1,!0,!0),this._selected_renderer&&this._emit_cds_changes(this._selected_renderer.data_source),this._basepoint=null)}activate(){this._drawing=!0}deactivate(){this._selected_renderer&&(this._drawing&&(this._drawing=!1),this._hide_intersections())}}s.LineEditToolView=l,l.__name__=\"LineEditToolView\";class h extends d.LineTool{constructor(e){super(e),this.tool_name=\"Line Edit Tool\",this.icon=o.tool_icon_line_edit,this.event_type=[\"tap\",\"pan\",\"move\"],this.default_order=4}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}s.LineEditTool=h,n=h,h.__name__=\"LineEditTool\",n.prototype.default_view=l,n.define((()=>({dimensions:[_.Dimensions,\"both\"]})))},\n", - " function _(e,i,n,t,s){var o;t();const r=e(8),_=e(370);class d extends _.EditToolView{_set_intersection(e,i){const n=this.model.intersection_renderer.glyph,t=this.model.intersection_renderer.data_source,[s,o]=[n.x.field,n.y.field];s&&((0,r.isArray)(e)?t.data[s]=e:n.x={value:e}),o&&((0,r.isArray)(i)?t.data[o]=i:n.y={value:i}),this._emit_cds_changes(t,!0,!0,!1)}_hide_intersections(){this._set_intersection([],[])}}n.LineToolView=d,d.__name__=\"LineToolView\";class a extends _.EditTool{constructor(e){super(e)}}n.LineTool=a,o=a,a.__name__=\"LineTool\",o.define((({AnyRef:e})=>({intersection_renderer:[e()]})))},\n", - " function _(t,s,n,e,i){e();const o=t(1);var a;const _=t(223),l=t(20),r=(0,o.__importStar)(t(228));function h(t,s,n){const e=new Map;for(const[i,o]of t){const[t,a]=o.r_invert(s,n);e.set(i,{start:t,end:a})}return e}n.update_ranges=h;class d extends _.GestureToolView{_pan_start(t){var s;this.last_dx=0,this.last_dy=0;const{sx:n,sy:e}=t,i=this.plot_view.frame.bbox;if(!i.contains(n,e)){const t=i.h_range,s=i.v_range;(nt.end)&&(this.v_axis_only=!0),(es.end)&&(this.h_axis_only=!0)}null===(s=this.model.document)||void 0===s||s.interactive_start(this.plot_model)}_pan(t){var s;this._update(t.deltaX,t.deltaY),null===(s=this.model.document)||void 0===s||s.interactive_start(this.plot_model)}_pan_end(t){this.h_axis_only=!1,this.v_axis_only=!1,null!=this.pan_info&&this.plot_view.state.push(\"pan\",{range:this.pan_info}),this.plot_view.trigger_ranges_update_event()}_update(t,s){const n=this.plot_view.frame,e=t-this.last_dx,i=s-this.last_dy,o=n.bbox.h_range,a=o.start-e,_=o.end-e,l=n.bbox.v_range,r=l.start-i,d=l.end-i,p=this.model.dimensions;let c,u,m,v,x,g;\"width\"!=p&&\"both\"!=p||this.v_axis_only?(c=o.start,u=o.end,m=0):(c=a,u=_,m=-e),\"height\"!=p&&\"both\"!=p||this.h_axis_only?(v=l.start,x=l.end,g=0):(v=r,x=d,g=-i),this.last_dx=t,this.last_dy=s;const{x_scales:w,y_scales:y}=n,f=h(w,c,u),b=h(y,v,x);this.pan_info={xrs:f,yrs:b,sdx:m,sdy:g},this.plot_view.update_range(this.pan_info,{panning:!0})}}n.PanToolView=d,d.__name__=\"PanToolView\";class p extends _.GestureTool{constructor(t){super(t),this.tool_name=\"Pan\",this.event_type=\"pan\",this.default_order=10}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}n.PanTool=p,a=p,p.__name__=\"PanTool\",a.prototype.default_view=d,a.define((()=>({dimensions:[l.Dimensions,\"both\",{on_update(t,s){switch(t){case\"both\":s.icon=r.tool_icon_pan;break;case\"width\":s.icon=r.tool_icon_xpan;break;case\"height\":s.icon=r.tool_icon_ypan}}}]}))),a.register_alias(\"pan\",(()=>new p({dimensions:\"both\"}))),a.register_alias(\"xpan\",(()=>new p({dimensions:\"width\"}))),a.register_alias(\"ypan\",(()=>new p({dimensions:\"height\"})))},\n", - " function _(e,t,i,s,n){var l;s();const a=e(116),r=e(58),o=e(19),_=e(223),h=e(228);function d(e){switch(e){case 1:return 2;case 2:return 1;case 4:return 5;case 5:return 4;default:return e}}function u(e,t,i,s){if(null==t)return!1;const n=i.compute(t);return Math.abs(e-n)n.right)&&(l=!1)}if(null!=n.bottom&&null!=n.top){const e=s.invert(t);(en.top)&&(l=!1)}return l}function g(e,t,i){let s=0;return e>=i.start&&e<=i.end&&(s+=1),t>=i.start&&t<=i.end&&(s+=1),s}function y(e,t,i,s){const n=t.compute(e),l=t.invert(n+i);return l>=s.start&&l<=s.end?l:e}function f(e,t,i){return e>t.start?(t.end=e,i):(t.end=t.start,t.start=e,d(i))}function v(e,t,i){return e=o&&(e.start=a,e.end=r)}i.flip_side=d,i.is_near=u,i.is_inside=c,i.sides_inside=g,i.compute_value=y,i.update_range_end_side=f,i.update_range_start_side=v,i.update_range=m;class p extends _.GestureToolView{initialize(){super.initialize(),this.side=0,this.model.update_overlay_from_ranges()}connect_signals(){super.connect_signals(),null!=this.model.x_range&&this.connect(this.model.x_range.change,(()=>this.model.update_overlay_from_ranges())),null!=this.model.y_range&&this.connect(this.model.y_range.change,(()=>this.model.update_overlay_from_ranges()))}_pan_start(e){this.last_dx=0,this.last_dy=0;const t=this.model.x_range,i=this.model.y_range,{frame:s}=this.plot_view,n=s.x_scale,l=s.y_scale,r=this.model.overlay,{left:o,right:_,top:h,bottom:d}=r,g=this.model.overlay.line_width+a.EDGE_TOLERANCE;null!=t&&this.model.x_interaction&&(u(e.sx,o,n,g)?this.side=1:u(e.sx,_,n,g)?this.side=2:c(e.sx,e.sy,n,l,r)&&(this.side=3)),null!=i&&this.model.y_interaction&&(0==this.side&&u(e.sy,d,l,g)&&(this.side=4),0==this.side&&u(e.sy,h,l,g)?this.side=5:c(e.sx,e.sy,n,l,this.model.overlay)&&(3==this.side?this.side=7:this.side=6))}_pan(e){const t=this.plot_view.frame,i=e.deltaX-this.last_dx,s=e.deltaY-this.last_dy,n=this.model.x_range,l=this.model.y_range,a=t.x_scale,r=t.y_scale;if(null!=n)if(3==this.side||7==this.side)m(n,a,i,t.x_range);else if(1==this.side){const e=y(n.start,a,i,t.x_range);this.side=v(e,n,this.side)}else if(2==this.side){const e=y(n.end,a,i,t.x_range);this.side=f(e,n,this.side)}if(null!=l)if(6==this.side||7==this.side)m(l,r,s,t.y_range);else if(4==this.side){const e=y(l.start,r,s,t.y_range);this.side=v(e,l,this.side)}else if(5==this.side){const e=y(l.end,r,s,t.y_range);this.side=f(e,l,this.side)}this.last_dx=e.deltaX,this.last_dy=e.deltaY}_pan_end(e){this.side=0,this.plot_view.trigger_ranges_update_event()}}i.RangeToolView=p,p.__name__=\"RangeToolView\";const x=()=>new a.BoxAnnotation({level:\"overlay\",fill_color:\"lightgrey\",fill_alpha:.5,line_color:\"black\",line_alpha:1,line_width:.5,line_dash:[2,2]});class w extends _.GestureTool{constructor(e){super(e),this.tool_name=\"Range Tool\",this.icon=h.tool_icon_range,this.event_type=\"pan\",this.default_order=1}initialize(){super.initialize(),this.overlay.in_cursor=\"grab\",this.overlay.ew_cursor=null!=this.x_range&&this.x_interaction?\"ew-resize\":null,this.overlay.ns_cursor=null!=this.y_range&&this.y_interaction?\"ns-resize\":null}update_overlay_from_ranges(){null==this.x_range&&null==this.y_range&&(this.overlay.left=null,this.overlay.right=null,this.overlay.bottom=null,this.overlay.top=null,o.logger.warn(\"RangeTool not configured with any Ranges.\")),null==this.x_range?(this.overlay.left=null,this.overlay.right=null):(this.overlay.left=this.x_range.start,this.overlay.right=this.x_range.end),null==this.y_range?(this.overlay.bottom=null,this.overlay.top=null):(this.overlay.bottom=this.y_range.start,this.overlay.top=this.y_range.end)}}i.RangeTool=w,l=w,w.__name__=\"RangeTool\",l.prototype.default_view=p,l.define((({Boolean:e,Ref:t,Nullable:i})=>({x_range:[i(t(r.Range1d)),null],x_interaction:[e,!0],y_range:[i(t(r.Range1d)),null],y_interaction:[e,!0],overlay:[t(a.BoxAnnotation),x]})))},\n", - " function _(e,t,s,o,i){var l;o();const a=e(378),n=e(20),c=e(228);class _ extends a.SelectToolView{_tap(e){\"tap\"==this.model.gesture&&this._handle_tap(e)}_doubletap(e){\"doubletap\"==this.model.gesture&&this._handle_tap(e)}_handle_tap(e){const{sx:t,sy:s}=e,o={type:\"point\",sx:t,sy:s};this._select(o,!0,this._select_mode(e))}_select(e,t,s){const{callback:o}=this.model;if(\"select\"==this.model.behavior){const i=this._computed_renderers_by_data_source();for(const[,l]of i){const i=l[0].get_selection_manager(),a=l.map((e=>this.plot_view.renderer_view(e))).filter((e=>null!=e));if(i.select(a,e,t,s)&&null!=o){const t=a[0].coordinates.x_scale.invert(e.sx),s=a[0].coordinates.y_scale.invert(e.sy),l={geometries:Object.assign(Object.assign({},e),{x:t,y:s}),source:i.source};o.execute(this.model,l)}}this._emit_selection_event(e),this.plot_view.state.push(\"tap\",{selection:this.plot_view.get_selection()})}else for(const t of this.computed_renderers){const s=this.plot_view.renderer_view(t);if(null==s)continue;const i=t.get_selection_manager();if(i.inspect(s,e)&&null!=o){const t=s.coordinates.x_scale.invert(e.sx),l=s.coordinates.y_scale.invert(e.sy),a={geometries:Object.assign(Object.assign({},e),{x:t,y:l}),source:i.source};o.execute(this.model,a)}}}}s.TapToolView=_,_.__name__=\"TapToolView\";class r extends a.SelectTool{constructor(e){super(e),this.tool_name=\"Tap\",this.icon=c.tool_icon_tap_select,this.event_type=\"tap\",this.default_order=10}}s.TapTool=r,l=r,r.__name__=\"TapTool\",l.prototype.default_view=_,l.define((({Any:e,Enum:t,Nullable:s})=>({behavior:[n.TapBehavior,\"select\"],gesture:[t(\"tap\",\"doubletap\"),\"tap\"],callback:[s(e)]}))),l.register_alias(\"click\",(()=>new r({behavior:\"inspect\"}))),l.register_alias(\"tap\",(()=>new r)),l.register_alias(\"doubletap\",(()=>new r({gesture:\"doubletap\"})))},\n", - " function _(e,t,s,n,i){var a;n();const o=e(223),l=e(20),_=e(228),r=e(384);class h extends o.GestureToolView{_scroll(e){let t=this.model.speed*e.delta;t>.9?t=.9:t<-.9&&(t=-.9),this._update_ranges(t)}_update_ranges(e){var t;const{frame:s}=this.plot_view,n=s.bbox.h_range,i=s.bbox.v_range,[a,o]=[n.start,n.end],[l,_]=[i.start,i.end];let h,d,p,c;switch(this.model.dimension){case\"height\":{const t=Math.abs(_-l);h=a,d=o,p=l-t*e,c=_-t*e;break}case\"width\":{const t=Math.abs(o-a);h=a-t*e,d=o-t*e,p=l,c=_;break}}const{x_scales:g,y_scales:u}=s,w={xrs:(0,r.update_ranges)(g,h,d),yrs:(0,r.update_ranges)(u,p,c),factor:e};this.plot_view.state.push(\"wheel_pan\",{range:w}),this.plot_view.update_range(w,{scrolling:!0}),null===(t=this.model.document)||void 0===t||t.interactive_start(this.plot_model,(()=>this.plot_view.trigger_ranges_update_event()))}}s.WheelPanToolView=h,h.__name__=\"WheelPanToolView\";class d extends o.GestureTool{constructor(e){super(e),this.tool_name=\"Wheel Pan\",this.icon=_.tool_icon_wheel_pan,this.event_type=\"scroll\",this.default_order=12}get tooltip(){return this._get_dim_tooltip(this.dimension)}}s.WheelPanTool=d,a=d,d.__name__=\"WheelPanTool\",a.prototype.default_view=h,a.define((()=>({dimension:[l.Dimension,\"width\"]}))),a.internal((({Number:e})=>({speed:[e,.001]}))),a.register_alias(\"xwheel_pan\",(()=>new d({dimension:\"width\"}))),a.register_alias(\"ywheel_pan\",(()=>new d({dimension:\"height\"})))},\n", - " function _(e,o,t,s,i){var n;s();const l=e(223),_=e(368),h=e(20),a=e(27),r=e(228);class m extends l.GestureToolView{_pinch(e){const{sx:o,sy:t,scale:s,ctrlKey:i,shiftKey:n}=e;let l;l=s>=1?20*(s-1):-20/s,this._scroll({type:\"wheel\",sx:o,sy:t,delta:l,ctrlKey:i,shiftKey:n})}_scroll(e){var o;const{frame:t}=this.plot_view,s=t.bbox.h_range,i=t.bbox.v_range,{sx:n,sy:l}=e,h=this.model.dimensions,a=(\"width\"==h||\"both\"==h)&&s.startthis.plot_view.trigger_ranges_update_event()))}}t.WheelZoomToolView=m,m.__name__=\"WheelZoomToolView\";class d extends l.GestureTool{constructor(e){super(e),this.tool_name=\"Wheel Zoom\",this.icon=r.tool_icon_wheel_zoom,this.event_type=a.is_mobile?\"pinch\":\"scroll\",this.default_order=10}get tooltip(){return this._get_dim_tooltip(this.dimensions)}}t.WheelZoomTool=d,n=d,d.__name__=\"WheelZoomTool\",n.prototype.default_view=m,n.define((({Boolean:e,Number:o})=>({dimensions:[h.Dimensions,\"both\"],maintain_focus:[e,!0],zoom_on_axis:[e,!0],speed:[o,1/600]}))),n.register_alias(\"wheel_zoom\",(()=>new d({dimensions:\"both\"}))),n.register_alias(\"xwheel_zoom\",(()=>new d({dimensions:\"width\"}))),n.register_alias(\"ywheel_zoom\",(()=>new d({dimensions:\"height\"})))},\n", - " function _(i,e,s,t,o){var n;t();const l=i(232),a=i(219),h=i(20),r=i(13),_=i(228);class c extends l.InspectToolView{_move(i){if(!this.model.active)return;const{sx:e,sy:s}=i;this.plot_view.frame.bbox.contains(e,s)?this._update_spans(e,s):this._update_spans(null,null)}_move_exit(i){this._update_spans(null,null)}_update_spans(i,e){const s=this.model.dimensions;\"width\"!=s&&\"both\"!=s||(this.model.spans.width.location=e),\"height\"!=s&&\"both\"!=s||(this.model.spans.height.location=i)}}s.CrosshairToolView=c,c.__name__=\"CrosshairToolView\";class p extends l.InspectTool{constructor(i){super(i),this.tool_name=\"Crosshair\",this.icon=_.tool_icon_crosshair}get tooltip(){return this._get_dim_tooltip(this.dimensions)}get synthetic_renderers(){return(0,r.values)(this.spans)}}s.CrosshairTool=p,n=p,p.__name__=\"CrosshairTool\",(()=>{function i(i,e){return new a.Span({for_hover:!0,dimension:e,location_units:\"screen\",level:\"overlay\",line_color:i.line_color,line_width:i.line_width,line_alpha:i.line_alpha})}n.prototype.default_view=c,n.define((({Alpha:i,Number:e,Color:s})=>({dimensions:[h.Dimensions,\"both\"],line_color:[s,\"black\"],line_width:[e,1],line_alpha:[i,1]}))),n.internal((({Struct:e,Ref:s})=>({spans:[e({width:s(a.Span),height:s(a.Span)}),e=>({width:i(e,\"width\"),height:i(e,\"height\")})]}))),n.register_alias(\"crosshair\",(()=>new p))})()},\n", - " function _(e,s,t,r,n){var o;r();const a=e(53),u=e(13),c=e(34);class i extends a.Model{constructor(e){super(e)}get values(){return(0,u.values)(this.args)}_make_code(e,s,t,r){return new Function(...(0,u.keys)(this.args),e,s,t,(0,c.use_strict)(r))}format(e,s,t){return this._make_code(\"value\",\"format\",\"special_vars\",this.code)(...this.values,e,s,t)}}t.CustomJSHover=i,o=i,i.__name__=\"CustomJSHover\",o.define((({Unknown:e,String:s,Dict:t})=>({args:[t(e),{}],code:[s,\"\"]})))},\n", - " function _(e,t,n,s,i){s();const o=e(1);var r;const l=e(232),a=e(390),c=e(241),_=e(175),d=e(339),p=e(176),h=e(177),u=e(283),m=e(186),y=e(187),f=e(189),x=(0,o.__importStar)(e(185)),v=e(152),w=e(43),g=e(22),b=e(13),k=e(234),C=e(8),S=e(113),T=e(20),$=e(228),R=e(15),A=e(66),M=(0,o.__importStar)(e(242)),V=e(392);function G(e,t,n,s,i,o){const r={x:i[e],y:o[e]},l={x:i[e+1],y:o[e+1]};let a,c;if(\"span\"==t.type)\"h\"==t.direction?(a=Math.abs(r.x-n),c=Math.abs(l.x-n)):(a=Math.abs(r.y-s),c=Math.abs(l.y-s));else{const e={x:n,y:s};a=x.dist_2_pts(r,e),c=x.dist_2_pts(l,e)}return adelete this._template_el)),this.on_change([e,t,n],(async()=>await this._update_ttmodels()))}async _update_ttmodels(){const{_ttmodels:e,computed_renderers:t}=this;e.clear();const{tooltips:n}=this.model;if(null!=n)for(const t of this.computed_renderers){const s=new c.Tooltip({custom:(0,C.isString)(n)||(0,C.isFunction)(n),attachment:this.model.attachment,show_arrow:this.model.show_arrow});t instanceof _.GlyphRenderer?e.set(t,s):t instanceof d.GraphRenderer&&(e.set(t.node_renderer,s),e.set(t.edge_renderer,s))}const s=await(0,S.build_views)(this._ttviews,[...e.values()],{parent:this.plot_view});for(const e of s)e.render();const i=[...function*(){for(const e of t)e instanceof _.GlyphRenderer?yield e:e instanceof d.GraphRenderer&&(yield e.node_renderer,yield e.edge_renderer)}()],o=this._slots.get(this._update);if(null!=o){const e=new Set(i.map((e=>e.data_source)));R.Signal.disconnect_receiver(this,o,e)}for(const e of i)this.connect(e.data_source.inspect,this._update)}get computed_renderers(){const{renderers:e,names:t}=this.model,n=this.plot_model.data_renderers;return(0,A.compute_renderers)(e,n,t)}get ttmodels(){return this._ttmodels}_clear(){this._inspect(1/0,1/0);for(const[,e]of this.ttmodels)e.clear()}_move(e){if(!this.model.active)return;const{sx:t,sy:n}=e;this.plot_view.frame.bbox.contains(t,n)?this._inspect(t,n):this._clear()}_move_exit(){this._clear()}_inspect(e,t){let n;if(\"mouse\"==this.model.mode)n={type:\"point\",sx:e,sy:t};else{n={type:\"span\",direction:\"vline\"==this.model.mode?\"h\":\"v\",sx:e,sy:t}}for(const e of this.computed_renderers){const t=e.get_selection_manager(),s=this.plot_view.renderer_view(e);null!=s&&t.inspect(s,n)}this._emit_callback(n)}_update([e,{geometry:t}]){var n,s;if(!this.model.active)return;if(\"point\"!=t.type&&\"span\"!=t.type)return;if(!(e instanceof _.GlyphRenderer))return;if(\"ignore\"==this.model.muted_policy&&e.muted)return;const i=this.ttmodels.get(e);if(null==i)return;const o=e.get_selection_manager(),r=o.inspectors.get(e),l=e.view.convert_selection_to_subset(r);if(r.is_empty()&&null==r.view)return void i.clear();const a=o.source,c=this.plot_view.renderer_view(e);if(null==c)return;const{sx:d,sy:p}=t,x=c.coordinates.x_scale,v=c.coordinates.y_scale,g=x.invert(d),k=v.invert(p),{glyph:C}=c,S=[];if(C instanceof m.PatchView){const[t,n]=[d,p],s={x:g,y:k,sx:d,sy:p,rx:t,ry:n,name:e.name};S.push([t,n,this._render_tooltips(a,-1,s)])}if(C instanceof y.HAreaView)for(const t of l.line_indices){const n=C._x1,s=C._x2,i=C._y,[o,r]=[d,p],c={index:t,x:g,y:k,sx:d,sy:p,data_x1:n,data_x2:s,data_y:i,rx:o,ry:r,indices:l.line_indices,name:e.name};S.push([o,r,this._render_tooltips(a,t,c)])}if(C instanceof f.VAreaView)for(const t of l.line_indices){const n=C._x,s=C._y1,i=C._y2,[o,r]=[d,p],c={index:t,x:g,y:k,sx:d,sy:p,data_x:n,data_y1:s,data_y2:i,rx:o,ry:r,indices:l.line_indices,name:e.name};S.push([o,r,this._render_tooltips(a,t,c)])}if(C instanceof h.LineView)for(const n of l.line_indices){let s,i,o=C._x[n+1],r=C._y[n+1],c=n;switch(this.model.line_policy){case\"interp\":[o,r]=C.get_interpolation_hit(n,t),s=x.compute(o),i=v.compute(r);break;case\"prev\":[[s,i],c]=H(C.sx,C.sy,n);break;case\"next\":[[s,i],c]=H(C.sx,C.sy,n+1);break;case\"nearest\":[[s,i],c]=G(n,t,d,p,C.sx,C.sy),o=C._x[c],r=C._y[c];break;default:[s,i]=[d,p]}const _={index:c,x:g,y:k,sx:d,sy:p,data_x:o,data_y:r,rx:s,ry:i,indices:l.line_indices,name:e.name};S.push([s,i,this._render_tooltips(a,c,_)])}for(const t of r.image_indices){const n={index:t.index,x:g,y:k,sx:d,sy:p,name:e.name},s=this._render_tooltips(a,t,n);S.push([d,p,s])}for(const i of l.indices)if(C instanceof u.MultiLineView&&!(0,b.isEmpty)(l.multiline_indices))for(const n of l.multiline_indices[i.toString()]){let s,o,r,c=C._xs.get(i)[n],h=C._ys.get(i)[n],u=n;switch(this.model.line_policy){case\"interp\":[c,h]=C.get_interpolation_hit(i,n,t),s=x.compute(c),o=v.compute(h);break;case\"prev\":[[s,o],u]=H(C.sxs.get(i),C.sys.get(i),n);break;case\"next\":[[s,o],u]=H(C.sxs.get(i),C.sys.get(i),n+1);break;case\"nearest\":[[s,o],u]=G(n,t,d,p,C.sxs.get(i),C.sys.get(i)),c=C._xs.get(i)[u],h=C._ys.get(i)[u];break;default:throw new Error(\"shouldn't have happened\")}r=e instanceof _.GlyphRenderer?e.view.convert_indices_from_subset([i])[0]:i;const m={index:r,x:g,y:k,sx:d,sy:p,data_x:c,data_y:h,segment_index:u,indices:l.multiline_indices,name:e.name};S.push([s,o,this._render_tooltips(a,r,m)])}else{const t=null===(n=C._x)||void 0===n?void 0:n[i],o=null===(s=C._y)||void 0===s?void 0:s[i];let r,c,h;if(\"snap_to_data\"==this.model.point_policy){let e=C.get_anchor_point(this.model.anchor,i,[d,p]);if(null==e&&(e=C.get_anchor_point(\"center\",i,[d,p]),null==e))continue;r=e.x,c=e.y}else[r,c]=[d,p];h=e instanceof _.GlyphRenderer?e.view.convert_indices_from_subset([i])[0]:i;const u={index:h,x:g,y:k,sx:d,sy:p,data_x:t,data_y:o,indices:l.indices,name:e.name};S.push([r,c,this._render_tooltips(a,h,u)])}if(0==S.length)i.clear();else{const{content:e}=i;(0,w.empty)(i.content);for(const[,,t]of S)null!=t&&e.appendChild(t);const[t,n]=S[S.length-1];i.setv({position:[t,n]},{check_eq:!1})}}_emit_callback(e){const{callback:t}=this.model;if(null!=t)for(const n of this.computed_renderers){if(!(n instanceof _.GlyphRenderer))continue;const s=this.plot_view.renderer_view(n);if(null==s)continue;const{x_scale:i,y_scale:o}=s.coordinates,r=i.invert(e.sx),l=o.invert(e.sy),a=n.data_source.inspected;t.execute(this.model,{geometry:Object.assign({x:r,y:l},e),renderer:n,index:a})}}_create_template(e){const t=(0,w.div)({style:{display:\"table\",borderSpacing:\"2px\"}});for(const[n]of e){const e=(0,w.div)({style:{display:\"table-row\"}});t.appendChild(e);const s=(0,w.div)({style:{display:\"table-cell\"},class:M.tooltip_row_label},0!=n.length?`${n}: `:\"\");e.appendChild(s);const i=(0,w.span)();i.dataset.value=\"\";const o=(0,w.span)({class:M.tooltip_color_block},\" \");o.dataset.swatch=\"\",(0,w.undisplay)(o);const r=(0,w.div)({style:{display:\"table-cell\"},class:M.tooltip_row_value},i,o);e.appendChild(r)}return t}_render_template(e,t,n,s,i){const o=e.cloneNode(!0),r=o.querySelectorAll(\"[data-value]\"),l=o.querySelectorAll(\"[data-swatch]\"),a=/\\$color(\\[.*\\])?:(\\w*)/,c=/\\$swatch:(\\w*)/;for(const[[,e],o]of(0,k.enumerate)(t)){const t=e.match(c),_=e.match(a);if(null!=t||null!=_){if(null!=t){const[,e]=t,i=n.get_column(e);if(null==i)r[o].textContent=`${e} unknown`;else{const e=(0,C.isNumber)(s)?i[s]:null;null!=e&&(l[o].style.backgroundColor=(0,g.color2css)(e),(0,w.display)(l[o]))}}if(null!=_){const[,e=\"\",t]=_,i=n.get_column(t);if(null==i){r[o].textContent=`${t} unknown`;continue}const a=e.indexOf(\"hex\")>=0,c=e.indexOf(\"swatch\")>=0,d=(0,C.isNumber)(s)?i[s]:null;if(null==d){r[o].textContent=\"(null)\";continue}r[o].textContent=a?(0,g.color2hex)(d):(0,g.color2css)(d),c&&(l[o].style.backgroundColor=(0,g.color2css)(d),(0,w.display)(l[o]))}}else{const t=(0,v.replace_placeholders)(e.replace(\"$~\",\"$data_\"),n,s,this.model.formatters,i);if((0,C.isString)(t))r[o].textContent=t;else for(const e of t)r[o].appendChild(e)}}return o}_render_tooltips(e,t,n){var s;const{tooltips:i}=this.model;if((0,C.isString)(i)){const s=(0,v.replace_placeholders)({html:i},e,t,this.model.formatters,n);return(0,w.div)(s)}if((0,C.isFunction)(i))return i(e,n);if(i instanceof V.Template)return this._template_view.update(e,t,n),this._template_view.el;if(null!=i){const o=null!==(s=this._template_el)&&void 0!==s?s:this._template_el=this._create_template(i);return this._render_template(o,i,e,t,n)}return null}}n.HoverToolView=z,z.__name__=\"HoverToolView\";class P extends l.InspectTool{constructor(e){super(e),this.tool_name=\"Hover\",this.icon=$.tool_icon_hover}}n.HoverTool=P,r=P,P.__name__=\"HoverTool\",r.prototype.default_view=z,r.define((({Any:e,Boolean:t,String:n,Array:s,Tuple:i,Dict:o,Or:r,Ref:l,Function:c,Auto:_,Nullable:d})=>({tooltips:[d(r(l(V.Template),n,s(i(n,n)),c())),[[\"index\",\"$index\"],[\"data (x, y)\",\"($x, $y)\"],[\"screen (x, y)\",\"($sx, $sy)\"]]],formatters:[o(r(l(a.CustomJSHover),v.FormatterType)),{}],renderers:[r(s(l(p.DataRenderer)),_),\"auto\"],names:[s(n),[]],mode:[T.HoverMode,\"mouse\"],muted_policy:[T.MutedPolicy,\"show\"],point_policy:[T.PointPolicy,\"snap_to_data\"],line_policy:[T.LinePolicy,\"nearest\"],show_arrow:[t,!0],anchor:[T.Anchor,\"center\"],attachment:[T.TooltipAttachment,\"horizontal\"],callback:[d(e)]}))),r.register_alias(\"hover\",(()=>new P))},\n", - " function _(e,t,s,n,a){n();const l=e(1);var i,_,o,r,c,d,p,u,m,w,f,h,x;const v=e(53),y=e(309),V=e(393);a(\"Styles\",V.Styles);const g=e(43),T=e(42),b=e(226),R=e(113),D=e(8),M=e(13),S=(0,l.__importStar)(e(242)),O=e(152);class C extends b.DOMView{}s.DOMNodeView=C,C.__name__=\"DOMNodeView\";class z extends v.Model{constructor(e){super(e)}}s.DOMNode=z,z.__name__=\"DOMNode\",z.__module__=\"bokeh.models.dom\";class P extends C{render(){super.render(),this.el.textContent=this.model.content}_createElement(){return document.createTextNode(\"\")}}s.TextView=P,P.__name__=\"TextView\";class A extends z{constructor(e){super(e)}}s.Text=A,i=A,A.__name__=\"Text\",i.prototype.default_view=P,i.define((({String:e})=>({content:[e,\"\"]})));class N extends C{}s.PlaceholderView=N,N.__name__=\"PlaceholderView\",N.tag_name=\"span\";class E extends z{constructor(e){super(e)}}s.Placeholder=E,_=E,E.__name__=\"Placeholder\",_.define((({})=>({})));class G extends N{update(e,t,s){this.el.textContent=t.toString()}}s.IndexView=G,G.__name__=\"IndexView\";class I extends E{constructor(e){super(e)}}s.Index=I,o=I,I.__name__=\"Index\",o.prototype.default_view=G,o.define((({})=>({})));class k extends N{update(e,t,s){const n=(0,O._get_column_value)(this.model.field,e,t),a=null==n?\"???\":`${n}`;this.el.textContent=a}}s.ValueRefView=k,k.__name__=\"ValueRefView\";class $ extends E{constructor(e){super(e)}}s.ValueRef=$,r=$,$.__name__=\"ValueRef\",r.prototype.default_view=k,r.define((({String:e})=>({field:[e]})));class B extends k{render(){super.render(),this.value_el=(0,g.span)(),this.swatch_el=(0,g.span)({class:S.tooltip_color_block},\" \"),this.el.appendChild(this.value_el),this.el.appendChild(this.swatch_el)}update(e,t,s){const n=(0,O._get_column_value)(this.model.field,e,t),a=null==n?\"???\":`${n}`;this.el.textContent=a}}s.ColorRefView=B,B.__name__=\"ColorRefView\";class L extends ${constructor(e){super(e)}}s.ColorRef=L,c=L,L.__name__=\"ColorRef\",c.prototype.default_view=B,c.define((({Boolean:e})=>({hex:[e,!0],swatch:[e,!0]})));class j extends C{constructor(){super(...arguments),this.child_views=new Map}async lazy_initialize(){await super.lazy_initialize();const e=this.model.children.filter((e=>e instanceof v.Model));await(0,R.build_views)(this.child_views,e,{parent:this})}render(){super.render();const{style:e}=this.model;if(null!=e)if(e instanceof V.Styles)for(const t of e){const e=t.get_value();if((0,D.isString)(e)){const s=t.attr.replace(/_/g,\"-\");this.el.style.hasOwnProperty(s)&&this.el.style.setProperty(s,e)}}else for(const[t,s]of(0,M.entries)(e)){const e=t.replace(/_/g,\"-\");this.el.style.hasOwnProperty(e)&&this.el.style.setProperty(e,s)}for(const e of this.model.children)if((0,D.isString)(e)){const t=document.createTextNode(e);this.el.appendChild(t)}else{this.child_views.get(e).renderTo(this.el)}}}s.DOMElementView=j,j.__name__=\"DOMElementView\";class q extends z{constructor(e){super(e)}}s.DOMElement=q,d=q,q.__name__=\"DOMElement\",d.define((({String:e,Array:t,Dict:s,Or:n,Nullable:a,Ref:l})=>({style:[a(n(l(V.Styles),s(e))),null],children:[t(n(e,l(z),l(y.LayoutDOM))),[]]})));class F extends T.View{}s.ActionView=F,F.__name__=\"ActionView\";class H extends v.Model{constructor(e){super(e)}}s.Action=H,p=H,H.__name__=\"Action\",H.__module__=\"bokeh.models.dom\",p.define((({})=>({})));class J extends j{constructor(){super(...arguments),this.action_views=new Map}async lazy_initialize(){await super.lazy_initialize(),await(0,R.build_views)(this.action_views,this.model.actions,{parent:this})}remove(){(0,R.remove_views)(this.action_views),super.remove()}update(e,t,s={}){!function n(a){for(const l of a.child_views.values())l instanceof N?l.update(e,t,s):l instanceof j&&n(l)}(this);for(const n of this.action_views.values())n.update(e,t,s)}}s.TemplateView=J,J.__name__=\"TemplateView\",J.tag_name=\"div\";class K extends q{}s.Template=K,u=K,K.__name__=\"Template\",u.prototype.default_view=J,u.define((({Array:e,Ref:t})=>({actions:[e(t(H)),[]]})));class Q extends j{}s.SpanView=Q,Q.__name__=\"SpanView\",Q.tag_name=\"span\";class U extends q{}s.Span=U,m=U,U.__name__=\"Span\",m.prototype.default_view=Q;class W extends j{}s.DivView=W,W.__name__=\"DivView\",W.tag_name=\"div\";class X extends q{}s.Div=X,w=X,X.__name__=\"Div\",w.prototype.default_view=W;class Y extends j{}s.TableView=Y,Y.__name__=\"TableView\",Y.tag_name=\"table\";class Z extends q{}s.Table=Z,f=Z,Z.__name__=\"Table\",f.prototype.default_view=Y;class ee extends j{}s.TableRowView=ee,ee.__name__=\"TableRowView\",ee.tag_name=\"tr\";class te extends q{}s.TableRow=te,h=te,te.__name__=\"TableRow\",h.prototype.default_view=ee;const se=e(41),ne=e(234);class ae extends F{update(e,t,s){for(const[e,s]of(0,ne.enumerate)(this.model.groups))e.visible=t==s}}s.ToggleGroupView=ae,ae.__name__=\"ToggleGroupView\";class le extends H{constructor(e){super(e)}}s.ToggleGroup=le,x=le,le.__name__=\"ToggleGroup\",x.prototype.default_view=ae,x.define((({Array:e,Ref:t})=>({groups:[e(t(se.RendererGroup)),[]]})))},\n", - " function _(l,n,u,_,e){var t;_();const o=l(53);class r extends o.Model{constructor(l){super(l)}}u.Styles=r,t=r,r.__name__=\"Styles\",r.__module__=\"bokeh.models.css\",t.define((({String:l,Nullable:n})=>({align_content:[n(l),null],align_items:[n(l),null],align_self:[n(l),null],alignment_baseline:[n(l),null],all:[n(l),null],animation:[n(l),null],animation_delay:[n(l),null],animation_direction:[n(l),null],animation_duration:[n(l),null],animation_fill_mode:[n(l),null],animation_iteration_count:[n(l),null],animation_name:[n(l),null],animation_play_state:[n(l),null],animation_timing_function:[n(l),null],backface_visibility:[n(l),null],background:[n(l),null],background_attachment:[n(l),null],background_clip:[n(l),null],background_color:[n(l),null],background_image:[n(l),null],background_origin:[n(l),null],background_position:[n(l),null],background_position_x:[n(l),null],background_position_y:[n(l),null],background_repeat:[n(l),null],background_size:[n(l),null],baseline_shift:[n(l),null],block_size:[n(l),null],border:[n(l),null],border_block_end:[n(l),null],border_block_end_color:[n(l),null],border_block_end_style:[n(l),null],border_block_end_width:[n(l),null],border_block_start:[n(l),null],border_block_start_color:[n(l),null],border_block_start_style:[n(l),null],border_block_start_width:[n(l),null],border_bottom:[n(l),null],border_bottom_color:[n(l),null],border_bottom_left_radius:[n(l),null],border_bottom_right_radius:[n(l),null],border_bottom_style:[n(l),null],border_bottom_width:[n(l),null],border_collapse:[n(l),null],border_color:[n(l),null],border_image:[n(l),null],border_image_outset:[n(l),null],border_image_repeat:[n(l),null],border_image_slice:[n(l),null],border_image_source:[n(l),null],border_image_width:[n(l),null],border_inline_end:[n(l),null],border_inline_end_color:[n(l),null],border_inline_end_style:[n(l),null],border_inline_end_width:[n(l),null],border_inline_start:[n(l),null],border_inline_start_color:[n(l),null],border_inline_start_style:[n(l),null],border_inline_start_width:[n(l),null],border_left:[n(l),null],border_left_color:[n(l),null],border_left_style:[n(l),null],border_left_width:[n(l),null],border_radius:[n(l),null],border_right:[n(l),null],border_right_color:[n(l),null],border_right_style:[n(l),null],border_right_width:[n(l),null],border_spacing:[n(l),null],border_style:[n(l),null],border_top:[n(l),null],border_top_color:[n(l),null],border_top_left_radius:[n(l),null],border_top_right_radius:[n(l),null],border_top_style:[n(l),null],border_top_width:[n(l),null],border_width:[n(l),null],bottom:[n(l),null],box_shadow:[n(l),null],box_sizing:[n(l),null],break_after:[n(l),null],break_before:[n(l),null],break_inside:[n(l),null],caption_side:[n(l),null],caret_color:[n(l),null],clear:[n(l),null],clip:[n(l),null],clip_path:[n(l),null],clip_rule:[n(l),null],color:[n(l),null],color_interpolation:[n(l),null],color_interpolation_filters:[n(l),null],column_count:[n(l),null],column_fill:[n(l),null],column_gap:[n(l),null],column_rule:[n(l),null],column_rule_color:[n(l),null],column_rule_style:[n(l),null],column_rule_width:[n(l),null],column_span:[n(l),null],column_width:[n(l),null],columns:[n(l),null],content:[n(l),null],counter_increment:[n(l),null],counter_reset:[n(l),null],css_float:[n(l),null],css_text:[n(l),null],cursor:[n(l),null],direction:[n(l),null],display:[n(l),null],dominant_baseline:[n(l),null],empty_cells:[n(l),null],fill:[n(l),null],fill_opacity:[n(l),null],fill_rule:[n(l),null],filter:[n(l),null],flex:[n(l),null],flex_basis:[n(l),null],flex_direction:[n(l),null],flex_flow:[n(l),null],flex_grow:[n(l),null],flex_shrink:[n(l),null],flex_wrap:[n(l),null],float:[n(l),null],flood_color:[n(l),null],flood_opacity:[n(l),null],font:[n(l),null],font_family:[n(l),null],font_feature_settings:[n(l),null],font_kerning:[n(l),null],font_size:[n(l),null],font_size_adjust:[n(l),null],font_stretch:[n(l),null],font_style:[n(l),null],font_synthesis:[n(l),null],font_variant:[n(l),null],font_variant_caps:[n(l),null],font_variant_east_asian:[n(l),null],font_variant_ligatures:[n(l),null],font_variant_numeric:[n(l),null],font_variant_position:[n(l),null],font_weight:[n(l),null],gap:[n(l),null],glyph_orientation_vertical:[n(l),null],grid:[n(l),null],grid_area:[n(l),null],grid_auto_columns:[n(l),null],grid_auto_flow:[n(l),null],grid_auto_rows:[n(l),null],grid_column:[n(l),null],grid_column_end:[n(l),null],grid_column_gap:[n(l),null],grid_column_start:[n(l),null],grid_gap:[n(l),null],grid_row:[n(l),null],grid_row_end:[n(l),null],grid_row_gap:[n(l),null],grid_row_start:[n(l),null],grid_template:[n(l),null],grid_template_areas:[n(l),null],grid_template_columns:[n(l),null],grid_template_rows:[n(l),null],height:[n(l),null],hyphens:[n(l),null],image_orientation:[n(l),null],image_rendering:[n(l),null],inline_size:[n(l),null],justify_content:[n(l),null],justify_items:[n(l),null],justify_self:[n(l),null],left:[n(l),null],letter_spacing:[n(l),null],lighting_color:[n(l),null],line_break:[n(l),null],line_height:[n(l),null],list_style:[n(l),null],list_style_image:[n(l),null],list_style_position:[n(l),null],list_style_type:[n(l),null],margin:[n(l),null],margin_block_end:[n(l),null],margin_block_start:[n(l),null],margin_bottom:[n(l),null],margin_inline_end:[n(l),null],margin_inline_start:[n(l),null],margin_left:[n(l),null],margin_right:[n(l),null],margin_top:[n(l),null],marker:[n(l),null],marker_end:[n(l),null],marker_mid:[n(l),null],marker_start:[n(l),null],mask:[n(l),null],mask_composite:[n(l),null],mask_image:[n(l),null],mask_position:[n(l),null],mask_repeat:[n(l),null],mask_size:[n(l),null],mask_type:[n(l),null],max_block_size:[n(l),null],max_height:[n(l),null],max_inline_size:[n(l),null],max_width:[n(l),null],min_block_size:[n(l),null],min_height:[n(l),null],min_inline_size:[n(l),null],min_width:[n(l),null],object_fit:[n(l),null],object_position:[n(l),null],opacity:[n(l),null],order:[n(l),null],orphans:[n(l),null],outline:[n(l),null],outline_color:[n(l),null],outline_offset:[n(l),null],outline_style:[n(l),null],outline_width:[n(l),null],overflow:[n(l),null],overflow_anchor:[n(l),null],overflow_wrap:[n(l),null],overflow_x:[n(l),null],overflow_y:[n(l),null],overscroll_behavior:[n(l),null],overscroll_behavior_block:[n(l),null],overscroll_behavior_inline:[n(l),null],overscroll_behavior_x:[n(l),null],overscroll_behavior_y:[n(l),null],padding:[n(l),null],padding_block_end:[n(l),null],padding_block_start:[n(l),null],padding_bottom:[n(l),null],padding_inline_end:[n(l),null],padding_inline_start:[n(l),null],padding_left:[n(l),null],padding_right:[n(l),null],padding_top:[n(l),null],page_break_after:[n(l),null],page_break_before:[n(l),null],page_break_inside:[n(l),null],paint_order:[n(l),null],perspective:[n(l),null],perspective_origin:[n(l),null],place_content:[n(l),null],place_items:[n(l),null],place_self:[n(l),null],pointer_events:[n(l),null],position:[n(l),null],quotes:[n(l),null],resize:[n(l),null],right:[n(l),null],rotate:[n(l),null],row_gap:[n(l),null],ruby_align:[n(l),null],ruby_position:[n(l),null],scale:[n(l),null],scroll_behavior:[n(l),null],shape_rendering:[n(l),null],stop_color:[n(l),null],stop_opacity:[n(l),null],stroke:[n(l),null],stroke_dasharray:[n(l),null],stroke_dashoffset:[n(l),null],stroke_linecap:[n(l),null],stroke_linejoin:[n(l),null],stroke_miterlimit:[n(l),null],stroke_opacity:[n(l),null],stroke_width:[n(l),null],tab_size:[n(l),null],table_layout:[n(l),null],text_align:[n(l),null],text_align_last:[n(l),null],text_anchor:[n(l),null],text_combine_upright:[n(l),null],text_decoration:[n(l),null],text_decoration_color:[n(l),null],text_decoration_line:[n(l),null],text_decoration_style:[n(l),null],text_emphasis:[n(l),null],text_emphasis_color:[n(l),null],text_emphasis_position:[n(l),null],text_emphasis_style:[n(l),null],text_indent:[n(l),null],text_justify:[n(l),null],text_orientation:[n(l),null],text_overflow:[n(l),null],text_rendering:[n(l),null],text_shadow:[n(l),null],text_transform:[n(l),null],text_underline_position:[n(l),null],top:[n(l),null],touch_action:[n(l),null],transform:[n(l),null],transform_box:[n(l),null],transform_origin:[n(l),null],transform_style:[n(l),null],transition:[n(l),null],transition_delay:[n(l),null],transition_duration:[n(l),null],transition_property:[n(l),null],transition_timing_function:[n(l),null],translate:[n(l),null],unicode_bidi:[n(l),null],user_select:[n(l),null],vertical_align:[n(l),null],visibility:[n(l),null],white_space:[n(l),null],widows:[n(l),null],width:[n(l),null],will_change:[n(l),null],word_break:[n(l),null],word_spacing:[n(l),null],word_wrap:[n(l),null],writing_mode:[n(l),null],z_index:[n(l),null]})))},\n", - " function _(t,o,e,n,s){var i;n();const l=t(15),c=t(53),r=t(224),a=t(232),u=t(234);class h extends c.Model{constructor(t){super(t)}get button_view(){return this.tools[0].button_view}get event_type(){return this.tools[0].event_type}get tooltip(){return this.tools[0].tooltip}get tool_name(){return this.tools[0].tool_name}get icon(){return this.tools[0].computed_icon}get computed_icon(){return this.icon}get toggleable(){const t=this.tools[0];return t instanceof a.InspectTool&&t.toggleable}initialize(){super.initialize(),this.do=new l.Signal0(this,\"do\")}connect_signals(){super.connect_signals(),this.connect(this.do,(()=>this.doit())),this.connect(this.properties.active.change,(()=>this.set_active()));for(const t of this.tools)this.connect(t.properties.active.change,(()=>{this.active=t.active}))}doit(){for(const t of this.tools)t.do.emit()}set_active(){for(const t of this.tools)t.active=this.active}get menu(){const{menu:t}=this.tools[0];if(null==t)return null;const o=[];for(const[e,n]of(0,u.enumerate)(t))if(null==e)o.push(null);else{const t=()=>{var t,o,e;for(const s of this.tools)null===(e=null===(o=null===(t=s.menu)||void 0===t?void 0:t[n])||void 0===o?void 0:o.handler)||void 0===e||e.call(o)};o.push(Object.assign(Object.assign({},e),{handler:t}))}return o}}e.ToolProxy=h,i=h,h.__name__=\"ToolProxy\",i.define((({Boolean:t,Array:o,Ref:e})=>({tools:[o(e(r.ButtonTool)),[]],active:[t,!1],disabled:[t,!1]})))},\n", - " function _(o,t,s,e,i){var n,r;e();const l=o(20),c=o(9),h=o(13),a=o(233),_=o(221),p=o(394),u=o(309),f=o(207);class y extends a.ToolbarBase{constructor(o){super(o)}initialize(){super.initialize(),this._merge_tools()}_merge_tools(){this._proxied_tools=[];const o={},t={},s={},e=[],i=[];for(const o of this.help)(0,c.includes)(i,o.redirect)||(e.push(o),i.push(o.redirect));this._proxied_tools.push(...e),this.help=e;for(const[o,t]of(0,h.entries)(this.gestures)){o in s||(s[o]={});for(const e of t.tools)e.type in s[o]||(s[o][e.type]=[]),s[o][e.type].push(e)}for(const t of this.inspectors)t.type in o||(o[t.type]=[]),o[t.type].push(t);for(const o of this.actions)o.type in t||(t[o.type]=[]),t[o.type].push(o);const n=(o,t=!1)=>{const s=new p.ToolProxy({tools:o,active:t});return this._proxied_tools.push(s),s};for(const o of(0,h.keys)(s)){const t=this.gestures[o];t.tools=[];for(const e of(0,h.keys)(s[o])){const i=s[o][e];if(i.length>0)if(\"multi\"==o)for(const o of i){const s=n([o]);t.tools.push(s),this.connect(s.properties.active.change,(()=>this._active_change(s)))}else{const o=n(i);t.tools.push(o),this.connect(o.properties.active.change,(()=>this._active_change(o)))}}}this.actions=[];for(const[o,s]of(0,h.entries)(t))if(\"CustomAction\"==o)for(const o of s)this.actions.push(n([o]));else s.length>0&&this.actions.push(n(s));this.inspectors=[];for(const t of(0,h.values)(o))t.length>0&&this.inspectors.push(n(t,!0));for(const[o,t]of(0,h.entries)(this.gestures))0!=t.tools.length&&(t.tools=(0,c.sort_by)(t.tools,(o=>o.default_order)),\"pinch\"!=o&&\"scroll\"!=o&&\"multi\"!=o&&(t.tools[0].active=!0))}}s.ProxyToolbar=y,n=y,y.__name__=\"ProxyToolbar\",n.define((({Array:o,Ref:t})=>({toolbars:[o(t(_.Toolbar)),[]]})));class d extends u.LayoutDOMView{initialize(){this.model.toolbar.toolbar_location=this.model.toolbar_location,super.initialize()}get child_models(){return[this.model.toolbar]}_update_layout(){this.layout=new f.ContentBox(this.child_views[0].el);const{toolbar:o}=this.model;o.horizontal?this.layout.set_sizing({width_policy:\"fit\",min_width:100,height_policy:\"fixed\"}):this.layout.set_sizing({width_policy:\"fixed\",height_policy:\"fit\",min_height:100})}after_layout(){super.after_layout();const o=this.child_views[0];o.layout.bbox=this.layout.bbox,o.render()}}s.ToolbarBoxView=d,d.__name__=\"ToolbarBoxView\";class b extends u.LayoutDOM{constructor(o){super(o)}}s.ToolbarBox=b,r=b,b.__name__=\"ToolbarBox\",r.prototype.default_view=d,r.define((({Ref:o})=>({toolbar:[o(a.ToolbarBase)],toolbar_location:[l.Location,\"right\"]})))},\n", - " function _(e,n,r,t,o){t();const s=e(1),u=e(53),c=(0,s.__importStar)(e(21)),a=e(8),l=e(13);r.resolve_defs=function(e,n){var r,t,o,s;function i(e){return null!=e.module?`${e.module}.${e.name}`:e.name}function f(e){if((0,a.isString)(e))switch(e){case\"Any\":return c.Any;case\"Unknown\":return c.Unknown;case\"Boolean\":return c.Boolean;case\"Number\":return c.Number;case\"Int\":return c.Int;case\"String\":return c.String;case\"Null\":return c.Null}else switch(e[0]){case\"Nullable\":{const[,n]=e;return c.Nullable(f(n))}case\"Or\":{const[,...n]=e;return c.Or(...n.map(f))}case\"Tuple\":{const[,n,...r]=e;return c.Tuple(f(n),...r.map(f))}case\"Array\":{const[,n]=e;return c.Array(f(n))}case\"Struct\":{const[,...n]=e,r=n.map((([e,n])=>[e,f(n)]));return c.Struct((0,l.to_object)(r))}case\"Dict\":{const[,n]=e;return c.Dict(f(n))}case\"Map\":{const[,n,r]=e;return c.Map(f(n),f(r))}case\"Enum\":{const[,...n]=e;return c.Enum(...n)}case\"Ref\":{const[,r]=e,t=n.get(i(r));if(null!=t)return c.Ref(t);throw new Error(`${i(r)} wasn't defined before referencing it`)}case\"AnyRef\":return c.AnyRef()}}for(const c of e){const e=(()=>{if(null==c.extends)return u.Model;{const e=n.get(i(c.extends));if(null!=e)return e;throw new Error(`base model ${i(c.extends)} of ${i(c)} is not defined`)}})(),a=((s=class extends e{}).__name__=c.name,s.__module__=c.module,s);for(const e of null!==(r=c.properties)&&void 0!==r?r:[]){const n=f(null!==(t=e.kind)&&void 0!==t?t:\"Unknown\");a.define({[e.name]:[n,e.default]})}for(const e of null!==(o=c.overrides)&&void 0!==o?o:[])a.override({[e.name]:e.default});n.register(a)}}},\n", - " function _(n,e,t,o,i){o();const d=n(5),c=n(226),s=n(113),a=n(43),l=n(398);t.index={},t.add_document_standalone=async function(n,e,o=[],i=!1){const u=new Map;async function f(i){let d;const f=n.roots().indexOf(i),r=o[f];null!=r?d=r:e.classList.contains(l.BOKEH_ROOT)?d=e:(d=(0,a.div)({class:l.BOKEH_ROOT}),e.appendChild(d));const w=await(0,s.build_view)(i,{parent:null});return w instanceof c.DOMView&&w.renderTo(d),u.set(i,w),t.index[i.id]=w,w}for(const e of n.roots())await f(e);return i&&(window.document.title=n.title()),n.on_change((n=>{n instanceof d.RootAddedEvent?f(n.model):n instanceof d.RootRemovedEvent?function(n){const e=u.get(n);null!=e&&(e.remove(),u.delete(n),delete t.index[n.id])}(n.model):i&&n instanceof d.TitleChangedEvent&&(window.document.title=n.title)})),[...u.values()]}},\n", - " function _(o,e,n,t,r){t();const l=o(43),d=o(44);function u(o){let e=document.getElementById(o);if(null==e)throw new Error(`Error rendering Bokeh model: could not find #${o} HTML tag`);if(!document.body.contains(e))throw new Error(`Error rendering Bokeh model: element #${o} must be under `);if(\"SCRIPT\"==e.tagName){const o=(0,l.div)({class:n.BOKEH_ROOT});(0,l.replaceWith)(e,o),e=o}return e}n.BOKEH_ROOT=d.root,n._resolve_element=function(o){const{elementid:e}=o;return null!=e?u(e):document.body},n._resolve_root_elements=function(o){const e=[];if(null!=o.root_ids&&null!=o.roots)for(const n of o.root_ids)e.push(u(o.roots[n]));return e}},\n", - " function _(n,o,t,s,e){s();const c=n(400),r=n(19),a=n(397);t._get_ws_url=function(n,o){let t,s=\"ws:\";return\"https:\"==window.location.protocol&&(s=\"wss:\"),null!=o?(t=document.createElement(\"a\"),t.href=o):t=window.location,null!=n?\"/\"==n&&(n=\"\"):n=t.pathname.replace(/\\/+$/,\"\"),`${s}//${t.host}${n}/ws`};const i={};t.add_document_from_session=async function(n,o,t,s=[],e=!1){const l=window.location.search.substr(1);let d;try{d=await function(n,o,t){const s=(0,c.parse_token)(o).session_id;n in i||(i[n]={});const e=i[n];return s in e||(e[s]=(0,c.pull_session)(n,o,t)),e[s]}(n,o,l)}catch(n){const t=(0,c.parse_token)(o).session_id;throw r.logger.error(`Failed to load Bokeh session ${t}: ${n}`),n}return(0,a.add_document_standalone)(d.document,t,s,e)}},\n", - " function _(e,s,n,t,o){t();const r=e(19),i=e(5),c=e(401),l=e(402),_=e(403);n.DEFAULT_SERVER_WEBSOCKET_URL=\"ws://localhost:5006/ws\",n.DEFAULT_TOKEN=\"eyJzZXNzaW9uX2lkIjogImRlZmF1bHQifQ\";let h=0;function a(e){let s=e.split(\".\")[0];const n=s.length%4;return 0!=n&&(s+=\"=\".repeat(4-n)),JSON.parse(atob(s.replace(/_/g,\"/\").replace(/-/g,\"+\")))}n.parse_token=a;class d{constructor(e=n.DEFAULT_SERVER_WEBSOCKET_URL,s=n.DEFAULT_TOKEN,t=null){this.url=e,this.token=s,this.args_string=t,this._number=h++,this.socket=null,this.session=null,this.closed_permanently=!1,this._current_handler=null,this._pending_replies=new Map,this._pending_messages=[],this._receiver=new l.Receiver,this.id=a(s).session_id.split(\".\")[0],r.logger.debug(`Creating websocket ${this._number} to '${this.url}' session '${this.id}'`)}async connect(){if(this.closed_permanently)throw new Error(\"Cannot connect() a closed ClientConnection\");if(null!=this.socket)throw new Error(\"Already connected\");this._current_handler=null,this._pending_replies.clear(),this._pending_messages=[];try{let e=`${this.url}`;return null!=this.args_string&&this.args_string.length>0&&(e+=`?${this.args_string}`),this.socket=new WebSocket(e,[\"bokeh\",this.token]),new Promise(((e,s)=>{this.socket.binaryType=\"arraybuffer\",this.socket.onopen=()=>this._on_open(e,s),this.socket.onmessage=e=>this._on_message(e),this.socket.onclose=e=>this._on_close(e,s),this.socket.onerror=()=>this._on_error(s)}))}catch(e){throw r.logger.error(`websocket creation failed to url: ${this.url}`),r.logger.error(` - ${e}`),e}}close(){this.closed_permanently||(r.logger.debug(`Permanently closing websocket connection ${this._number}`),this.closed_permanently=!0,null!=this.socket&&this.socket.close(1e3,`close method called on ClientConnection ${this._number}`),this.session._connection_closed())}_schedule_reconnect(e){setTimeout((()=>{this.closed_permanently||r.logger.info(`Websocket connection ${this._number} disconnected, will not attempt to reconnect`)}),e)}send(e){if(null==this.socket)throw new Error(`not connected so cannot send ${e}`);e.send(this.socket)}async send_with_reply(e){const s=await new Promise(((s,n)=>{this._pending_replies.set(e.msgid(),{resolve:s,reject:n}),this.send(e)}));if(\"ERROR\"===s.msgtype())throw new Error(`Error reply ${s.content.text}`);return s}async _pull_doc_json(){const e=c.Message.create(\"PULL-DOC-REQ\",{}),s=await this.send_with_reply(e);if(!(\"doc\"in s.content))throw new Error(\"No 'doc' field in PULL-DOC-REPLY\");return s.content.doc}async _repull_session_doc(e,s){var n;r.logger.debug(this.session?\"Repulling session\":\"Pulling session for first time\");try{const n=await this._pull_doc_json();if(null==this.session)if(this.closed_permanently)r.logger.debug(\"Got new document after connection was already closed\"),s(new Error(\"The connection has been closed\"));else{const s=i.Document.from_json(n),t=i.Document._compute_patch_since_json(n,s);if(t.events.length>0){r.logger.debug(`Sending ${t.events.length} changes from model construction back to server`);const e=c.Message.create(\"PATCH-DOC\",{},t);this.send(e)}this.session=new _.ClientSession(this,s,this.id);for(const e of this._pending_messages)this.session.handle(e);this._pending_messages=[],r.logger.debug(\"Created a new session from new pulled doc\"),e(this.session)}else this.session.document.replace_with_json(n),r.logger.debug(\"Updated existing session with new pulled doc\")}catch(e){null===(n=console.trace)||void 0===n||n.call(console,e),r.logger.error(`Failed to repull session ${e}`),s(e instanceof Error?e:`${e}`)}}_on_open(e,s){r.logger.info(`Websocket connection ${this._number} is now open`),this._current_handler=n=>{this._awaiting_ack_handler(n,e,s)}}_on_message(e){null==this._current_handler&&r.logger.error(\"Got a message with no current handler set\");try{this._receiver.consume(e.data)}catch(e){this._close_bad_protocol(`${e}`)}const s=this._receiver.message;if(null!=s){const e=s.problem();null!=e&&this._close_bad_protocol(e),this._current_handler(s)}}_on_close(e,s){r.logger.info(`Lost websocket ${this._number} connection, ${e.code} (${e.reason})`),this.socket=null,this._pending_replies.forEach((e=>e.reject(\"Disconnected\"))),this._pending_replies.clear(),this.closed_permanently||this._schedule_reconnect(2e3),s(new Error(`Lost websocket connection, ${e.code} (${e.reason})`))}_on_error(e){r.logger.debug(`Websocket error on socket ${this._number}`);const s=\"Could not open websocket\";r.logger.error(`Failed to connect to Bokeh server: ${s}`),e(new Error(s))}_close_bad_protocol(e){r.logger.error(`Closing connection: ${e}`),null!=this.socket&&this.socket.close(1002,e)}_awaiting_ack_handler(e,s,n){\"ACK\"===e.msgtype()?(this._current_handler=e=>this._steady_state_handler(e),this._repull_session_doc(s,n)):this._close_bad_protocol(\"First message was not an ACK\")}_steady_state_handler(e){const s=e.reqid(),n=this._pending_replies.get(s);n?(this._pending_replies.delete(s),n.resolve(e)):this.session?this.session.handle(e):\"PATCH-DOC\"!=e.msgtype()&&this._pending_messages.push(e)}}n.ClientConnection=d,d.__name__=\"ClientConnection\",n.pull_session=function(e,s,n){return new d(e,s,n).connect()}},\n", - " function _(e,s,t,r,n){r();const i=e(34);class a{constructor(e,s,t){this.header=e,this.metadata=s,this.content=t,this.buffers=new Map}static assemble(e,s,t){const r=JSON.parse(e),n=JSON.parse(s),i=JSON.parse(t);return new a(r,n,i)}assemble_buffer(e,s){const t=null!=this.header.num_buffers?this.header.num_buffers:0;if(t<=this.buffers.size)throw new Error(`too many buffers received, expecting ${t}`);const{id:r}=JSON.parse(e);this.buffers.set(r,s)}static create(e,s,t={}){const r=a.create_header(e);return new a(r,s,t)}static create_header(e){return{msgid:(0,i.uniqueId)(),msgtype:e}}complete(){return null!=this.header&&null!=this.metadata&&null!=this.content&&(null==this.header.num_buffers||this.buffers.size==this.header.num_buffers)}send(e){if((null!=this.header.num_buffers?this.header.num_buffers:0)>0)throw new Error(\"BokehJS only supports receiving buffers, not sending\");const s=JSON.stringify(this.header),t=JSON.stringify(this.metadata),r=JSON.stringify(this.content);e.send(s),e.send(t),e.send(r)}msgid(){return this.header.msgid}msgtype(){return this.header.msgtype}reqid(){return this.header.reqid}problem(){return\"msgid\"in this.header?\"msgtype\"in this.header?null:\"No msgtype in header\":\"No msgid in header\"}}t.Message=a,a.__name__=\"Message\"},\n", - " function _(e,t,s,_,r){_();const i=e(401),h=e(8);class a{constructor(){this.message=null,this._partial=null,this._fragments=[],this._buf_header=null,this._current_consumer=this._HEADER}consume(e){this._current_consumer(e)}_HEADER(e){this._assume_text(e),this.message=null,this._partial=null,this._fragments=[e],this._buf_header=null,this._current_consumer=this._METADATA}_METADATA(e){this._assume_text(e),this._fragments.push(e),this._current_consumer=this._CONTENT}_CONTENT(e){this._assume_text(e),this._fragments.push(e);const[t,s,_]=this._fragments.slice(0,3);this._partial=i.Message.assemble(t,s,_),this._check_complete()}_BUFFER_HEADER(e){this._assume_text(e),this._buf_header=e,this._current_consumer=this._BUFFER_PAYLOAD}_BUFFER_PAYLOAD(e){this._assume_binary(e),this._partial.assemble_buffer(this._buf_header,e),this._check_complete()}_assume_text(e){if(!(0,h.isString)(e))throw new Error(\"Expected text fragment but received binary fragment\")}_assume_binary(e){if(!(e instanceof ArrayBuffer))throw new Error(\"Expected binary fragment but received text fragment\")}_check_complete(){this._partial.complete()?(this.message=this._partial,this._current_consumer=this._HEADER):this._current_consumer=this._BUFFER_HEADER}}s.Receiver=a,a.__name__=\"Receiver\"},\n", - " function _(e,t,n,s,o){s();const c=e(5),i=e(401),_=e(19);class r{constructor(e,t,n){this._connection=e,this.document=t,this.id=n,this._document_listener=e=>{this._document_changed(e)},this.document.on_change(this._document_listener,!0)}handle(e){const t=e.msgtype();\"PATCH-DOC\"===t?this._handle_patch(e):\"OK\"===t?this._handle_ok(e):\"ERROR\"===t?this._handle_error(e):_.logger.debug(`Doing nothing with message ${e.msgtype()}`)}close(){this._connection.close()}_connection_closed(){this.document.remove_on_change(this._document_listener)}async request_server_info(){const e=i.Message.create(\"SERVER-INFO-REQ\",{});return(await this._connection.send_with_reply(e)).content}async force_roundtrip(){await this.request_server_info()}_document_changed(e){if(e.setter_id===this.id)return;const t=e instanceof c.DocumentEventBatch?e.events:[e],n=this.document.create_json_patch(t),s=i.Message.create(\"PATCH-DOC\",{},n);this._connection.send(s)}_handle_patch(e){this.document.apply_json_patch(e.content,e.buffers,this.id)}_handle_ok(e){_.logger.trace(`Unhandled OK reply to ${e.reqid()}`)}_handle_error(e){_.logger.error(`Unhandled ERROR reply to ${e.reqid()}: ${e.content.text}`)}}n.ClientSession=r,r.__name__=\"ClientSession\"},\n", - " function _(e,o,t,n,r){n();const s=e(1),l=e(5),i=e(402),a=e(19),c=e(43),g=e(13),f=e(397),u=e(398),m=(0,s.__importDefault)(e(44)),p=(0,s.__importDefault)(e(240)),d=(0,s.__importDefault)(e(405));function _(e,o){o.buffers.length>0?e.consume(o.buffers[0].buffer):e.consume(o.content.data);const t=e.message;null!=t&&this.apply_json_patch(t.content,t.buffers)}function b(e,o){if(\"undefined\"!=typeof Jupyter&&null!=Jupyter.notebook.kernel){a.logger.info(`Registering Jupyter comms for target ${e}`);const t=Jupyter.notebook.kernel.comm_manager;try{t.register_target(e,(t=>{a.logger.info(`Registering Jupyter comms for target ${e}`);const n=new i.Receiver;t.on_msg(_.bind(o,n))}))}catch(e){a.logger.warn(`Jupyter comms failed to register. push_notebook() will not function. (exception reported: ${e})`)}}else if(o.roots()[0].id in t.kernels){a.logger.info(`Registering JupyterLab comms for target ${e}`);const n=t.kernels[o.roots()[0].id];try{n.registerCommTarget(e,(t=>{a.logger.info(`Registering JupyterLab comms for target ${e}`);const n=new i.Receiver;t.onMsg=_.bind(o,n)}))}catch(e){a.logger.warn(`Jupyter comms failed to register. push_notebook() will not function. (exception reported: ${e})`)}}else if(\"undefined\"!=typeof google&&null!=google.colab.kernel){a.logger.info(`Registering Google Colab comms for target ${e}`);const t=google.colab.kernel.comms;try{t.registerTarget(e,(async t=>{var n,r,l;a.logger.info(`Registering Google Colab comms for target ${e}`);const c=new i.Receiver;try{for(var g,f=(0,s.__asyncValues)(t.messages);!(g=await f.next()).done;){const e=g.value,t={data:e.data},n=[];for(const o of null!==(l=e.buffers)&&void 0!==l?l:[])n.push(new DataView(o));const r={content:t,buffers:n};_.bind(o)(c,r)}}catch(e){n={error:e}}finally{try{g&&!g.done&&(r=f.return)&&await r.call(f)}finally{if(n)throw n.error}}}))}catch(e){a.logger.warn(`Google Colab comms failed to register. push_notebook() will not function. (exception reported: ${e})`)}}else console.warn(\"Jupyter notebooks comms not available. push_notebook() will not function. If running JupyterLab ensure the latest @bokeh/jupyter_bokeh extension is installed. In an exported notebook this warning is expected.\")}c.stylesheet.append(m.default),c.stylesheet.append(p.default),c.stylesheet.append(d.default),t.kernels={},t.embed_items_notebook=function(e,o){if(1!=(0,g.size)(e))throw new Error(\"embed_items_notebook expects exactly one document in docs_json\");const t=l.Document.from_json((0,g.values)(e)[0]);for(const e of o){null!=e.notebook_comms_target&&b(e.notebook_comms_target,t);const o=(0,u._resolve_element)(e),n=(0,u._resolve_root_elements)(e);(0,f.add_document_standalone)(t,o,n)}}},\n", - " function _(t,o,r,e,d){e(),r.root=\"bk-root\",r.tooltip=\"bk-tooltip\",r.default=\".rendered_html .bk-root .bk-tooltip table,.rendered_html .bk-root .bk-tooltip tr,.rendered_html .bk-root .bk-tooltip th,.rendered_html .bk-root .bk-tooltip td{border:none;padding:1px;}\"},\n", - " function _(t,_,o,r,n){r();const a=t(1);(0,a.__exportStar)(t(401),o),(0,a.__exportStar)(t(402),o)},\n", - " function _(e,t,n,s,o){function l(){const e=document.getElementsByTagName(\"body\")[0],t=document.getElementsByClassName(\"bokeh-test-div\");1==t.length&&(e.removeChild(t[0]),delete t[0]);const n=document.createElement(\"div\");n.classList.add(\"bokeh-test-div\"),n.style.display=\"none\",e.insertBefore(n,e.firstChild)}s(),n.results={},n.init=function(){l()},n.record0=function(e,t){n.results[e]=t},n.record=function(e,t){n.results[e]=t,l()},n.count=function(e){null==n.results[e]&&(n.results[e]=0),n.results[e]+=1,l()}},\n", - " function _(e,t,o,n,l){n(),o.safely=function(e,t=!1){try{return e()}catch(e){if(function(e){const t=document.createElement(\"div\");t.style.backgroundColor=\"#f2dede\",t.style.border=\"1px solid #a94442\",t.style.borderRadius=\"4px\",t.style.display=\"inline-block\",t.style.fontFamily=\"sans-serif\",t.style.marginTop=\"5px\",t.style.minWidth=\"200px\",t.style.padding=\"5px 5px 5px 10px\",t.classList.add(\"bokeh-error-box-into-flames\");const o=document.createElement(\"span\");o.style.backgroundColor=\"#a94442\",o.style.borderRadius=\"0px 4px 0px 0px\",o.style.color=\"white\",o.style.cursor=\"pointer\",o.style.cssFloat=\"right\",o.style.fontSize=\"0.8em\",o.style.margin=\"-6px -6px 0px 0px\",o.style.padding=\"2px 5px 4px 5px\",o.title=\"close\",o.setAttribute(\"aria-label\",\"close\"),o.appendChild(document.createTextNode(\"x\")),o.addEventListener(\"click\",(()=>s.removeChild(t)));const n=document.createElement(\"h3\");n.style.color=\"#a94442\",n.style.margin=\"8px 0px 0px 0px\",n.style.padding=\"0px\",n.appendChild(document.createTextNode(\"Bokeh Error\"));const l=document.createElement(\"pre\");l.style.whiteSpace=\"unset\",l.style.overflowX=\"auto\",l.appendChild(document.createTextNode(e)),t.appendChild(o),t.appendChild(n),t.appendChild(l);const s=document.getElementsByTagName(\"body\")[0];s.insertBefore(t,s.firstChild)}(e instanceof Error&&e.stack?e.stack:`${e}`),t)return;throw e}}},\n", - " ], 0, {\"main\":0,\"tslib\":1,\"index\":2,\"version\":3,\"embed/index\":4,\"document/index\":5,\"document/document\":6,\"base\":7,\"core/util/types\":8,\"core/util/array\":9,\"core/util/math\":10,\"core/util/assert\":11,\"core/util/arrayable\":12,\"core/util/object\":13,\"core/has_props\":14,\"core/signaling\":15,\"core/util/defer\":16,\"core/util/refs\":17,\"core/properties\":18,\"core/logging\":19,\"core/enums\":20,\"core/kinds\":21,\"core/util/color\":22,\"core/util/svg_colors\":23,\"core/types\":24,\"core/util/bitset\":25,\"core/util/eq\":26,\"core/util/platform\":27,\"core/settings\":28,\"core/util/ndarray\":29,\"core/serializer\":30,\"core/util/serialization\":31,\"core/util/buffer\":32,\"core/uniforms\":33,\"core/util/string\":34,\"document/events\":35,\"core/util/pretty\":36,\"core/util/cloneable\":37,\"models/index\":38,\"models/annotations/index\":39,\"models/annotations/annotation\":40,\"models/renderers/renderer\":41,\"core/view\":42,\"core/dom\":43,\"styles/root.css\":44,\"core/visuals/index\":45,\"core/visuals/line\":46,\"core/visuals/visual\":47,\"core/property_mixins\":48,\"core/visuals/fill\":49,\"core/visuals/text\":50,\"core/visuals/hatch\":51,\"core/visuals/patterns\":52,\"model\":53,\"models/canvas/coordinates\":54,\"models/scales/scale\":55,\"models/transforms/transform\":56,\"models/ranges/range\":57,\"models/ranges/range1d\":58,\"models/scales/linear_scale\":59,\"models/scales/continuous_scale\":60,\"models/scales/log_scale\":61,\"models/scales/categorical_scale\":62,\"models/ranges/data_range1d\":63,\"models/ranges/data_range\":64,\"core/util/bbox\":65,\"models/util\":66,\"models/ranges/factor_range\":67,\"models/annotations/arrow\":68,\"models/annotations/data_annotation\":69,\"models/sources/columnar_data_source\":70,\"models/sources/data_source\":71,\"models/selections/selection\":72,\"core/selection_manager\":73,\"models/selections/interaction_policy\":74,\"models/sources/column_data_source\":75,\"core/util/typed_array\":76,\"core/util/set\":77,\"core/util/projections\":78,\"models/annotations/arrow_head\":112,\"core/build_views\":113,\"models/annotations/band\":114,\"models/annotations/upper_lower\":115,\"models/annotations/box_annotation\":116,\"models/annotations/color_bar\":117,\"models/annotations/title\":118,\"models/annotations/text_annotation\":119,\"core/graphics\":120,\"core/util/text\":121,\"core/util/affine\":122,\"core/layout/side_panel\":123,\"core/layout/types\":124,\"core/layout/layoutable\":125,\"models/canvas/cartesian_frame\":126,\"models/axes/index\":127,\"models/axes/axis\":128,\"models/renderers/guide_renderer\":129,\"models/tickers/ticker\":130,\"models/formatters/tick_formatter\":131,\"models/policies/labeling\":132,\"models/text/base_text\":133,\"models/text/utils\":134,\"models/text/math_text\":135,\"core/util/image\":136,\"models/text/providers\":137,\"core/util/modules\":138,\"models/text/plain_text\":139,\"models/axes/categorical_axis\":140,\"models/tickers/categorical_ticker\":141,\"models/formatters/categorical_tick_formatter\":142,\"models/axes/continuous_axis\":143,\"models/axes/datetime_axis\":144,\"models/axes/linear_axis\":145,\"models/formatters/basic_tick_formatter\":146,\"models/tickers/basic_ticker\":147,\"models/tickers/adaptive_ticker\":148,\"models/tickers/continuous_ticker\":149,\"models/formatters/datetime_tick_formatter\":150,\"core/util/templating\":152,\"models/tickers/datetime_ticker\":155,\"models/tickers/composite_ticker\":156,\"models/tickers/days_ticker\":157,\"models/tickers/single_interval_ticker\":158,\"models/tickers/util\":159,\"models/tickers/months_ticker\":160,\"models/tickers/years_ticker\":161,\"models/axes/log_axis\":162,\"models/formatters/log_tick_formatter\":163,\"models/tickers/log_ticker\":164,\"models/axes/mercator_axis\":165,\"models/formatters/mercator_tick_formatter\":166,\"models/tickers/mercator_ticker\":167,\"models/tickers/index\":168,\"models/tickers/fixed_ticker\":169,\"models/tickers/binned_ticker\":170,\"models/mappers/scanning_color_mapper\":171,\"models/mappers/continuous_color_mapper\":172,\"models/mappers/color_mapper\":173,\"models/mappers/mapper\":174,\"models/renderers/glyph_renderer\":175,\"models/renderers/data_renderer\":176,\"models/glyphs/line\":177,\"models/glyphs/xy_glyph\":178,\"models/glyphs/glyph\":179,\"core/util/ragged_array\":180,\"core/util/spatial\":181,\"models/glyphs/utils\":184,\"core/hittest\":185,\"models/glyphs/patch\":186,\"models/glyphs/harea\":187,\"models/glyphs/area\":188,\"models/glyphs/varea\":189,\"models/sources/cds_view\":190,\"models/filters/filter\":191,\"models/formatters/index\":192,\"models/formatters/func_tick_formatter\":193,\"models/formatters/numeral_tick_formatter\":194,\"models/formatters/printf_tick_formatter\":195,\"models/mappers/index\":196,\"models/mappers/categorical_color_mapper\":197,\"models/mappers/categorical_mapper\":198,\"models/mappers/categorical_marker_mapper\":199,\"models/mappers/categorical_pattern_mapper\":200,\"models/mappers/linear_color_mapper\":201,\"models/mappers/log_color_mapper\":202,\"models/mappers/eqhist_color_mapper\":203,\"models/scales/index\":204,\"models/scales/linear_interpolation_scale\":205,\"models/ranges/index\":206,\"core/layout/index\":207,\"core/layout/alignments\":208,\"core/layout/grid\":209,\"core/layout/html\":210,\"core/layout/border\":211,\"models/annotations/label\":212,\"models/annotations/label_set\":213,\"models/annotations/legend\":214,\"models/annotations/legend_item\":215,\"core/vectorization\":216,\"models/annotations/poly_annotation\":217,\"models/annotations/slope\":218,\"models/annotations/span\":219,\"models/annotations/toolbar_panel\":220,\"models/tools/toolbar\":221,\"models/tools/tool\":222,\"models/tools/gestures/gesture_tool\":223,\"models/tools/button_tool\":224,\"core/dom_view\":226,\"styles/toolbar.css\":227,\"styles/icons.css\":228,\"styles/menus.css\":229,\"core/util/menus\":230,\"models/tools/on_off_button\":231,\"models/tools/inspectors/inspect_tool\":232,\"models/tools/toolbar_base\":233,\"core/util/iterator\":234,\"core/util/canvas\":235,\"core/util/svg\":236,\"core/util/random\":237,\"models/tools/actions/action_tool\":238,\"models/tools/actions/help_tool\":239,\"styles/logo.css\":240,\"models/annotations/tooltip\":241,\"styles/tooltips.css\":242,\"models/annotations/whisker\":243,\"models/callbacks/index\":244,\"models/callbacks/customjs\":245,\"models/callbacks/callback\":246,\"models/callbacks/open_url\":247,\"models/canvas/index\":248,\"models/canvas/canvas\":249,\"core/ui_events\":250,\"core/bokeh_events\":251,\"core/util/wheel\":252,\"models/expressions/index\":253,\"models/expressions/expression\":254,\"models/expressions/customjs_expr\":255,\"models/expressions/stack\":256,\"models/expressions/cumsum\":257,\"models/expressions/minimum\":258,\"models/expressions/maximum\":259,\"models/expressions/coordinate_transform\":260,\"models/expressions/polar\":261,\"models/filters/index\":262,\"models/filters/boolean_filter\":263,\"models/filters/customjs_filter\":264,\"models/filters/group_filter\":265,\"models/filters/index_filter\":266,\"models/glyphs/index\":267,\"models/glyphs/annular_wedge\":268,\"models/glyphs/annulus\":269,\"models/glyphs/arc\":270,\"models/glyphs/bezier\":271,\"models/glyphs/circle\":272,\"models/glyphs/ellipse\":273,\"models/glyphs/ellipse_oval\":274,\"models/glyphs/center_rotatable\":275,\"models/glyphs/hbar\":276,\"models/glyphs/box\":277,\"models/glyphs/hex_tile\":278,\"models/glyphs/image\":279,\"models/glyphs/image_base\":280,\"models/glyphs/image_rgba\":281,\"models/glyphs/image_url\":282,\"models/glyphs/multi_line\":283,\"models/glyphs/multi_polygons\":284,\"models/glyphs/oval\":285,\"models/glyphs/patches\":286,\"models/glyphs/quad\":287,\"models/glyphs/quadratic\":288,\"models/glyphs/ray\":289,\"models/glyphs/rect\":290,\"models/glyphs/scatter\":291,\"models/glyphs/marker\":292,\"models/glyphs/defs\":293,\"models/glyphs/segment\":294,\"models/glyphs/spline\":295,\"core/util/interpolation\":296,\"models/glyphs/step\":297,\"models/glyphs/text\":298,\"models/glyphs/vbar\":299,\"models/glyphs/wedge\":300,\"models/graphs/index\":301,\"models/graphs/graph_hit_test_policy\":302,\"models/graphs/layout_provider\":303,\"models/graphs/static_layout_provider\":304,\"models/grids/index\":305,\"models/grids/grid\":306,\"models/layouts/index\":307,\"models/layouts/box\":308,\"models/layouts/layout_dom\":309,\"models/layouts/column\":310,\"models/layouts/grid_box\":311,\"models/layouts/html_box\":312,\"models/layouts/panel\":313,\"models/layouts/row\":314,\"models/layouts/spacer\":315,\"models/layouts/tabs\":316,\"styles/tabs.css\":317,\"styles/buttons.css\":318,\"models/layouts/widget_box\":319,\"models/text/index\":320,\"models/transforms/index\":321,\"models/transforms/customjs_transform\":322,\"models/transforms/dodge\":323,\"models/transforms/range_transform\":324,\"models/transforms/interpolator\":325,\"models/transforms/jitter\":326,\"models/transforms/linear_interpolator\":327,\"models/transforms/step_interpolator\":328,\"models/plots/index\":329,\"models/plots/gmap_plot\":330,\"models/plots/plot\":331,\"models/plots/plot_canvas\":332,\"core/util/throttle\":333,\"models/plots/range_manager\":334,\"models/plots/state_manager\":335,\"models/plots/gmap_plot_canvas\":336,\"models/policies/index\":337,\"models/renderers/index\":338,\"models/renderers/graph_renderer\":339,\"models/selections/index\":340,\"models/sources/index\":341,\"models/sources/server_sent_data_source\":342,\"models/sources/web_data_source\":343,\"models/sources/ajax_data_source\":344,\"models/sources/geojson_data_source\":345,\"models/tiles/index\":346,\"models/tiles/bbox_tile_source\":347,\"models/tiles/mercator_tile_source\":348,\"models/tiles/tile_source\":349,\"models/tiles/tile_utils\":350,\"models/tiles/quadkey_tile_source\":351,\"models/tiles/tile_renderer\":352,\"models/tiles/wmts_tile_source\":353,\"styles/tiles.css\":354,\"models/tiles/tms_tile_source\":355,\"models/textures/index\":356,\"models/textures/canvas_texture\":357,\"models/textures/texture\":358,\"models/textures/image_url_texture\":359,\"models/tools/index\":360,\"models/tools/actions/custom_action\":361,\"models/tools/actions/redo_tool\":362,\"models/tools/actions/reset_tool\":363,\"models/tools/actions/save_tool\":364,\"models/tools/actions/undo_tool\":365,\"models/tools/actions/zoom_in_tool\":366,\"models/tools/actions/zoom_base_tool\":367,\"core/util/zoom\":368,\"models/tools/actions/zoom_out_tool\":369,\"models/tools/edit/edit_tool\":370,\"models/tools/edit/box_edit_tool\":371,\"models/tools/edit/freehand_draw_tool\":372,\"models/tools/edit/point_draw_tool\":373,\"models/tools/edit/poly_draw_tool\":374,\"models/tools/edit/poly_tool\":375,\"models/tools/edit/poly_edit_tool\":376,\"models/tools/gestures/box_select_tool\":377,\"models/tools/gestures/select_tool\":378,\"models/tools/gestures/box_zoom_tool\":379,\"models/tools/gestures/lasso_select_tool\":380,\"models/tools/gestures/poly_select_tool\":381,\"models/tools/edit/line_edit_tool\":382,\"models/tools/edit/line_tool\":383,\"models/tools/gestures/pan_tool\":384,\"models/tools/gestures/range_tool\":385,\"models/tools/gestures/tap_tool\":386,\"models/tools/gestures/wheel_pan_tool\":387,\"models/tools/gestures/wheel_zoom_tool\":388,\"models/tools/inspectors/crosshair_tool\":389,\"models/tools/inspectors/customjs_hover\":390,\"models/tools/inspectors/hover_tool\":391,\"models/dom/index\":392,\"models/dom/styles\":393,\"models/tools/tool_proxy\":394,\"models/tools/toolbar_box\":395,\"document/defs\":396,\"embed/standalone\":397,\"embed/dom\":398,\"embed/server\":399,\"client/connection\":400,\"protocol/message\":401,\"protocol/receiver\":402,\"client/session\":403,\"embed/notebook\":404,\"styles/notebook.css\":405,\"protocol/index\":406,\"testing\":407,\"safely\":408}, {});});\n", - "\n", - " /* END bokeh.min.js */\n", - " },\n", - " function(Bokeh) {\n", - " /* BEGIN bokeh-gl.min.js */\n", - " /*!\n", - " * Copyright (c) 2012 - 2022, Anaconda, Inc., and Bokeh Contributors\n", - " * All rights reserved.\n", - " * \n", - " * Redistribution and use in source and binary forms, with or without modification,\n", - " * are permitted provided that the following conditions are met:\n", - " * \n", - " * Redistributions of source code must retain the above copyright notice,\n", - " * this list of conditions and the following disclaimer.\n", - " * \n", - " * Redistributions in binary form must reproduce the above copyright notice,\n", - " * this list of conditions and the following disclaimer in the documentation\n", - " * and/or other materials provided with the distribution.\n", - " * \n", - " * Neither the name of Anaconda nor the names of any contributors\n", - " * may be used to endorse or promote products derived from this software\n", - " * without specific prior written permission.\n", - " * \n", - " * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n", - " * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n", - " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n", - " * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n", - " * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n", - " * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n", - " * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n", - " * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n", - " * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n", - " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n", - " * THE POSSIBILITY OF SUCH DAMAGE.\n", - " */\n", - " (function(root, factory) {\n", - " factory(root[\"Bokeh\"], \"2.4.3\");\n", - " })(this, function(Bokeh, version) {\n", - " let define;\n", - " return (function(modules, entry, aliases, externals) {\n", - " const bokeh = typeof Bokeh !== \"undefined\" && (version != null ? Bokeh[version] : Bokeh);\n", - " if (bokeh != null) {\n", - " return bokeh.register_plugin(modules, entry, aliases);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh \" + version + \". You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " 409: function _(n,c,f,i,o){i(),n(410)},\n", - " 410: function _(t,_,r,e,o){e();const a=t(1);o(\"get_regl\",t(411).get_regl),(0,a.__exportStar)(t(419),r),(0,a.__exportStar)(t(423),r),(0,a.__exportStar)(t(425),r),(0,a.__exportStar)(t(426),r),(0,a.__exportStar)(t(427),r),(0,a.__exportStar)(t(428),r),(0,a.__exportStar)(t(429),r),(0,a.__exportStar)(t(424),r)},\n", - " 411: function _(t,i,e,_,a){_();const r=t(1),o=(0,r.__importDefault)(t(412)),n=t(413),s=(0,r.__importDefault)(t(415)),l=(0,r.__importDefault)(t(416)),p=(0,r.__importDefault)(t(417)),h=(0,r.__importDefault)(t(418));let c;e.get_regl=function(t){return null==c&&(c=new u(t)),c};class u{constructor(t){try{this._regl=(0,o.default)({gl:t,extensions:[\"ANGLE_instanced_arrays\",\"EXT_blend_minmax\"]}),this._regl_available=!0,this._line_geometry=this._regl.buffer({usage:\"static\",type:\"float\",data:[[-2,0],[-1,-1],[1,-1],[2,0],[1,1],[-1,1]]}),this._line_triangles=this._regl.elements({usage:\"static\",primitive:\"triangles\",data:[[0,1,5],[1,2,5],[5,2,4],[2,3,4]]})}catch(t){this._regl_available=!1}}buffer(t){return this._regl.buffer(t)}clear(t,i){this._viewport={x:0,y:0,width:t,height:i},this._regl.clear({color:[0,0,0,0]})}get has_webgl(){return this._regl_available}get scissor(){return this._scissor}set_scissor(t,i,e,_){this._scissor={x:t,y:i,width:e,height:_}}get viewport(){return this._viewport}dashed_line(){return null==this._dashed_line&&(this._dashed_line=function(t,i,e){const _={vert:`#define DASHED\\n\\n${s.default}`,frag:`#define DASHED\\n\\n${l.default}`,attributes:{a_position:{buffer:i,divisor:0},a_point_prev:(t,i)=>i.points.to_attribute_config(),a_point_start:(t,i)=>i.points.to_attribute_config(2*Float32Array.BYTES_PER_ELEMENT),a_point_end:(t,i)=>i.points.to_attribute_config(4*Float32Array.BYTES_PER_ELEMENT),a_point_next:(t,i)=>i.points.to_attribute_config(6*Float32Array.BYTES_PER_ELEMENT),a_show_prev:(t,i)=>i.show.to_attribute_config(),a_show_curr:(t,i)=>i.show.to_attribute_config(Uint8Array.BYTES_PER_ELEMENT),a_show_next:(t,i)=>i.show.to_attribute_config(2*Uint8Array.BYTES_PER_ELEMENT),a_length_so_far:(t,i)=>i.length_so_far.to_attribute_config()},uniforms:{u_canvas_size:t.prop(\"canvas_size\"),u_pixel_ratio:t.prop(\"pixel_ratio\"),u_antialias:t.prop(\"antialias\"),u_line_color:t.prop(\"line_color\"),u_linewidth:t.prop(\"linewidth\"),u_miter_limit:t.prop(\"miter_limit\"),u_line_join:t.prop(\"line_join\"),u_line_cap:t.prop(\"line_cap\"),u_dash_tex:t.prop(\"dash_tex\"),u_dash_tex_info:t.prop(\"dash_tex_info\"),u_dash_scale:t.prop(\"dash_scale\"),u_dash_offset:t.prop(\"dash_offset\")},elements:e,instances:t.prop(\"nsegments\"),blend:{enable:!0,equation:\"max\",func:{srcRGB:1,srcAlpha:1,dstRGB:1,dstAlpha:1}},depth:{enable:!1},scissor:{enable:!0,box:t.prop(\"scissor\")},viewport:t.prop(\"viewport\")};return t(_)}(this._regl,this._line_geometry,this._line_triangles)),this._dashed_line}get_dash(t){return null==this._dash_cache&&(this._dash_cache=new n.DashCache(this._regl)),this._dash_cache.get(t)}marker_no_hatch(t){null==this._marker_no_hatch_map&&(this._marker_no_hatch_map=new Map);let i=this._marker_no_hatch_map.get(t);return null==i&&(i=function(t,i){const e={vert:p.default,frag:`#define USE_${i.toUpperCase()}\\n${h.default}`,attributes:{a_position:{buffer:t.buffer([[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]),divisor:0},a_center:(t,i)=>i.center.to_attribute_config(),a_width:(t,i)=>i.width.to_attribute_config(),a_height:(t,i)=>i.height.to_attribute_config(),a_angle:(t,i)=>i.angle.to_attribute_config(),a_linewidth:(t,i)=>i.linewidth.to_attribute_config(),a_line_color:(t,i)=>i.line_color.to_attribute_config(),a_fill_color:(t,i)=>i.fill_color.to_attribute_config(),a_line_cap:(t,i)=>i.line_cap.to_attribute_config(),a_line_join:(t,i)=>i.line_join.to_attribute_config(),a_show:(t,i)=>i.show.to_attribute_config()},uniforms:{u_canvas_size:t.prop(\"canvas_size\"),u_pixel_ratio:t.prop(\"pixel_ratio\"),u_antialias:t.prop(\"antialias\"),u_size_hint:t.prop(\"size_hint\")},count:4,primitive:\"triangle fan\",instances:t.prop(\"nmarkers\"),blend:{enable:!0,func:{srcRGB:\"one\",srcAlpha:\"one\",dstRGB:\"one minus src alpha\",dstAlpha:\"one minus src alpha\"}},depth:{enable:!1},scissor:{enable:!0,box:t.prop(\"scissor\")},viewport:t.prop(\"viewport\")};return t(e)}(this._regl,t),this._marker_no_hatch_map.set(t,i)),i}marker_hatch(t){null==this._marker_hatch_map&&(this._marker_hatch_map=new Map);let i=this._marker_hatch_map.get(t);return null==i&&(i=function(t,i){const e={vert:`#define HATCH\\n${p.default}`,frag:`#define USE_${i.toUpperCase()}\\n#define HATCH\\n${h.default}`,attributes:{a_position:{buffer:t.buffer([[-.5,-.5],[-.5,.5],[.5,.5],[.5,-.5]]),divisor:0},a_center:(t,i)=>i.center.to_attribute_config(),a_width:(t,i)=>i.width.to_attribute_config(),a_height:(t,i)=>i.height.to_attribute_config(),a_angle:(t,i)=>i.angle.to_attribute_config(),a_linewidth:(t,i)=>i.linewidth.to_attribute_config(),a_line_color:(t,i)=>i.line_color.to_attribute_config(),a_fill_color:(t,i)=>i.fill_color.to_attribute_config(),a_line_cap:(t,i)=>i.line_cap.to_attribute_config(),a_line_join:(t,i)=>i.line_join.to_attribute_config(),a_show:(t,i)=>i.show.to_attribute_config(),a_hatch_pattern:(t,i)=>i.hatch_pattern.to_attribute_config(),a_hatch_scale:(t,i)=>i.hatch_scale.to_attribute_config(),a_hatch_weight:(t,i)=>i.hatch_weight.to_attribute_config(),a_hatch_color:(t,i)=>i.hatch_color.to_attribute_config()},uniforms:{u_canvas_size:t.prop(\"canvas_size\"),u_pixel_ratio:t.prop(\"pixel_ratio\"),u_antialias:t.prop(\"antialias\"),u_size_hint:t.prop(\"size_hint\")},count:4,primitive:\"triangle fan\",instances:t.prop(\"nmarkers\"),blend:{enable:!0,func:{srcRGB:\"one\",srcAlpha:\"one\",dstRGB:\"one minus src alpha\",dstAlpha:\"one minus src alpha\"}},depth:{enable:!1},scissor:{enable:!0,box:t.prop(\"scissor\")},viewport:t.prop(\"viewport\")};return t(e)}(this._regl,t),this._marker_hatch_map.set(t,i)),i}solid_line(){return null==this._solid_line&&(this._solid_line=function(t,i,e){const _={vert:s.default,frag:l.default,attributes:{a_position:{buffer:i,divisor:0},a_point_prev:(t,i)=>i.points.to_attribute_config(),a_point_start:(t,i)=>i.points.to_attribute_config(2*Float32Array.BYTES_PER_ELEMENT),a_point_end:(t,i)=>i.points.to_attribute_config(4*Float32Array.BYTES_PER_ELEMENT),a_point_next:(t,i)=>i.points.to_attribute_config(6*Float32Array.BYTES_PER_ELEMENT),a_show_prev:(t,i)=>i.show.to_attribute_config(),a_show_curr:(t,i)=>i.show.to_attribute_config(Uint8Array.BYTES_PER_ELEMENT),a_show_next:(t,i)=>i.show.to_attribute_config(2*Uint8Array.BYTES_PER_ELEMENT)},uniforms:{u_canvas_size:t.prop(\"canvas_size\"),u_pixel_ratio:t.prop(\"pixel_ratio\"),u_antialias:t.prop(\"antialias\"),u_line_color:t.prop(\"line_color\"),u_linewidth:t.prop(\"linewidth\"),u_miter_limit:t.prop(\"miter_limit\"),u_line_join:t.prop(\"line_join\"),u_line_cap:t.prop(\"line_cap\")},elements:e,instances:t.prop(\"nsegments\"),blend:{enable:!0,equation:\"max\",func:{srcRGB:1,srcAlpha:1,dstRGB:1,dstAlpha:1}},depth:{enable:!1},scissor:{enable:!0,box:t.prop(\"scissor\")},viewport:t.prop(\"viewport\")};return t(_)}(this._regl,this._line_geometry,this._line_triangles)),this._solid_line}}e.ReglWrapper=u,u.__name__=\"ReglWrapper\"},\n", - " 412: function _(e,t,r,n,a){var i,o;i=this,o=function(){\"use strict\";var e=function(e){return e instanceof Uint8Array||e instanceof Uint16Array||e instanceof Uint32Array||e instanceof Int8Array||e instanceof Int16Array||e instanceof Int32Array||e instanceof Float32Array||e instanceof Float64Array||e instanceof Uint8ClampedArray},t=function(e,t){for(var r=Object.keys(t),n=0;n=0&&(0|e)===e||n(\"invalid parameter type, (\"+e+\")\"+i(t)+\". must be a nonnegative integer\")},oneOf:f,shaderError:function(e,t,n,i,o){if(!e.getShaderParameter(t,e.COMPILE_STATUS)){var f=e.getShaderInfoLog(t),u=i===e.FRAGMENT_SHADER?\"fragment\":\"vertex\";g(n,\"string\",u+\" shader source must be a string\",o);var c=h(n,o),l=function(e){var t=[];return e.split(\"\\n\").forEach((function(e){if(!(e.length<5)){var r=/^ERROR:\\s+(\\d+):(\\d+):\\s*(.*)$/.exec(e);r?t.push(new d(0|r[1],0|r[2],r[3].trim())):e.length>0&&t.push(new d(\"unknown\",0,e))}})),t}(f);!function(e,t){t.forEach((function(t){var r=e[t.file];if(r){var n=r.index[t.line];if(n)return n.errors.push(t),void(r.hasErrors=!0)}e.unknown.hasErrors=!0,e.unknown.lines[0].errors.push(t)}))}(c,l),Object.keys(c).forEach((function(e){var t=c[e];if(t.hasErrors){var n=[\"\"],a=[\"\"];i(\"file number \"+e+\": \"+t.name+\"\\n\",\"color:red;text-decoration:underline;font-weight:bold\"),t.lines.forEach((function(e){if(e.errors.length>0){i(s(e.number,4)+\"| \",\"background-color:yellow; font-weight:bold\"),i(e.line+r,\"color:red; background-color:yellow; font-weight:bold\");var t=0;e.errors.forEach((function(n){var a=n.message,o=/^\\s*'(.*)'\\s*:\\s*(.*)$/.exec(a);if(o){var f=o[1];a=o[2],\"assign\"===f&&(f=\"=\"),t=Math.max(e.line.indexOf(f,t),0)}else t=0;i(s(\"| \",6)),i(s(\"^^^\",t+3)+r,\"font-weight:bold\"),i(s(\"| \",6)),i(a+r,\"font-weight:bold\")})),i(s(\"| \",6)+r)}else i(s(e.number,4)+\"| \"),i(e.line+r,\"color:red\")})),\"undefined\"==typeof document||window.chrome?console.log(n.join(\"\")):(a[0]=n.join(\"%c\"),console.log.apply(console,a))}function i(e,t){n.push(e),a.push(t||\"\")}})),a.raise(\"Error compiling \"+u+\" shader, \"+c[0].name)}},linkError:function(e,t,n,i,o){if(!e.getProgramParameter(t,e.LINK_STATUS)){var f=e.getProgramInfoLog(t),u=h(n,o),s='Error linking program with vertex shader, \"'+h(i,o)[0].name+'\", and fragment shader \"'+u[0].name+'\"';\"undefined\"!=typeof document?console.log(\"%c\"+s+\"\\n%c\"+f,\"color:red;text-decoration:underline;font-weight:bold\",\"color:red\"):console.log(s+r+f),a.raise(s)}},callSite:p,saveCommandRef:b,saveDrawInfo:function(e,t,r,n){function a(e){return e?n.id(e):0}function i(e,t){Object.keys(t).forEach((function(t){e[n.id(t)]=!0}))}b(e),e._fragId=a(e.static.frag),e._vertId=a(e.static.vert);var o=e._uniformSet={};i(o,t.static),i(o,t.dynamic);var f=e._attributeSet={};i(f,r.static),i(f,r.dynamic),e._hasCount=\"count\"in e.static||\"count\"in e.dynamic||\"elements\"in e.static||\"elements\"in e.dynamic},framebufferFormat:function(e,t,r){e.texture?f(e.texture._texture.internalformat,t,\"unsupported texture format for attachment\"):f(e.renderbuffer._renderbuffer.format,r,\"unsupported renderbuffer format for attachment\")},guessCommand:m,texture2D:function(e,t,r){var n,i=t.width,o=t.height,f=t.channels;a(i>0&&i<=r.maxTextureSize&&o>0&&o<=r.maxTextureSize,\"invalid texture shape\"),e.wrapS===y&&e.wrapT===y||a(A(i)&&A(o),\"incompatible wrap mode for texture, both width and height must be power of 2\"),1===t.mipmask?1!==i&&1!==o&&a(9984!==e.minFilter&&9986!==e.minFilter&&9985!==e.minFilter&&9987!==e.minFilter,\"min filter requires mipmap\"):(a(A(i)&&A(o),\"texture must be a square power of 2 to support mipmapping\"),a(t.mipmask===(i<<1)-1,\"missing or incomplete mipmap data\")),5126===t.type&&(r.extensions.indexOf(\"oes_texture_float_linear\")<0&&a(9728===e.minFilter&&9728===e.magFilter,\"filter not supported, must enable oes_texture_float_linear\"),a(!e.genMipmaps,\"mipmap generation not supported with float textures\"));var u=t.images;for(n=0;n<16;++n)if(u[n]){var s=i>>n,c=o>>n;a(t.mipmask&1<0&&i<=n.maxTextureSize&&o>0&&o<=n.maxTextureSize,\"invalid texture shape\"),a(i===o,\"cube map must be square\"),a(t.wrapS===y&&t.wrapT===y,\"wrap mode not supported by cube map\");for(var u=0;u>l,p=o>>l;a(s.mipmask&1<1&&t===r&&('\"'===t||\"'\"===t))return['\"'+O(e.substr(1,e.length-2))+'\"'];var n=/\\[(false|true|null|\\d+|'[^']*'|\"[^\"]*\")\\]/.exec(e);if(n)return E(e.substr(0,n.index)).concat(E(n[1])).concat(E(e.substr(n.index+n[0].length)));var a=e.split(\".\");if(1===a.length)return['\"'+O(e)+'\"'];for(var i=[],o=0;o0,\"invalid pixel ratio\"))):_.raise(\"invalid arguments to regl\"),r&&(\"canvas\"===r.nodeName.toLowerCase()?a=r:n=r),!i){if(!a){_(\"undefined\"!=typeof document,\"must manually specify webgl context outside of DOM environments\");var h=function(e,r,n){var a,i=document.createElement(\"canvas\");function o(){var t=window.innerWidth,r=window.innerHeight;if(e!==document.body){var a=i.getBoundingClientRect();t=a.right-a.left,r=a.bottom-a.top}i.width=n*t,i.height=n*r}return t(i.style,{border:0,margin:0,padding:0,top:0,left:0,width:\"100%\",height:\"100%\"}),e.appendChild(i),e===document.body&&(i.style.position=\"absolute\",t(e.style,{margin:0,padding:0})),e!==document.body&&\"function\"==typeof ResizeObserver?(a=new ResizeObserver((function(){setTimeout(o)}))).observe(e):window.addEventListener(\"resize\",o,!1),o(),{canvas:i,onDestroy:function(){a?a.disconnect():window.removeEventListener(\"resize\",o),e.removeChild(i)}}}(n||document.body,0,l);if(!h)return null;a=h.canvas,p=h.onDestroy}void 0===u.premultipliedAlpha&&(u.premultipliedAlpha=!0),i=function(e,t){function r(r){try{return e.getContext(r,t)}catch(e){return null}}return r(\"webgl\")||r(\"experimental-webgl\")||r(\"webgl-experimental\")}(a,u)}return i?{gl:i,canvas:a,container:n,extensions:s,optionalExtensions:c,pixelRatio:l,profile:d,onDone:m,onDestroy:p}:(p(),m(\"webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org\"),null)}function V(e,t){for(var r=Array(e),n=0;n65535)<<4,t|=r=((e>>>=t)>255)<<3,t|=r=((e>>>=r)>15)<<2,(t|=r=((e>>>=r)>3)<<1)|(e>>>=r)>>1}function P(){var e=V(8,(function(){return[]}));function t(t){var r=function(e){for(var t=16;t<=1<<28;t*=16)if(e<=t)return t;return 0}(t),n=e[I(r)>>2];return n.length>0?n.pop():new ArrayBuffer(r)}function r(t){e[I(t.byteLength)>>2].push(t)}return{alloc:t,free:r,allocType:function(e,r){var n=null;switch(e){case 5120:n=new Int8Array(t(r),0,r);break;case 5121:n=new Uint8Array(t(r),0,r);break;case 5122:n=new Int16Array(t(2*r),0,r);break;case 5123:n=new Uint16Array(t(2*r),0,r);break;case 5124:n=new Int32Array(t(4*r),0,r);break;case 5125:n=new Uint32Array(t(4*r),0,r);break;case 5126:n=new Float32Array(t(4*r),0,r);break;default:return null}return n.length!==r?n.subarray(0,r):n},freeType:function(e){r(e.buffer)}}}var L=P();L.zero=P();var R=3553,M=6408,W=5126,U=36160;function G(t){return!!t&&\"object\"==typeof t&&Array.isArray(t.shape)&&Array.isArray(t.stride)&&\"number\"==typeof t.offset&&t.shape.length===t.stride.length&&(Array.isArray(t.data)||e(t.data))}var H=function(e){return Object.keys(e).map((function(t){return e[t]}))},N={shape:function(e){for(var t=[],r=e;r.length;r=r[0])t.push(r.length);return t},flatten:function(e,t,r,n){var a=1;if(t.length)for(var i=0;i>>31<<15,i=(n<<1>>>24)-127,o=n>>13&1023;if(i<-24)t[r]=a;else if(i<-14){var f=-14-i;t[r]=a+(o+1024>>f)}else t[r]=i>15?a+31744:a+(i+15<<10)+o}return t}function me(t){return Array.isArray(t)||e(t)}var pe=function(e){return!(e&e-1||!e)},he=3553,be=34067,ve=34069,ge=6408,ye=6406,xe=6407,we=6409,Ae=6410,_e=32855,ke=6402,Se=34041,Oe=35904,Ee=35906,Te=36193,De=33776,je=33777,Ce=33778,ze=33779,Fe=5121,Be=5123,Ve=5125,Ie=5126,Pe=33071,Le=9728,Re=9984,Me=9987,We=4352,Ue=33984,Ge=[Re,9986,9985,Me],He=[0,we,Ae,xe,ge],Ne={};function qe(e){return\"[object \"+e+\"]\"}Ne[6409]=Ne[6406]=Ne[6402]=1,Ne[34041]=Ne[6410]=2,Ne[6407]=Ne[35904]=3,Ne[6408]=Ne[35906]=4;var Qe=qe(\"HTMLCanvasElement\"),Ye=qe(\"OffscreenCanvas\"),Xe=qe(\"CanvasRenderingContext2D\"),$e=qe(\"ImageBitmap\"),Ke=qe(\"HTMLImageElement\"),Je=qe(\"HTMLVideoElement\"),Ze=Object.keys(Y).concat([Qe,Ye,Xe,$e,Ke,Je]),et=[];et[5121]=1,et[5126]=4,et[36193]=2,et[5123]=2,et[5125]=4;var tt=[];function rt(e){return Array.isArray(e)&&(0===e.length||\"number\"==typeof e[0])}function nt(e){return!!Array.isArray(e)&&!(0===e.length||!me(e[0]))}function at(e){return Object.prototype.toString.call(e)}function it(e){return at(e)===Qe}function ot(e){return at(e)===Ye}function ft(e){if(!e)return!1;var t=at(e);return Ze.indexOf(t)>=0||rt(e)||nt(e)||G(e)}function ut(e){return 0|Y[Object.prototype.toString.call(e)]}function st(e,t){return L.allocType(e.type===Te?Ie:e.type,t)}function ct(e,t){e.type===Te?(e.data=de(t),L.freeType(t)):e.data=t}function lt(e,t,r,n,a,i){var o;if(o=void 0!==tt[e]?tt[e]:Ne[e]*et[t],i&&(o*=6),a){for(var f=0,u=r;u>=1;)f+=o*u*u,u/=2;return f}return o*r*n}function dt(r,n,a,i,o,f,u){var s={\"don't care\":We,\"dont care\":We,nice:4354,fast:4353},c={repeat:10497,clamp:Pe,mirror:33648},l={nearest:Le,linear:9729},d=t({mipmap:Me,\"nearest mipmap nearest\":Re,\"linear mipmap nearest\":9985,\"nearest mipmap linear\":9986,\"linear mipmap linear\":Me},l),m={none:0,browser:37444},p={uint8:Fe,rgba4:32819,rgb565:33635,\"rgb5 a1\":32820},h={alpha:ye,luminance:we,\"luminance alpha\":Ae,rgb:xe,rgba:ge,rgba4:32854,\"rgb5 a1\":_e,rgb565:36194},b={};n.ext_srgb&&(h.srgb=Oe,h.srgba=Ee),n.oes_texture_float&&(p.float32=p.float=Ie),n.oes_texture_half_float&&(p.float16=p[\"half float\"]=Te),n.webgl_depth_texture&&(t(h,{depth:ke,\"depth stencil\":Se}),t(p,{uint16:Be,uint32:Ve,\"depth stencil\":34042})),n.webgl_compressed_texture_s3tc&&t(b,{\"rgb s3tc dxt1\":De,\"rgba s3tc dxt1\":je,\"rgba s3tc dxt3\":Ce,\"rgba s3tc dxt5\":ze}),n.webgl_compressed_texture_atc&&t(b,{\"rgb atc\":35986,\"rgba atc explicit alpha\":35987,\"rgba atc interpolated alpha\":34798}),n.webgl_compressed_texture_pvrtc&&t(b,{\"rgb pvrtc 4bppv1\":35840,\"rgb pvrtc 2bppv1\":35841,\"rgba pvrtc 4bppv1\":35842,\"rgba pvrtc 2bppv1\":35843}),n.webgl_compressed_texture_etc1&&(b[\"rgb etc1\"]=36196);var v=Array.prototype.slice.call(r.getParameter(34467));Object.keys(b).forEach((function(e){var t=b[e];v.indexOf(t)>=0&&(h[e]=t)}));var g=Object.keys(h);a.textureFormats=g;var y=[];Object.keys(h).forEach((function(e){var t=h[e];y[t]=e}));var x=[];Object.keys(p).forEach((function(e){var t=p[e];x[t]=e}));var w=[];Object.keys(l).forEach((function(e){w[l[e]]=e}));var A=[];Object.keys(d).forEach((function(e){var t=d[e];A[t]=e}));var k=[];Object.keys(c).forEach((function(e){k[c[e]]=e}));var S=g.reduce((function(e,t){var r=h[t];return r===we||r===ye||r===we||r===Ae||r===ke||r===Se||n.ext_srgb&&(r===Oe||r===Ee)?e[r]=r:r===_e||t.indexOf(\"rgba\")>=0?e[r]=ge:e[r]=xe,e}),{});function O(){this.internalformat=ge,this.format=ge,this.type=Fe,this.compressed=!1,this.premultiplyAlpha=!1,this.flipY=!1,this.unpackAlignment=1,this.colorSpace=37444,this.width=0,this.height=0,this.channels=0}function E(e,t){e.internalformat=t.internalformat,e.format=t.format,e.type=t.type,e.compressed=t.compressed,e.premultiplyAlpha=t.premultiplyAlpha,e.flipY=t.flipY,e.unpackAlignment=t.unpackAlignment,e.colorSpace=t.colorSpace,e.width=t.width,e.height=t.height,e.channels=t.channels}function T(e,t){if(\"object\"==typeof t&&t){if(\"premultiplyAlpha\"in t&&(_.type(t.premultiplyAlpha,\"boolean\",\"invalid premultiplyAlpha\"),e.premultiplyAlpha=t.premultiplyAlpha),\"flipY\"in t&&(_.type(t.flipY,\"boolean\",\"invalid texture flip\"),e.flipY=t.flipY),\"alignment\"in t&&(_.oneOf(t.alignment,[1,2,4,8],\"invalid texture unpack alignment\"),e.unpackAlignment=t.alignment),\"colorSpace\"in t&&(_.parameter(t.colorSpace,m,\"invalid colorSpace\"),e.colorSpace=m[t.colorSpace]),\"type\"in t){var r=t.type;_(n.oes_texture_float||!(\"float\"===r||\"float32\"===r),\"you must enable the OES_texture_float extension in order to use floating point textures.\"),_(n.oes_texture_half_float||!(\"half float\"===r||\"float16\"===r),\"you must enable the OES_texture_half_float extension in order to use 16-bit floating point textures.\"),_(n.webgl_depth_texture||!(\"uint16\"===r||\"uint32\"===r||\"depth stencil\"===r),\"you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.\"),_.parameter(r,p,\"invalid texture type\"),e.type=p[r]}var i=e.width,o=e.height,f=e.channels,u=!1;\"shape\"in t?(_(Array.isArray(t.shape)&&t.shape.length>=2,\"shape must be an array\"),i=t.shape[0],o=t.shape[1],3===t.shape.length&&(f=t.shape[2],_(f>0&&f<=4,\"invalid number of channels\"),u=!0),_(i>=0&&i<=a.maxTextureSize,\"invalid width\"),_(o>=0&&o<=a.maxTextureSize,\"invalid height\")):(\"radius\"in t&&(i=o=t.radius,_(i>=0&&i<=a.maxTextureSize,\"invalid radius\")),\"width\"in t&&(i=t.width,_(i>=0&&i<=a.maxTextureSize,\"invalid width\")),\"height\"in t&&(o=t.height,_(o>=0&&o<=a.maxTextureSize,\"invalid height\")),\"channels\"in t&&(f=t.channels,_(f>0&&f<=4,\"invalid number of channels\"),u=!0)),e.width=0|i,e.height=0|o,e.channels=0|f;var s=!1;if(\"format\"in t){var c=t.format;_(n.webgl_depth_texture||!(\"depth\"===c||\"depth stencil\"===c),\"you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.\"),_.parameter(c,h,\"invalid texture format\");var l=e.internalformat=h[c];e.format=S[l],c in p&&(\"type\"in t||(e.type=p[c])),c in b&&(e.compressed=!0),s=!0}!u&&s?e.channels=Ne[e.format]:u&&!s?e.channels!==He[e.format]&&(e.format=e.internalformat=He[e.channels]):s&&u&&_(e.channels===Ne[e.format],\"number of channels inconsistent with specified format\")}}function D(e){r.pixelStorei(37440,e.flipY),r.pixelStorei(37441,e.premultiplyAlpha),r.pixelStorei(37443,e.colorSpace),r.pixelStorei(3317,e.unpackAlignment)}function j(){O.call(this),this.xOffset=0,this.yOffset=0,this.data=null,this.needsFree=!1,this.element=null,this.needsCopy=!1}function C(t,r){var n=null;if(ft(r)?n=r:r&&(_.type(r,\"object\",\"invalid pixel data type\"),T(t,r),\"x\"in r&&(t.xOffset=0|r.x),\"y\"in r&&(t.yOffset=0|r.y),ft(r.data)&&(n=r.data)),_(!t.compressed||n instanceof Uint8Array,\"compressed texture data must be stored in a uint8array\"),r.copy){_(!n,\"can not specify copy and data field for the same texture\");var i=o.viewportWidth,f=o.viewportHeight;t.width=t.width||i-t.xOffset,t.height=t.height||f-t.yOffset,t.needsCopy=!0,_(t.xOffset>=0&&t.xOffset=0&&t.yOffset0&&t.width<=i&&t.height>0&&t.height<=f,\"copy texture read out of bounds\")}else if(n){if(e(n))t.channels=t.channels||4,t.data=n,\"type\"in r||t.type!==Fe||(t.type=ut(n));else if(rt(n))t.channels=t.channels||4,function(e,t){var r=t.length;switch(e.type){case Fe:case Be:case Ve:case Ie:var n=L.allocType(e.type,r);n.set(t),e.data=n;break;case Te:e.data=de(t);break;default:_.raise(\"unsupported texture type, must specify a typed array\")}}(t,n),t.alignment=1,t.needsFree=!0;else if(G(n)){var u=n.data;Array.isArray(u)||t.type!==Fe||(t.type=ut(u));var s,c,l,d,m,p,h=n.shape,b=n.stride;3===h.length?(l=h[2],p=b[2]):(_(2===h.length,\"invalid ndarray pixel data, must be 2 or 3D\"),l=1,p=1),s=h[0],c=h[1],d=b[0],m=b[1],t.alignment=1,t.width=s,t.height=c,t.channels=l,t.format=t.internalformat=He[l],t.needsFree=!0,function(e,t,r,n,a,i){for(var o=e.width,f=e.height,u=e.channels,s=st(e,o*f*u),c=0,l=0;l=0,\"oes_texture_float extension not enabled\"):t.type===Te&&_(a.extensions.indexOf(\"oes_texture_half_float\")>=0,\"oes_texture_half_float extension not enabled\")}function z(e,t,n){var a=e.element,o=e.data,f=e.internalformat,u=e.format,s=e.type,c=e.width,l=e.height;D(e),a?r.texImage2D(t,n,u,u,s,a):e.compressed?r.compressedTexImage2D(t,n,f,c,l,0,o):e.needsCopy?(i(),r.copyTexImage2D(t,n,u,e.xOffset,e.yOffset,c,l,0)):r.texImage2D(t,n,u,c,l,0,u,s,o||null)}function F(e,t,n,a,o){var f=e.element,u=e.data,s=e.internalformat,c=e.format,l=e.type,d=e.width,m=e.height;D(e),f?r.texSubImage2D(t,o,n,a,c,l,f):e.compressed?r.compressedTexSubImage2D(t,o,n,a,s,d,m,u):e.needsCopy?(i(),r.copyTexSubImage2D(t,o,n,a,e.xOffset,e.yOffset,d,m)):r.texSubImage2D(t,o,n,a,d,m,c,l,u)}var B=[];function V(){return B.pop()||new j}function I(e){e.needsFree&&L.freeType(e.data),j.call(e),B.push(e)}function P(){O.call(this),this.genMipmaps=!1,this.mipmapHint=We,this.mipmask=0,this.images=Array(16)}function R(e,t,r){var n=e.images[0]=V();e.mipmask=1,n.width=e.width=t,n.height=e.height=r,n.channels=e.channels=4}function M(e,t){var r=null;if(ft(t))E(r=e.images[0]=V(),e),C(r,t),e.mipmask=1;else if(T(e,t),Array.isArray(t.mipmap))for(var n=t.mipmap,a=0;a>=a,r.height>>=a,C(r,n[a]),e.mipmask|=1<=0&&!(\"faces\"in t)&&(e.genMipmaps=!0)}if(\"mag\"in t){var n=t.mag;_.parameter(n,l),e.magFilter=l[n]}var i=e.wrapS,o=e.wrapT;if(\"wrap\"in t){var f=t.wrap;\"string\"==typeof f?(_.parameter(f,c),i=o=c[f]):Array.isArray(f)&&(_.parameter(f[0],c),_.parameter(f[1],c),i=c[f[0]],o=c[f[1]])}else{if(\"wrapS\"in t){var u=t.wrapS;_.parameter(u,c),i=c[u]}if(\"wrapT\"in t){var m=t.wrapT;_.parameter(m,c),o=c[m]}}if(e.wrapS=i,e.wrapT=o,\"anisotropic\"in t){var p=t.anisotropic;_(\"number\"==typeof p&&p>=1&&p<=a.maxAnisotropic,\"aniso samples must be between 1 and \"),e.anisotropic=t.anisotropic}if(\"mipmap\"in t){var h=!1;switch(typeof t.mipmap){case\"string\":_.parameter(t.mipmap,s,\"invalid mipmap hint\"),e.mipmapHint=s[t.mipmap],e.genMipmaps=!0,h=!0;break;case\"boolean\":h=e.genMipmaps=t.mipmap;break;case\"object\":_(Array.isArray(t.mipmap),\"invalid mipmap type\"),e.genMipmaps=!1,h=!0;break;default:_.raise(\"invalid mipmap type\")}h&&!(\"min\"in t)&&(e.minFilter=Re)}}function $(e,t){r.texParameteri(t,10241,e.minFilter),r.texParameteri(t,10240,e.magFilter),r.texParameteri(t,10242,e.wrapS),r.texParameteri(t,10243,e.wrapT),n.ext_texture_filter_anisotropic&&r.texParameteri(t,34046,e.anisotropic),e.genMipmaps&&(r.hint(33170,e.mipmapHint),r.generateMipmap(t))}var K=0,J={},Z=a.maxTextureUnits,ee=Array(Z).map((function(){return null}));function te(e){O.call(this),this.mipmask=0,this.internalformat=ge,this.id=K++,this.refCount=1,this.target=e,this.texture=r.createTexture(),this.unit=-1,this.bindCount=0,this.texInfo=new Y,u.profile&&(this.stats={size:0})}function re(e){r.activeTexture(Ue),r.bindTexture(e.target,e.texture)}function ne(){var e=ee[0];e?r.bindTexture(e.target,e.texture):r.bindTexture(he,null)}function ae(e){var t=e.texture;_(t,\"must not double destroy texture\");var n=e.unit,a=e.target;n>=0&&(r.activeTexture(Ue+n),r.bindTexture(a,null),ee[n]=null),r.deleteTexture(t),e.texture=null,e.params=null,e.pixels=null,e.refCount=0,delete J[e.id],f.textureCount--}return t(te.prototype,{bind:function(){var e=this;e.bindCount+=1;var t=e.unit;if(t<0){for(var n=0;n0)continue;a.unit=-1}ee[n]=e,t=n;break}t>=Z&&_.raise(\"insufficient number of texture units\"),u.profile&&f.maxTextureUnits>u)-o,s.height=s.height||(n.height>>u)-f,_(n.type===s.type&&n.format===s.format&&n.internalformat===s.internalformat,\"incompatible format for texture.subimage\"),_(o>=0&&f>=0&&o+s.width<=n.width&&f+s.height<=n.height,\"texture.subimage write out of bounds\"),_(n.mipmask&1<>f;++f){var s=a>>f,c=o>>f;if(!s||!c)break;r.texImage2D(he,f,n.format,s,c,0,n.format,n.type,null)}return ne(),u.profile&&(n.stats.size=lt(n.internalformat,n.type,a,o,!1,!1)),i},i._reglType=\"texture2d\",i._texture=n,u.profile&&(i.stats=n.stats),i.destroy=function(){n.decRef()},i},createCube:function(e,t,n,i,o,s){var c=new te(be);J[c.id]=c,f.cubeCount++;var l=new Array(6);function d(e,t,r,n,i,o){var f,s=c.texInfo;for(Y.call(s),f=0;f<6;++f)l[f]=q();if(\"number\"!=typeof e&&e)if(\"object\"==typeof e)if(t)M(l[0],e),M(l[1],t),M(l[2],r),M(l[3],n),M(l[4],i),M(l[5],o);else if(X(s,e),T(c,e),\"faces\"in e){var m=e.faces;for(_(Array.isArray(m)&&6===m.length,\"cube faces must be a length 6 array\"),f=0;f<6;++f)_(\"object\"==typeof m[f]&&!!m[f],\"invalid input for cube map face\"),E(l[f],c),M(l[f],m[f])}else for(f=0;f<6;++f)M(l[f],e);else _.raise(\"invalid arguments to cube map\");else{var p=0|e||1;for(f=0;f<6;++f)R(l[f],p,p)}for(E(c,l[0]),_.optional((function(){a.npotTextureCube||_(pe(c.width)&&pe(c.height),\"your browser does not support non power or two texture dimensions\")})),s.genMipmaps?c.mipmask=(l[0].width<<1)-1:c.mipmask=l[0].mipmask,_.textureCube(c,s,l,a),c.internalformat=l[0].internalformat,d.width=l[0].width,d.height=l[0].height,re(c),f=0;f<6;++f)W(l[f],ve+f);for($(s,be),ne(),u.profile&&(c.stats.size=lt(c.internalformat,c.type,d.width,d.height,s.genMipmaps,!0)),d.format=y[c.internalformat],d.type=x[c.type],d.mag=w[s.magFilter],d.min=A[s.minFilter],d.wrapS=k[s.wrapS],d.wrapT=k[s.wrapT],f=0;f<6;++f)Q(l[f]);return d}return d(e,t,n,i,o,s),d.subimage=function(e,t,r,n,a){_(!!t,\"must specify image data\"),_(\"number\"==typeof e&&e===(0|e)&&e>=0&&e<6,\"invalid face\");var i=0|r,o=0|n,f=0|a,u=V();return E(u,c),u.width=0,u.height=0,C(u,t),u.width=u.width||(c.width>>f)-i,u.height=u.height||(c.height>>f)-o,_(c.type===u.type&&c.format===u.format&&c.internalformat===u.internalformat,\"incompatible format for texture.subimage\"),_(i>=0&&o>=0&&i+u.width<=c.width&&o+u.height<=c.height,\"texture.subimage write out of bounds\"),_(c.mipmask&1<>a;++a)r.texImage2D(ve+n,a,c.format,t>>a,t>>a,0,c.format,c.type,null);return ne(),u.profile&&(c.stats.size=lt(c.internalformat,c.type,d.width,d.height,!1,!0)),d}},d._reglType=\"textureCube\",d._texture=c,u.profile&&(d.stats=c.stats),d.destroy=function(){c.decRef()},d},clear:function(){for(var e=0;e>t,e.height>>t,0,e.internalformat,e.type,null);else for(var n=0;n<6;++n)r.texImage2D(ve+n,t,e.internalformat,e.width>>t,e.height>>t,0,e.internalformat,e.type,null);$(e.texInfo,e.target)}))},refresh:function(){for(var e=0;e=0&&c=0&&l0&&d+c<=a.framebufferWidth,\"invalid width for read pixels\"),_(m>0&&m+l<=a.framebufferHeight,\"invalid height for read pixels\"),n();var h=d*m*4;return p||(s===Dt?p=new Uint8Array(h):s===jt&&(p=p||new Float32Array(h))),_.isTypedArray(p,\"data buffer for regl.read() must be a typedarray\"),_(p.byteLength>=h,\"data buffer for regl.read() too small\"),t.pixelStorei(3333,4),t.readPixels(c,l,d,m,6408,s,p),p}return function(e){return e&&\"framebuffer\"in e?function(e){var t;return r.setFBO({framebuffer:e.framebuffer},(function(){t=u(e)})),t}(e):u(e)}}function zt(e){return Array.prototype.slice.call(e)}function Ft(e){return zt(e).join(\"\")}var Bt=\"xyzw\".split(\"\"),Vt=\"dither\",It=\"blend.enable\",Pt=\"blend.color\",Lt=\"blend.equation\",Rt=\"blend.func\",Mt=\"depth.enable\",Wt=\"depth.func\",Ut=\"depth.range\",Gt=\"depth.mask\",Ht=\"colorMask\",Nt=\"cull.enable\",qt=\"cull.face\",Qt=\"frontFace\",Yt=\"lineWidth\",Xt=\"polygonOffset.enable\",$t=\"polygonOffset.offset\",Kt=\"sample.alpha\",Jt=\"sample.enable\",Zt=\"sample.coverage\",er=\"stencil.enable\",tr=\"stencil.mask\",rr=\"stencil.func\",nr=\"stencil.opFront\",ar=\"stencil.opBack\",ir=\"scissor.enable\",or=\"scissor.box\",fr=\"viewport\",ur=\"profile\",sr=\"framebuffer\",cr=\"vert\",lr=\"frag\",dr=\"elements\",mr=\"primitive\",pr=\"count\",hr=\"offset\",br=\"instances\",vr=\"vao\",gr=\"Width\",yr=\"Height\",xr=sr+gr,wr=sr+yr,Ar=\"drawingBufferWidth\",_r=\"drawingBufferHeight\",kr=[Rt,Lt,rr,nr,ar,Zt,fr,or,$t],Sr=34962,Or=34963,Er=5126,Tr=35664,Dr=35665,jr=35666,Cr=5124,zr=35667,Fr=35668,Br=35669,Vr=35670,Ir=35671,Pr=35672,Lr=35673,Rr=35674,Mr=35675,Wr=35676,Ur=35678,Gr=35680,Hr=1028,Nr=1029,qr=2305,Qr=7680,Yr={0:0,1:1,zero:0,one:1,\"src color\":768,\"one minus src color\":769,\"src alpha\":770,\"one minus src alpha\":771,\"dst color\":774,\"one minus dst color\":775,\"dst alpha\":772,\"one minus dst alpha\":773,\"constant color\":32769,\"one minus constant color\":32770,\"constant alpha\":32771,\"one minus constant alpha\":32772,\"src alpha saturate\":776},Xr=[\"constant color, constant alpha\",\"one minus constant color, constant alpha\",\"constant color, one minus constant alpha\",\"one minus constant color, one minus constant alpha\",\"constant alpha, constant color\",\"constant alpha, one minus constant color\",\"one minus constant alpha, constant color\",\"one minus constant alpha, one minus constant color\"],$r={never:512,less:513,\"<\":513,equal:514,\"=\":514,\"==\":514,\"===\":514,lequal:515,\"<=\":515,greater:516,\">\":516,notequal:517,\"!=\":517,\"!==\":517,gequal:518,\">=\":518,always:519},Kr={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,\"increment wrap\":34055,\"decrement wrap\":34056,invert:5386},Jr={frag:35632,vert:35633},Zr={cw:2304,ccw:qr};function en(t){return Array.isArray(t)||e(t)||G(t)}function tn(e){return e.sort((function(e,t){return e===fr?-1:t===fr?1:e=1,n>=2,t)}if(4===r){var a=e.data;return new rn(a.thisDep,a.contextDep,a.propDep,t)}if(5===r)return new rn(!1,!1,!1,t);if(6===r){for(var i=!1,o=!1,f=!1,u=0;u=1&&(o=!0),c>=2&&(f=!0)}else 4===s.type&&(i=i||s.data.thisDep,o=o||s.data.contextDep,f=f||s.data.propDep)}return new rn(i,o,f,t)}return new rn(3===r,2===r,1===r,t)}var fn=new rn(!1,!1,!1,(function(){}));function un(e,r,n,a,i,o,f,u,s,c,l,d,m,p,h){var b=c.Record,v={add:32774,subtract:32778,\"reverse subtract\":32779};n.ext_blend_minmax&&(v.min=32775,v.max=32776);var g=n.angle_instanced_arrays,y=n.webgl_draw_buffers,x=n.oes_vertex_array_object,w={dirty:!0,profile:h.profile},A={},k=[],S={},O={};function E(e){return e.replace(\".\",\"_\")}function T(e,t,r){var n=E(e);k.push(e),A[n]=w[n]=!!r,S[n]=t}function j(e,t,r){var n=E(e);k.push(e),Array.isArray(r)?(w[n]=r.slice(),A[n]=r.slice()):w[n]=A[n]=r,O[n]=t}T(Vt,3024),T(It,3042),j(Pt,\"blendColor\",[0,0,0,0]),j(Lt,\"blendEquationSeparate\",[32774,32774]),j(Rt,\"blendFuncSeparate\",[1,0,1,0]),T(Mt,2929,!0),j(Wt,\"depthFunc\",513),j(Ut,\"depthRange\",[0,1]),j(Gt,\"depthMask\",!0),j(Ht,Ht,[!0,!0,!0,!0]),T(Nt,2884),j(qt,\"cullFace\",Nr),j(Qt,Qt,qr),j(Yt,Yt,1),T(Xt,32823),j($t,\"polygonOffset\",[0,0]),T(Kt,32926),T(Jt,32928),j(Zt,\"sampleCoverage\",[1,!1]),T(er,2960),j(tr,\"stencilMask\",-1),j(rr,\"stencilFunc\",[519,0,-1]),j(nr,\"stencilOpSeparate\",[Hr,Qr,Qr,Qr]),j(ar,\"stencilOpSeparate\",[Nr,Qr,Qr,Qr]),T(ir,3089),j(or,\"scissor\",[0,0,e.drawingBufferWidth,e.drawingBufferHeight]),j(fr,fr,[0,0,e.drawingBufferWidth,e.drawingBufferHeight]);var C={gl:e,context:m,strings:r,next:A,current:w,draw:d,elements:o,buffer:i,shader:l,attributes:c.state,vao:c,uniforms:s,framebuffer:u,extensions:n,timer:p,isBufferArgs:en},z={primTypes:ie,compareFuncs:$r,blendFuncs:Yr,blendEquations:v,stencilOps:Kr,glTypes:X,orientationType:Zr};_.optional((function(){C.isArrayLike=me})),y&&(z.backBuffer=[Nr],z.drawBuffer=V(a.maxDrawbuffers,(function(e){return 0===e?[0]:V(e,(function(e){return 36064+e}))})));var F=0;function B(){var e=function(){var e=0,r=[],n=[];function a(){var r=[],n=[];return t((function(){r.push.apply(r,zt(arguments))}),{def:function(){var t=\"v\"+e++;return n.push(t),arguments.length>0&&(r.push(t,\"=\"),r.push.apply(r,zt(arguments)),r.push(\";\")),t},toString:function(){return Ft([n.length>0?\"var \"+n.join(\",\")+\";\":\"\",Ft(r)])}})}function i(){var e=a(),r=a(),n=e.toString,i=r.toString;function o(t,n){r(t,n,\"=\",e.def(t,n),\";\")}return t((function(){e.apply(e,zt(arguments))}),{def:e.def,entry:e,exit:r,save:o,set:function(t,r,n){o(t,r),e(t,r,\"=\",n,\";\")},toString:function(){return n()+i()}})}var o=a(),f={};return{global:o,link:function(t){for(var a=0;a=0,'unknown parameter \"'+t+'\"',d.commandStr)}))}t(m),t(p)}));var h=function(e,t){var r=e.static;if(\"string\"==typeof r[lr]&&\"string\"==typeof r[cr]){if(Object.keys(t.dynamic).length>0)return null;var n=t.static,a=Object.keys(n);if(a.length>0&&\"number\"==typeof n[a[0]]){for(var i=[],o=0;o=0,\"invalid \"+e,r.commandStr)):u=!1,\"height\"in i?(f=0|i.height,_.command(f>=0,\"invalid \"+e,r.commandStr)):u=!1,new rn(!u&&t&&t.thisDep,!u&&t&&t.contextDep,!u&&t&&t.propDep,(function(e,t){var r=e.shared.context,n=o;\"width\"in i||(n=t.def(r,\".\",xr,\"-\",s));var a=f;return\"height\"in i||(a=t.def(r,\".\",wr,\"-\",c)),[s,c,n,a]}))}if(e in a){var l=a[e],d=on(l,(function(t,r){var n=t.invoke(r,l);_.optional((function(){t.assert(r,n+\"&&typeof \"+n+'===\"object\"',\"invalid \"+e)}));var a=t.shared.context,i=r.def(n,\".x|0\"),o=r.def(n,\".y|0\"),f=r.def('\"width\" in ',n,\"?\",n,\".width|0:\",\"(\",a,\".\",xr,\"-\",i,\")\"),u=r.def('\"height\" in ',n,\"?\",n,\".height|0:\",\"(\",a,\".\",wr,\"-\",o,\")\");return _.optional((function(){t.assert(r,f+\">=0&&\"+u+\">=0\",\"invalid \"+e)})),[i,o,f,u]}));return t&&(d.thisDep=d.thisDep||t.thisDep,d.contextDep=d.contextDep||t.contextDep,d.propDep=d.propDep||t.propDep),d}return t?new rn(t.thisDep,t.contextDep,t.propDep,(function(e,t){var r=e.shared.context;return[0,0,t.def(r,\".\",xr),t.def(r,\".\",wr)]})):null}var o=i(fr);if(o){var f=o;o=new rn(o.thisDep,o.contextDep,o.propDep,(function(e,t){var r=f.append(e,t),n=e.shared.context;return t.set(n,\".viewportWidth\",r[2]),t.set(n,\".viewportHeight\",r[3]),r}))}return{viewport:o,scissor_box:i(or)}}(e,y,d),w=function(e,t){var r=e.static,n=e.dynamic,a={},i=!1,f=function(){if(vr in r){var e=r[vr];return null!==e&&null===c.getVAO(e)&&(e=c.createVAO(e)),i=!0,a.vao=e,an((function(t){var r=c.getVAO(e);return r?t.link(r):\"null\"}))}if(vr in n){i=!0;var t=n[vr];return on(t,(function(e,r){var n=e.invoke(r,t);return r.def(e.shared.vao+\".getVAO(\"+n+\")\")}))}return null}(),u=!1,s=function(){if(dr in r){var e=r[dr];if(a.elements=e,en(e)){var s=a.elements=o.create(e,!0);e=o.getElements(s),u=!0}else e&&(e=o.getElements(e),u=!0,_.command(e,\"invalid elements\",t.commandStr));var c=an((function(t,r){if(e){var n=t.link(e);return t.ELEMENTS=n,n}return t.ELEMENTS=null,null}));return c.value=e,c}if(dr in n){u=!0;var l=n[dr];return on(l,(function(e,t){var r=e.shared,n=r.isBufferArgs,a=r.elements,i=e.invoke(t,l),o=t.def(\"null\"),f=t.def(n,\"(\",i,\")\"),u=e.cond(f).then(o,\"=\",a,\".createStream(\",i,\");\").else(o,\"=\",a,\".getElements(\",i,\");\");return _.optional((function(){e.assert(u.else,\"!\"+i+\"||\"+o,\"invalid elements\")})),t.entry(u),t.exit(e.cond(f).then(a,\".destroyStream(\",o,\");\")),e.ELEMENTS=o,o}))}return i?new rn(f.thisDep,f.contextDep,f.propDep,(function(e,t){return t.def(e.shared.vao+\".currentVAO?\"+e.shared.elements+\".getElements(\"+e.shared.vao+\".currentVAO.elements):null\")})):null}();function l(e,o){if(e in r){var s=0|r[e];return o?a.offset=s:a.instances=s,_.command(!o||s>=0,\"invalid \"+e,t.commandStr),an((function(e,t){return o&&(e.OFFSET=s),s}))}if(e in n){var c=n[e];return on(c,(function(t,r){var n=t.invoke(r,c);return o&&(t.OFFSET=n,_.optional((function(){t.assert(r,n+\">=0\",\"invalid \"+e)}))),n}))}if(o){if(u)return an((function(e,t){return e.OFFSET=0,0}));if(i)return new rn(f.thisDep,f.contextDep,f.propDep,(function(e,t){return t.def(e.shared.vao+\".currentVAO?\"+e.shared.vao+\".currentVAO.offset:0\")}))}else if(i)return new rn(f.thisDep,f.contextDep,f.propDep,(function(e,t){return t.def(e.shared.vao+\".currentVAO?\"+e.shared.vao+\".currentVAO.instances:-1\")}));return null}var d=l(hr,!0),m=function(){if(mr in r){var e=r[mr];return a.primitive=e,_.commandParameter(e,ie,\"invalid primitve\",t.commandStr),an((function(t,r){return ie[e]}))}if(mr in n){var o=n[mr];return on(o,(function(e,t){var r=e.constants.primTypes,n=e.invoke(t,o);return _.optional((function(){e.assert(t,n+\" in \"+r,\"invalid primitive, must be one of \"+Object.keys(ie))})),t.def(r,\"[\",n,\"]\")}))}return u?nn(s)?s.value?an((function(e,t){return t.def(e.ELEMENTS,\".primType\")})):an((function(){return 4})):new rn(s.thisDep,s.contextDep,s.propDep,(function(e,t){var r=e.ELEMENTS;return t.def(r,\"?\",r,\".primType:\",4)})):i?new rn(f.thisDep,f.contextDep,f.propDep,(function(e,t){return t.def(e.shared.vao+\".currentVAO?\"+e.shared.vao+\".currentVAO.primitive:4\")})):null}(),p=function(){if(pr in r){var e=0|r[pr];return a.count=e,_.command(\"number\"==typeof e&&e>=0,\"invalid vertex count\",t.commandStr),an((function(){return e}))}if(pr in n){var o=n[pr];return on(o,(function(e,t){var r=e.invoke(t,o);return _.optional((function(){e.assert(t,\"typeof \"+r+'===\"number\"&&'+r+\">=0&&\"+r+\"===(\"+r+\"|0)\",\"invalid vertex count\")})),r}))}if(u){if(nn(s)){if(s)return d?new rn(d.thisDep,d.contextDep,d.propDep,(function(e,t){var r=t.def(e.ELEMENTS,\".vertCount-\",e.OFFSET);return _.optional((function(){e.assert(t,r+\">=0\",\"invalid vertex offset/element buffer too small\")})),r})):an((function(e,t){return t.def(e.ELEMENTS,\".vertCount\")}));var c=an((function(){return-1}));return _.optional((function(){c.MISSING=!0})),c}var l=new rn(s.thisDep||d.thisDep,s.contextDep||d.contextDep,s.propDep||d.propDep,(function(e,t){var r=e.ELEMENTS;return e.OFFSET?t.def(r,\"?\",r,\".vertCount-\",e.OFFSET,\":-1\"):t.def(r,\"?\",r,\".vertCount:-1\")}));return _.optional((function(){l.DYNAMIC=!0})),l}if(i){var m=new rn(f.thisDep,f.contextDep,f.propDep,(function(e,t){return t.def(e.shared.vao,\".currentVAO?\",e.shared.vao,\".currentVAO.count:-1\")}));return m}return null}(),h=l(br,!1);return{elements:s,primitive:m,count:p,instances:h,offset:d,vao:f,vaoActive:i,elementsActive:u,static:a}}(e,d),A=function(e,t){var r=e.static,n=e.dynamic,i={};return k.forEach((function(e){var o=E(e);function f(t,a){if(e in r){var f=t(r[e]);i[o]=an((function(){return f}))}else if(e in n){var u=n[e];i[o]=on(u,(function(e,t){return a(e,t,e.invoke(t,u))}))}}switch(e){case Nt:case It:case Vt:case er:case Mt:case ir:case Xt:case Kt:case Jt:case Gt:return f((function(r){return _.commandType(r,\"boolean\",e,t.commandStr),r}),(function(t,r,n){return _.optional((function(){t.assert(r,\"typeof \"+n+'===\"boolean\"',\"invalid flag \"+e,t.commandStr)})),n}));case Wt:return f((function(r){return _.commandParameter(r,$r,\"invalid \"+e,t.commandStr),$r[r]}),(function(t,r,n){var a=t.constants.compareFuncs;return _.optional((function(){t.assert(r,n+\" in \"+a,\"invalid \"+e+\", must be one of \"+Object.keys($r))})),r.def(a,\"[\",n,\"]\")}));case Ut:return f((function(e){return _.command(me(e)&&2===e.length&&\"number\"==typeof e[0]&&\"number\"==typeof e[1]&&e[0]<=e[1],\"depth range is 2d array\",t.commandStr),e}),(function(e,t,r){return _.optional((function(){e.assert(t,e.shared.isArrayLike+\"(\"+r+\")&&\"+r+\".length===2&&typeof \"+r+'[0]===\"number\"&&typeof '+r+'[1]===\"number\"&&'+r+\"[0]<=\"+r+\"[1]\",\"depth range must be a 2d array\")})),[t.def(\"+\",r,\"[0]\"),t.def(\"+\",r,\"[1]\")]}));case Rt:return f((function(e){_.commandType(e,\"object\",\"blend.func\",t.commandStr);var r=\"srcRGB\"in e?e.srcRGB:e.src,n=\"srcAlpha\"in e?e.srcAlpha:e.src,a=\"dstRGB\"in e?e.dstRGB:e.dst,i=\"dstAlpha\"in e?e.dstAlpha:e.dst;return _.commandParameter(r,Yr,o+\".srcRGB\",t.commandStr),_.commandParameter(n,Yr,o+\".srcAlpha\",t.commandStr),_.commandParameter(a,Yr,o+\".dstRGB\",t.commandStr),_.commandParameter(i,Yr,o+\".dstAlpha\",t.commandStr),_.command(-1===Xr.indexOf(r+\", \"+a),\"unallowed blending combination (srcRGB, dstRGB) = (\"+r+\", \"+a+\")\",t.commandStr),[Yr[r],Yr[a],Yr[n],Yr[i]]}),(function(t,r,n){var a=t.constants.blendFuncs;function i(i,o){var f=r.def('\"',i,o,'\" in ',n,\"?\",n,\".\",i,o,\":\",n,\".\",i);return _.optional((function(){t.assert(r,f+\" in \"+a,\"invalid \"+e+\".\"+i+o+\", must be one of \"+Object.keys(Yr))})),f}_.optional((function(){t.assert(r,n+\"&&typeof \"+n+'===\"object\"',\"invalid blend func, must be an object\")}));var o=i(\"src\",\"RGB\"),f=i(\"dst\",\"RGB\");_.optional((function(){var e=t.constants.invalidBlendCombinations;t.assert(r,e+\".indexOf(\"+o+'+\", \"+'+f+\") === -1 \",\"unallowed blending combination for (srcRGB, dstRGB)\")}));var u=r.def(a,\"[\",o,\"]\"),s=r.def(a,\"[\",i(\"src\",\"Alpha\"),\"]\");return[u,r.def(a,\"[\",f,\"]\"),s,r.def(a,\"[\",i(\"dst\",\"Alpha\"),\"]\")]}));case Lt:return f((function(r){return\"string\"==typeof r?(_.commandParameter(r,v,\"invalid \"+e,t.commandStr),[v[r],v[r]]):\"object\"==typeof r?(_.commandParameter(r.rgb,v,e+\".rgb\",t.commandStr),_.commandParameter(r.alpha,v,e+\".alpha\",t.commandStr),[v[r.rgb],v[r.alpha]]):void _.commandRaise(\"invalid blend.equation\",t.commandStr)}),(function(t,r,n){var a=t.constants.blendEquations,i=r.def(),o=r.def(),f=t.cond(\"typeof \",n,'===\"string\"');return _.optional((function(){function r(e,r,n){t.assert(e,n+\" in \"+a,\"invalid \"+r+\", must be one of \"+Object.keys(v))}r(f.then,e,n),t.assert(f.else,n+\"&&typeof \"+n+'===\"object\"',\"invalid \"+e),r(f.else,e+\".rgb\",n+\".rgb\"),r(f.else,e+\".alpha\",n+\".alpha\")})),f.then(i,\"=\",o,\"=\",a,\"[\",n,\"];\"),f.else(i,\"=\",a,\"[\",n,\".rgb];\",o,\"=\",a,\"[\",n,\".alpha];\"),r(f),[i,o]}));case Pt:return f((function(e){return _.command(me(e)&&4===e.length,\"blend.color must be a 4d array\",t.commandStr),V(4,(function(t){return+e[t]}))}),(function(e,t,r){return _.optional((function(){e.assert(t,e.shared.isArrayLike+\"(\"+r+\")&&\"+r+\".length===4\",\"blend.color must be a 4d array\")})),V(4,(function(e){return t.def(\"+\",r,\"[\",e,\"]\")}))}));case tr:return f((function(e){return _.commandType(e,\"number\",o,t.commandStr),0|e}),(function(e,t,r){return _.optional((function(){e.assert(t,\"typeof \"+r+'===\"number\"',\"invalid stencil.mask\")})),t.def(r,\"|0\")}));case rr:return f((function(r){_.commandType(r,\"object\",o,t.commandStr);var n=r.cmp||\"keep\",a=r.ref||0,i=\"mask\"in r?r.mask:-1;return _.commandParameter(n,$r,e+\".cmp\",t.commandStr),_.commandType(a,\"number\",e+\".ref\",t.commandStr),_.commandType(i,\"number\",e+\".mask\",t.commandStr),[$r[n],a,i]}),(function(e,t,r){var n=e.constants.compareFuncs;return _.optional((function(){function a(){e.assert(t,Array.prototype.join.call(arguments,\"\"),\"invalid stencil.func\")}a(r+\"&&typeof \",r,'===\"object\"'),a('!(\"cmp\" in ',r,\")||(\",r,\".cmp in \",n,\")\")})),[t.def('\"cmp\" in ',r,\"?\",n,\"[\",r,\".cmp]\",\":\",Qr),t.def(r,\".ref|0\"),t.def('\"mask\" in ',r,\"?\",r,\".mask|0:-1\")]}));case nr:case ar:return f((function(r){_.commandType(r,\"object\",o,t.commandStr);var n=r.fail||\"keep\",a=r.zfail||\"keep\",i=r.zpass||\"keep\";return _.commandParameter(n,Kr,e+\".fail\",t.commandStr),_.commandParameter(a,Kr,e+\".zfail\",t.commandStr),_.commandParameter(i,Kr,e+\".zpass\",t.commandStr),[e===ar?Nr:Hr,Kr[n],Kr[a],Kr[i]]}),(function(t,r,n){var a=t.constants.stencilOps;function i(i){return _.optional((function(){t.assert(r,'!(\"'+i+'\" in '+n+\")||(\"+n+\".\"+i+\" in \"+a+\")\",\"invalid \"+e+\".\"+i+\", must be one of \"+Object.keys(Kr))})),r.def('\"',i,'\" in ',n,\"?\",a,\"[\",n,\".\",i,\"]:\",Qr)}return _.optional((function(){t.assert(r,n+\"&&typeof \"+n+'===\"object\"',\"invalid \"+e)})),[e===ar?Nr:Hr,i(\"fail\"),i(\"zfail\"),i(\"zpass\")]}));case $t:return f((function(e){_.commandType(e,\"object\",o,t.commandStr);var r=0|e.factor,n=0|e.units;return _.commandType(r,\"number\",o+\".factor\",t.commandStr),_.commandType(n,\"number\",o+\".units\",t.commandStr),[r,n]}),(function(t,r,n){return _.optional((function(){t.assert(r,n+\"&&typeof \"+n+'===\"object\"',\"invalid \"+e)})),[r.def(n,\".factor|0\"),r.def(n,\".units|0\")]}));case qt:return f((function(e){var r=0;return\"front\"===e?r=Hr:\"back\"===e&&(r=Nr),_.command(!!r,o,t.commandStr),r}),(function(e,t,r){return _.optional((function(){e.assert(t,r+'===\"front\"||'+r+'===\"back\"',\"invalid cull.face\")})),t.def(r,'===\"front\"?',Hr,\":\",Nr)}));case Yt:return f((function(e){return _.command(\"number\"==typeof e&&e>=a.lineWidthDims[0]&&e<=a.lineWidthDims[1],\"invalid line width, must be a positive number between \"+a.lineWidthDims[0]+\" and \"+a.lineWidthDims[1],t.commandStr),e}),(function(e,t,r){return _.optional((function(){e.assert(t,\"typeof \"+r+'===\"number\"&&'+r+\">=\"+a.lineWidthDims[0]+\"&&\"+r+\"<=\"+a.lineWidthDims[1],\"invalid line width\")})),r}));case Qt:return f((function(e){return _.commandParameter(e,Zr,o,t.commandStr),Zr[e]}),(function(e,t,r){return _.optional((function(){e.assert(t,r+'===\"cw\"||'+r+'===\"ccw\"',\"invalid frontFace, must be one of cw,ccw\")})),t.def(r+'===\"cw\"?2304:'+qr)}));case Ht:return f((function(e){return _.command(me(e)&&4===e.length,\"color.mask must be length 4 array\",t.commandStr),e.map((function(e){return!!e}))}),(function(e,t,r){return _.optional((function(){e.assert(t,e.shared.isArrayLike+\"(\"+r+\")&&\"+r+\".length===4\",\"invalid color.mask\")})),V(4,(function(e){return\"!!\"+r+\"[\"+e+\"]\"}))}));case Zt:return f((function(e){_.command(\"object\"==typeof e&&e,o,t.commandStr);var r=\"value\"in e?e.value:1,n=!!e.invert;return _.command(\"number\"==typeof r&&r>=0&&r<=1,\"sample.coverage.value must be a number between 0 and 1\",t.commandStr),[r,n]}),(function(e,t,r){return _.optional((function(){e.assert(t,r+\"&&typeof \"+r+'===\"object\"',\"invalid sample.coverage\")})),[t.def('\"value\" in ',r,\"?+\",r,\".value:1\"),t.def(\"!!\",r,\".invert\")]}))}})),i}(e,d),S=function(e,t,n){var a=e.static,i=e.dynamic;function o(e){if(e in a){var t=r.id(a[e]);_.optional((function(){l.shader(Jr[e],t,_.guessCommand())}));var n=an((function(){return t}));return n.id=t,n}if(e in i){var o=i[e];return on(o,(function(t,r){var n=t.invoke(r,o),a=r.def(t.shared.strings,\".id(\",n,\")\");return _.optional((function(){r(t.shared.shader,\".shader(\",Jr[e],\",\",a,\",\",t.command,\");\")})),a}))}return null}var f,u=o(lr),s=o(cr),c=null;return nn(u)&&nn(s)?(c=l.program(s.id,u.id,null,n),f=an((function(e,t){return e.link(c)}))):f=new rn(u&&u.thisDep||s&&s.thisDep,u&&u.contextDep||s&&s.contextDep,u&&u.propDep||s&&s.propDep,(function(e,t){var r,n=e.shared.shader;r=u?u.append(e,t):t.def(n,\".\",lr);var a=n+\".program(\"+(s?s.append(e,t):t.def(n,\".\",cr))+\",\"+r;return _.optional((function(){a+=\",\"+e.command})),t.def(a+\")\")})),{frag:u,vert:s,progVar:f,program:c}}(e,0,h);function O(e){var t=x[e];t&&(A[e]=t)}O(fr),O(E(or));var T=Object.keys(A).length>0,D={framebuffer:y,draw:w,shader:S,state:A,dirty:T,scopeVAO:null,drawVAO:null,useVAO:!1,attributes:{}};if(D.profile=function(e){var t,r=e.static,n=e.dynamic;if(ur in r){var a=!!r[ur];(t=an((function(e,t){return a}))).enable=a}else if(ur in n){var i=n[ur];t=on(i,(function(e,t){return e.invoke(t,i)}))}return t}(e),D.uniforms=function(e,t){var r=e.static,n=e.dynamic,a={};return Object.keys(r).forEach((function(e){var n,i=r[e];if(\"number\"==typeof i||\"boolean\"==typeof i)n=an((function(){return i}));else if(\"function\"==typeof i){var o=i._reglType;\"texture2d\"===o||\"textureCube\"===o?n=an((function(e){return e.link(i)})):\"framebuffer\"===o||\"framebufferCube\"===o?(_.command(i.color.length>0,'missing color attachment for framebuffer sent to uniform \"'+e+'\"',t.commandStr),n=an((function(e){return e.link(i.color[0])}))):_.commandRaise('invalid data for uniform \"'+e+'\"',t.commandStr)}else me(i)?n=an((function(t){return t.global.def(\"[\",V(i.length,(function(r){return _.command(\"number\"==typeof i[r]||\"boolean\"==typeof i[r],\"invalid uniform \"+e,t.commandStr),i[r]})),\"]\")})):_.commandRaise('invalid or missing data for uniform \"'+e+'\"',t.commandStr);n.value=i,a[e]=n})),Object.keys(n).forEach((function(e){var t=n[e];a[e]=on(t,(function(e,r){return e.invoke(r,t)}))})),a}(f,d),D.drawVAO=D.scopeVAO=w.vao,!D.drawVAO&&S.program&&!h&&n.angle_instanced_arrays&&w.static.elements){var j=!0,C=S.program.attributes.map((function(e){var r=t.static[e];return j=j&&!!r,r}));if(j&&C.length>0){var z=c.getVAO(c.createVAO({attributes:C,elements:w.static.elements}));D.drawVAO=new rn(null,null,null,(function(e,t){return e.link(z)})),D.useVAO=!0}}return h?D.useVAO=!0:D.attributes=function(e,t){var n=e.static,a=e.dynamic,o={};return Object.keys(n).forEach((function(e){var a=n[e],f=r.id(e),u=new b;if(en(a))u.state=1,u.buffer=i.getBuffer(i.create(a,Sr,!1,!0)),u.type=0;else{var s=i.getBuffer(a);if(s)u.state=1,u.buffer=s,u.type=0;else if(_.command(\"object\"==typeof a&&a,\"invalid data for attribute \"+e,t.commandStr),\"constant\"in a){var c=a.constant;u.buffer=\"null\",u.state=2,\"number\"==typeof c?u.x=c:(_.command(me(c)&&c.length>0&&c.length<=4,\"invalid constant for attribute \"+e,t.commandStr),Bt.forEach((function(e,t){t=0,'invalid offset for attribute \"'+e+'\"',t.commandStr);var d=0|a.stride;_.command(d>=0&&d<256,'invalid stride for attribute \"'+e+'\", must be integer betweeen [0, 255]',t.commandStr);var m=0|a.size;_.command(!(\"size\"in a)||m>0&&m<=4,'invalid size for attribute \"'+e+'\", must be 1,2,3,4',t.commandStr);var p=!!a.normalized,h=0;\"type\"in a&&(_.commandParameter(a.type,X,\"invalid type for attribute \"+e,t.commandStr),h=X[a.type]);var v=0|a.divisor;_.optional((function(){\"divisor\"in a&&(_.command(0===v||g,'cannot specify divisor for attribute \"'+e+'\", instancing not supported',t.commandStr),_.command(v>=0,'invalid divisor for attribute \"'+e+'\"',t.commandStr));var r=t.commandStr,n=[\"buffer\",\"offset\",\"divisor\",\"normalized\",\"type\",\"size\",\"stride\"];Object.keys(a).forEach((function(t){_.command(n.indexOf(t)>=0,'unknown parameter \"'+t+'\" for attribute pointer \"'+e+'\" (valid parameters are '+n+\")\",r)}))})),u.buffer=s,u.state=1,u.size=m,u.normalized=p,u.type=h||s.dtype,u.offset=l,u.stride=d,u.divisor=v}}o[e]=an((function(e,t){var r=e.attribCache;if(f in r)return r[f];var n={isStream:!1};return Object.keys(u).forEach((function(e){n[e]=u[e]})),u.buffer&&(n.buffer=e.link(u.buffer),n.type=n.type||n.buffer+\".dtype\"),r[f]=n,n}))})),Object.keys(a).forEach((function(e){var t=a[e];o[e]=on(t,(function(r,n){var a=r.invoke(n,t),i=r.shared,o=r.constants,f=i.isBufferArgs,u=i.buffer;_.optional((function(){r.assert(n,a+\"&&(typeof \"+a+'===\"object\"||typeof '+a+'===\"function\")&&('+f+\"(\"+a+\")||\"+u+\".getBuffer(\"+a+\")||\"+u+\".getBuffer(\"+a+\".buffer)||\"+f+\"(\"+a+'.buffer)||(\"constant\" in '+a+\"&&(typeof \"+a+'.constant===\"number\"||'+i.isArrayLike+\"(\"+a+\".constant))))\",'invalid dynamic attribute \"'+e+'\"')}));var s={isStream:n.def(!1)},c=new b;c.state=1,Object.keys(c).forEach((function(e){s[e]=n.def(\"\"+c[e])}));var l=s.buffer,d=s.type;function m(e){n(s[e],\"=\",a,\".\",e,\"|0;\")}return n(\"if(\",f,\"(\",a,\")){\",s.isStream,\"=true;\",l,\"=\",u,\".createStream(\",Sr,\",\",a,\");\",d,\"=\",l,\".dtype;\",\"}else{\",l,\"=\",u,\".getBuffer(\",a,\");\",\"if(\",l,\"){\",d,\"=\",l,\".dtype;\",'}else if(\"constant\" in ',a,\"){\",s.state,\"=\",2,\";\",\"if(typeof \"+a+'.constant === \"number\"){',s[Bt[0]],\"=\",a,\".constant;\",Bt.slice(1).map((function(e){return s[e]})).join(\"=\"),\"=0;\",\"}else{\",Bt.map((function(e,t){return s[e]+\"=\"+a+\".constant.length>\"+t+\"?\"+a+\".constant[\"+t+\"]:0;\"})).join(\"\"),\"}}else{\",\"if(\",f,\"(\",a,\".buffer)){\",l,\"=\",u,\".createStream(\",Sr,\",\",a,\".buffer);\",\"}else{\",l,\"=\",u,\".getBuffer(\",a,\".buffer);\",\"}\",d,'=\"type\" in ',a,\"?\",o.glTypes,\"[\",a,\".type]:\",l,\".dtype;\",s.normalized,\"=!!\",a,\".normalized;\"),m(\"size\"),m(\"offset\"),m(\"stride\"),m(\"divisor\"),n(\"}}\"),n.exit(\"if(\",s.isStream,\"){\",u,\".destroyStream(\",l,\");\",\"}\"),s}))})),o}(t,d),D.context=function(e){var t=e.static,r=e.dynamic,n={};return Object.keys(t).forEach((function(e){var r=t[e];n[e]=an((function(e,t){return\"number\"==typeof r||\"boolean\"==typeof r?\"\"+r:e.link(r)}))})),Object.keys(r).forEach((function(e){var t=r[e];n[e]=on(t,(function(e,r){return e.invoke(r,t)}))})),n}(s),D}function P(e,t,r){var n=e.shared.context,a=e.scope();Object.keys(r).forEach((function(i){t.save(n,\".\"+i);var o=r[i].append(e,t);Array.isArray(o)?a(n,\".\",i,\"=[\",o.join(),\"];\"):a(n,\".\",i,\"=\",o,\";\")})),t(a)}function L(e,t,r,n){var a,i=e.shared,o=i.gl,f=i.framebuffer;y&&(a=t.def(i.extensions,\".webgl_draw_buffers\"));var u,s=e.constants,c=s.drawBuffer,l=s.backBuffer;u=r?r.append(e,t):t.def(f,\".next\"),n||t(\"if(\",u,\"!==\",f,\".cur){\"),t(\"if(\",u,\"){\",o,\".bindFramebuffer(\",36160,\",\",u,\".framebuffer);\"),y&&t(a,\".drawBuffersWEBGL(\",c,\"[\",u,\".colorAttachments.length]);\"),t(\"}else{\",o,\".bindFramebuffer(\",36160,\",null);\"),y&&t(a,\".drawBuffersWEBGL(\",l,\");\"),t(\"}\",f,\".cur=\",u,\";\"),n||t(\"}\")}function R(e,t,r){var n=e.shared,a=n.gl,i=e.current,o=e.next,f=n.current,u=n.next,s=e.cond(f,\".dirty\");k.forEach((function(t){var n,c,l=E(t);if(!(l in r.state))if(l in o){n=o[l],c=i[l];var d=V(w[l].length,(function(e){return s.def(n,\"[\",e,\"]\")}));s(e.cond(d.map((function(e,t){return e+\"!==\"+c+\"[\"+t+\"]\"})).join(\"||\")).then(a,\".\",O[l],\"(\",d,\");\",d.map((function(e,t){return c+\"[\"+t+\"]=\"+e})).join(\";\"),\";\"))}else{n=s.def(u,\".\",l);var m=e.cond(n,\"!==\",f,\".\",l);s(m),l in S?m(e.cond(n).then(a,\".enable(\",S[l],\");\").else(a,\".disable(\",S[l],\");\"),f,\".\",l,\"=\",n,\";\"):m(a,\".\",O[l],\"(\",n,\");\",f,\".\",l,\"=\",n,\";\")}})),0===Object.keys(r.state).length&&s(f,\".dirty=false;\"),t(s)}function M(e,t,r,n){var a=e.shared,i=e.current,o=a.current,f=a.gl;tn(Object.keys(r)).forEach((function(a){var u=r[a];if(!n||n(u)){var s=u.append(e,t);if(S[a]){var c=S[a];nn(u)?t(f,s?\".enable(\":\".disable(\",c,\");\"):t(e.cond(s).then(f,\".enable(\",c,\");\").else(f,\".disable(\",c,\");\")),t(o,\".\",a,\"=\",s,\";\")}else if(me(s)){var l=i[a];t(f,\".\",O[a],\"(\",s,\");\",s.map((function(e,t){return l+\"[\"+t+\"]=\"+e})).join(\";\"),\";\")}else t(f,\".\",O[a],\"(\",s,\");\",o,\".\",a,\"=\",s,\";\")}}))}function W(e,t){g&&(e.instancing=t.def(e.shared.extensions,\".angle_instanced_arrays\"))}function U(e,t,r,n,a){var i,o,f,u=e.shared,s=e.stats,c=u.current,l=u.timer,d=r.profile;function m(){return\"undefined\"==typeof performance?\"Date.now()\":\"performance.now()\"}function h(e){e(i=t.def(),\"=\",m(),\";\"),\"string\"==typeof a?e(s,\".count+=\",a,\";\"):e(s,\".count++;\"),p&&(n?e(o=t.def(),\"=\",l,\".getNumPendingQueries();\"):e(l,\".beginQuery(\",s,\");\"))}function b(e){e(s,\".cpuTime+=\",m(),\"-\",i,\";\"),p&&(n?e(l,\".pushScopeStats(\",o,\",\",l,\".getNumPendingQueries(),\",s,\");\"):e(l,\".endQuery();\"))}function v(e){var r=t.def(c,\".profile\");t(c,\".profile=\",e,\";\"),t.exit(c,\".profile=\",r,\";\")}if(d){if(nn(d))return void(d.enable?(h(t),b(t.exit),v(\"true\")):v(\"false\"));v(f=d.append(e,t))}else f=t.def(c,\".profile\");var g=e.block();h(g),t(\"if(\",f,\"){\",g,\"}\");var y=e.block();b(y),t.exit(\"if(\",f,\"){\",y,\"}\")}function G(e,t,r,n,a){var i=e.shared;n.forEach((function(n){var o,f=n.name,u=r.attributes[f];if(u){if(!a(u))return;o=u.append(e,t)}else{if(!a(fn))return;var s=e.scopeAttrib(f);_.optional((function(){e.assert(t,s+\".state\",\"missing attribute \"+f)})),o={},Object.keys(new b).forEach((function(e){o[e]=t.def(s,\".\",e)}))}!function(r,n,a){var o=i.gl,f=t.def(r,\".location\"),u=t.def(i.attributes,\"[\",f,\"]\"),s=a.state,c=a.buffer,l=[a.x,a.y,a.z,a.w],d=[\"buffer\",\"normalized\",\"offset\",\"stride\"];function m(){t(\"if(!\",u,\".buffer){\",o,\".enableVertexAttribArray(\",f,\");}\");var r,i=a.type;if(r=a.size?t.def(a.size,\"||\",n):n,t(\"if(\",u,\".type!==\",i,\"||\",u,\".size!==\",r,\"||\",d.map((function(e){return u+\".\"+e+\"!==\"+a[e]})).join(\"||\"),\"){\",o,\".bindBuffer(\",Sr,\",\",c,\".buffer);\",o,\".vertexAttribPointer(\",[f,r,i,a.normalized,a.stride,a.offset],\");\",u,\".type=\",i,\";\",u,\".size=\",r,\";\",d.map((function(e){return u+\".\"+e+\"=\"+a[e]+\";\"})).join(\"\"),\"}\"),g){var s=a.divisor;t(\"if(\",u,\".divisor!==\",s,\"){\",e.instancing,\".vertexAttribDivisorANGLE(\",[f,s],\");\",u,\".divisor=\",s,\";}\")}}function p(){t(\"if(\",u,\".buffer){\",o,\".disableVertexAttribArray(\",f,\");\",u,\".buffer=null;\",\"}if(\",Bt.map((function(e,t){return u+\".\"+e+\"!==\"+l[t]})).join(\"||\"),\"){\",o,\".vertexAttrib4f(\",f,\",\",l,\");\",Bt.map((function(e,t){return u+\".\"+e+\"=\"+l[t]+\";\"})).join(\"\"),\"}\")}1===s?m():2===s?p():(t(\"if(\",s,\"===\",1,\"){\"),m(),t(\"}else{\"),p(),t(\"}\"))}(e.link(n),function(e){switch(e){case Tr:case zr:case Ir:return 2;case Dr:case Fr:case Pr:return 3;case jr:case Br:case Lr:return 4;default:return 1}}(n.info.type),o)}))}function H(e,t,n,a,i,o){for(var f,u=e.shared,s=u.gl,c={},l=0;l1){if(!b)continue;var v=m.replace(\"[0]\",\"\");if(c[v])continue;c[v]=1}var g,y=e.link(d)+\".location\";if(b){if(!i(b))continue;if(nn(b)){var x=b.value;if(_.command(null!=x,'missing uniform \"'+m+'\"',e.commandStr),p===Ur||p===Gr){_.command(\"function\"==typeof x&&(p===Ur&&(\"texture2d\"===x._reglType||\"framebuffer\"===x._reglType)||p===Gr&&(\"textureCube\"===x._reglType||\"framebufferCube\"===x._reglType)),\"invalid texture for uniform \"+m,e.commandStr);var w=e.link(x._texture||x.color[0]._texture);t(s,\".uniform1i(\",y,\",\",w+\".bind());\"),t.exit(w,\".unbind();\")}else if(p===Rr||p===Mr||p===Wr){_.optional((function(){_.command(me(x),\"invalid matrix for uniform \"+m,e.commandStr),_.command(p===Rr&&4===x.length||p===Mr&&9===x.length||p===Wr&&16===x.length,\"invalid length for matrix uniform \"+m,e.commandStr)}));var A=e.global.def(\"new Float32Array([\"+Array.prototype.slice.call(x)+\"])\"),k=2;p===Mr?k=3:p===Wr&&(k=4),t(s,\".uniformMatrix\",k,\"fv(\",y,\",false,\",A,\");\")}else{switch(p){case Er:1===h?_.commandType(x,\"number\",\"uniform \"+m,e.commandStr):_.command(me(x)&&x.length===h,\"uniform \"+m,e.commandStr),f=\"1f\";break;case Tr:_.command(me(x)&&x.length&&x.length%2==0&&x.length<=2*h,\"uniform \"+m,e.commandStr),f=\"2f\";break;case Dr:_.command(me(x)&&x.length&&x.length%3==0&&x.length<=3*h,\"uniform \"+m,e.commandStr),f=\"3f\";break;case jr:_.command(me(x)&&x.length&&x.length%4==0&&x.length<=4*h,\"uniform \"+m,e.commandStr),f=\"4f\";break;case Vr:1===h?_.commandType(x,\"boolean\",\"uniform \"+m,e.commandStr):_.command(me(x)&&x.length===h,\"uniform \"+m,e.commandStr),f=\"1i\";break;case Cr:1===h?_.commandType(x,\"number\",\"uniform \"+m,e.commandStr):_.command(me(x)&&x.length===h,\"uniform \"+m,e.commandStr),f=\"1i\";break;case Ir:case zr:_.command(me(x)&&x.length&&x.length%2==0&&x.length<=2*h,\"uniform \"+m,e.commandStr),f=\"2i\";break;case Pr:case Fr:_.command(me(x)&&x.length&&x.length%3==0&&x.length<=3*h,\"uniform \"+m,e.commandStr),f=\"3i\";break;case Lr:case Br:_.command(me(x)&&x.length&&x.length%4==0&&x.length<=4*h,\"uniform \"+m,e.commandStr),f=\"4i\"}h>1?(f+=\"v\",x=e.global.def(\"[\"+Array.prototype.slice.call(x)+\"]\")):x=me(x)?Array.prototype.slice.call(x):x,t(s,\".uniform\",f,\"(\",y,\",\",x,\");\")}continue}g=b.append(e,t)}else{if(!i(fn))continue;g=t.def(u.uniforms,\"[\",r.id(m),\"]\")}p===Ur?(_(!Array.isArray(g),\"must specify a scalar prop for textures\"),t(\"if(\",g,\"&&\",g,'._reglType===\"framebuffer\"){',g,\"=\",g,\".color[0];\",\"}\")):p===Gr&&(_(!Array.isArray(g),\"must specify a scalar prop for cube maps\"),t(\"if(\",g,\"&&\",g,'._reglType===\"framebufferCube\"){',g,\"=\",g,\".color[0];\",\"}\")),_.optional((function(){function r(r,n){e.assert(t,r,'bad data or missing for uniform \"'+m+'\". '+n)}function n(e,t){1===t&&_(!Array.isArray(g),\"must not specify an array type for uniform\"),r(\"Array.isArray(\"+g+\") && typeof \"+g+'[0]===\" '+e+'\" || typeof '+g+'===\"'+e+'\"',\"invalid type, expected \"+e)}function a(t,n,a){Array.isArray(g)?_(g.length&&g.length%t==0&&g.length<=t*a,\"must have length of \"+(1===a?\"\":\"n * \")+t):r(u.isArrayLike+\"(\"+g+\")&&\"+g+\".length && \"+g+\".length % \"+t+\" === 0 && \"+g+\".length<=\"+t*a,\"invalid vector, should have length of \"+(1===a?\"\":\"n * \")+t,e.commandStr)}function i(t){_(!Array.isArray(g),\"must not specify a value type\"),r(\"typeof \"+g+'===\"function\"&&'+g+'._reglType===\"texture'+(3553===t?\"2d\":\"Cube\")+'\"',\"invalid texture type\",e.commandStr)}switch(p){case Cr:n(\"number\",h);break;case zr:a(2,0,h);break;case Fr:a(3,0,h);break;case Br:a(4,0,h);break;case Er:n(\"number\",h);break;case Tr:a(2,0,h);break;case Dr:a(3,0,h);break;case jr:a(4,0,h);break;case Vr:n(\"boolean\",h);break;case Ir:a(2,0,h);break;case Pr:a(3,0,h);break;case Lr:case Rr:a(4,0,h);break;case Mr:a(9,0,h);break;case Wr:a(16,0,h);break;case Ur:i(3553);break;case Gr:i(34067)}}));var S=1;switch(p){case Ur:case Gr:var O=t.def(g,\"._texture\");t(s,\".uniform1i(\",y,\",\",O,\".bind());\"),t.exit(O,\".unbind();\");continue;case Cr:case Vr:f=\"1i\";break;case zr:case Ir:f=\"2i\",S=2;break;case Fr:case Pr:f=\"3i\",S=3;break;case Br:case Lr:f=\"4i\",S=4;break;case Er:f=\"1f\";break;case Tr:f=\"2f\",S=2;break;case Dr:f=\"3f\",S=3;break;case jr:f=\"4f\",S=4;break;case Rr:f=\"Matrix2fv\";break;case Mr:f=\"Matrix3fv\";break;case Wr:f=\"Matrix4fv\"}if(-1===f.indexOf(\"Matrix\")&&h>1&&(f+=\"v\",S=1),\"M\"===f.charAt(0)){t(s,\".uniform\",f,\"(\",y,\",\");var E=Math.pow(p-Rr+2,2),T=e.global.def(\"new Float32Array(\",E,\")\");Array.isArray(g)?t(\"false,(\",V(E,(function(e){return T+\"[\"+e+\"]=\"+g[e]})),\",\",T,\")\"):t(\"false,(Array.isArray(\",g,\")||\",g,\" instanceof Float32Array)?\",g,\":(\",V(E,(function(e){return T+\"[\"+e+\"]=\"+g+\"[\"+e+\"]\"})),\",\",T,\")\"),t(\");\")}else if(S>1){for(var D=[],j=[],C=0;C=0\",\"missing vertex count\")}))):(a=u.def(o,\".\",pr),_.optional((function(){e.assert(u,a+\">=0\",\"missing vertex count\")}))),a}();if(\"number\"==typeof p){if(0===p)return}else r(\"if(\",p,\"){\"),r.exit(\"}\");g&&(c=s(br),l=e.instancing);var h=u+\".type\",b=f.elements&&nn(f.elements)&&!f.vaoActive;function v(){function e(){r(l,\".drawElementsInstancedANGLE(\",[d,p,h,m+\"<<((\"+h+\"-5121)>>1)\",c],\");\")}function t(){r(l,\".drawArraysInstancedANGLE(\",[d,m,p,c],\");\")}u&&\"null\"!==u?b?e():(r(\"if(\",u,\"){\"),e(),r(\"}else{\"),t(),r(\"}\")):t()}function y(){function e(){r(i+\".drawElements(\"+[d,p,h,m+\"<<((\"+h+\"-5121)>>1)\"]+\");\")}function t(){r(i+\".drawArrays(\"+[d,m,p]+\");\")}u&&\"null\"!==u?b?e():(r(\"if(\",u,\"){\"),e(),r(\"}else{\"),t(),r(\"}\")):t()}g&&(\"number\"!=typeof c||c>=0)?\"string\"==typeof c?(r(\"if(\",c,\">0){\"),v(),r(\"}else if(\",c,\"<0){\"),y(),r(\"}\")):v():y()}function q(e,t,r,n,a){var i=B(),o=i.proc(\"body\",a);return _.optional((function(){i.commandStr=t.commandStr,i.command=i.link(t.commandStr)})),g&&(i.instancing=o.def(i.shared.extensions,\".angle_instanced_arrays\")),e(i,o,r,n),i.compile().body}function Q(e,t,r,n){W(e,t),r.useVAO?r.drawVAO?t(e.shared.vao,\".setVAO(\",r.drawVAO.append(e,t),\");\"):t(e.shared.vao,\".setVAO(\",e.shared.vao,\".targetVAO);\"):(t(e.shared.vao,\".setVAO(null);\"),G(e,t,r,n.attributes,(function(){return!0}))),H(e,t,r,n.uniforms,(function(){return!0}),!1),N(e,t,t,r)}function Y(e,t,r,n){function a(){return!0}e.batchId=\"a1\",W(e,t),G(e,t,r,n.attributes,a),H(e,t,r,n.uniforms,a,!1),N(e,t,t,r)}function $(e,t,r,n){W(e,t);var a=r.contextDep,i=t.def(),o=t.def();e.shared.props=o,e.batchId=i;var f=e.scope(),u=e.scope();function s(e){return e.contextDep&&a||e.propDep}function c(e){return!s(e)}if(t(f.entry,\"for(\",i,\"=0;\",i,\"<\",\"a1\",\";++\",i,\"){\",o,\"=\",\"a0\",\"[\",i,\"];\",u,\"}\",f.exit),r.needsContext&&P(e,u,r.context),r.needsFramebuffer&&L(e,u,r.framebuffer),M(e,u,r.state,s),r.profile&&s(r.profile)&&U(e,u,r,!1,!0),n)r.useVAO?r.drawVAO?s(r.drawVAO)?u(e.shared.vao,\".setVAO(\",r.drawVAO.append(e,u),\");\"):f(e.shared.vao,\".setVAO(\",r.drawVAO.append(e,f),\");\"):f(e.shared.vao,\".setVAO(\",e.shared.vao,\".targetVAO);\"):(f(e.shared.vao,\".setVAO(null);\"),G(e,f,r,n.attributes,c),G(e,u,r,n.attributes,s)),H(e,f,r,n.uniforms,c,!1),H(e,u,r,n.uniforms,s,!0),N(e,f,u,r);else{var l=e.global.def(\"{}\"),d=r.shader.progVar.append(e,u),m=u.def(d,\".id\"),p=u.def(l,\"[\",m,\"]\");u(e.shared.gl,\".useProgram(\",d,\".program);\",\"if(!\",p,\"){\",p,\"=\",l,\"[\",m,\"]=\",e.link((function(t){return q(Y,e,r,t,2)})),\"(\",d,\");}\",p,\".call(this,a0[\",i,\"],\",i,\");\")}}function K(e,t,r){var n=t.static[r];if(n&&function(e){if(\"object\"==typeof e&&!me(e)){for(var t=Object.keys(e),r=0;r0&&r(e.shared.current,\".dirty=true;\"),e.shared.vao&&r(e.shared.vao,\".setVAO(null);\")}(f,u),function(e,t){var n=e.proc(\"scope\",3);e.batchId=\"a2\";var a=e.shared,i=a.current;function o(r){var i=t.shader[r];i&&n.set(a.shader,\".\"+r,i.append(e,n))}P(e,n,t.context),t.framebuffer&&t.framebuffer.append(e,n),tn(Object.keys(t.state)).forEach((function(r){var i=t.state[r].append(e,n);me(i)?i.forEach((function(t,a){n.set(e.next[r],\"[\"+a+\"]\",t)})):n.set(a.next,\".\"+r,i)})),U(e,n,t,!0,!0),[dr,hr,pr,br,mr].forEach((function(r){var i=t.draw[r];i&&n.set(a.draw,\".\"+r,\"\"+i.append(e,n))})),Object.keys(t.uniforms).forEach((function(i){var o=t.uniforms[i].append(e,n);Array.isArray(o)&&(o=\"[\"+o.join()+\"]\"),n.set(a.uniforms,\"[\"+r.id(i)+\"]\",o)})),Object.keys(t.attributes).forEach((function(r){var a=t.attributes[r].append(e,n),i=e.scopeAttrib(r);Object.keys(new b).forEach((function(e){n.set(i,\".\"+e,a[e])}))})),t.scopeVAO&&n.set(a.vao,\".targetVAO\",t.scopeVAO.append(e,n)),o(cr),o(lr),Object.keys(t.state).length>0&&(n(i,\".dirty=true;\"),n.exit(i,\".dirty=true;\")),n(\"a1(\",e.shared.context,\",a0,\",e.batchId,\");\")}(f,u),function(e,t){var r=e.proc(\"batch\",2);e.batchId=\"0\",W(e,r);var n=!1,a=!0;Object.keys(t.context).forEach((function(e){n=n||t.context[e].propDep})),n||(P(e,r,t.context),a=!1);var i=t.framebuffer,o=!1;function f(e){return e.contextDep&&n||e.propDep}i?(i.propDep?n=o=!0:i.contextDep&&n&&(o=!0),o||L(e,r,i)):L(e,r,null),t.state.viewport&&t.state.viewport.propDep&&(n=!0),R(e,r,t),M(e,r,t.state,(function(e){return!f(e)})),t.profile&&f(t.profile)||U(e,r,t,!1,\"a1\"),t.contextDep=n,t.needsContext=a,t.needsFramebuffer=o;var u=t.shader.progVar;if(u.contextDep&&n||u.propDep)$(e,r,t,null);else{var s=u.append(e,r);if(r(e.shared.gl,\".useProgram(\",s,\".program);\"),t.shader.program)$(e,r,t,t.shader.program);else{r(e.shared.vao,\".setVAO(null);\");var c=e.global.def(\"{}\"),l=r.def(s,\".id\"),d=r.def(c,\"[\",l,\"]\");r(e.cond(d).then(d,\".call(this,a0,a1);\").else(d,\"=\",c,\"[\",l,\"]=\",e.link((function(r){return q($,e,t,r,2)})),\"(\",s,\");\",d,\".call(this,a0,a1);\"))}}Object.keys(t.state).length>0&&r(e.shared.current,\".dirty=true;\"),e.shared.vao&&r(e.shared.vao,\".setVAO(null);\")}(f,u),t(f.compile(),{destroy:function(){u.shader.program.destroy()}})}}}var sn=function(e,t){if(!t.ext_disjoint_timer_query)return null;var r=[];function n(e){r.push(e)}var a=[];function i(){this.startQueryIndex=-1,this.endQueryIndex=-1,this.sum=0,this.stats=null}var o=[];function f(e){o.push(e)}var u=[];function s(e,t,r){var n=o.pop()||new i;n.startQueryIndex=e,n.endQueryIndex=t,n.sum=0,n.stats=r,u.push(n)}var c=[],l=[];return{beginQuery:function(e){var n=r.pop()||t.ext_disjoint_timer_query.createQueryEXT();t.ext_disjoint_timer_query.beginQueryEXT(35007,n),a.push(n),s(a.length-1,a.length,e)},endQuery:function(){t.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:s,update:function(){var e,r,i=a.length;if(0!==i){l.length=Math.max(l.length,i+1),c.length=Math.max(c.length,i+1),c[0]=0,l[0]=0;var o=0;for(e=0,r=0;r0)if(Array.isArray(r[0])){f=J(r);for(var c=1,l=1;l0)if(\"number\"==typeof t[0]){var i=L.allocType(d.dtype,t.length);ne(i,t),p(i,a),L.freeType(i)}else if(Array.isArray(t[0])||e(t[0])){n=J(t);var o=K(t,n,d.dtype);p(o,a),L.freeType(o)}else _.raise(\"invalid buffer data\")}else if(G(t)){n=t.shape;var f=t.stride,u=0,s=0,c=0,l=0;1===n.length?(u=n[0],s=1,c=f[0],l=0):2===n.length?(u=n[0],s=n[1],c=f[0],l=f[1]):_.raise(\"invalid shape\");var h=Array.isArray(t.data)?d.dtype:re(t.data),b=L.allocType(h,u*s);ae(b,t.data,u,s,c,l,t.offset),p(b,a),L.freeType(b)}else _.raise(\"invalid data for buffer subdata\");return m},n.profile&&(m.stats=d.stats),m.destroy=function(){l(d)},m},createStream:function(e,t){var r=u.pop();return r||(r=new f(e)),r.bind(),c(r,t,35040,0,1,!1),r},destroyStream:function(e){u.push(e)},clear:function(){H(o).forEach(l),u.forEach(l)},getBuffer:function(e){return e&&e._buffer instanceof f?e._buffer:null},restore:function(){H(o).forEach((function(e){e.buffer=t.createBuffer(),t.bindBuffer(e.type,e.buffer),t.bufferData(e.type,e.persistentData||e.byteLength,e.usage)}))},_initBuffer:c}}(a,l,n,(function(e){return A.destroyBuffer(e)})),w=function(t,r,n,a){var i={},o=0,f={uint8:oe,uint16:fe};function u(e){this.id=o++,i[this.id]=this,this.buffer=e,this.primType=4,this.vertCount=0,this.type=0}r.oes_element_index_uint&&(f.uint32=ue),u.prototype.bind=function(){this.buffer.bind()};var s=[];function c(a,i,o,f,u,s,c){var l;if(a.buffer.bind(),i){var d=c;c||e(i)&&(!G(i)||e(i.data))||(d=r.oes_element_index_uint?ue:fe),n._initBuffer(a.buffer,i,o,d,3)}else t.bufferData(se,s,o),a.buffer.dtype=l||oe,a.buffer.usage=o,a.buffer.dimension=3,a.buffer.byteLength=s;if(l=c,!c){switch(a.buffer.dtype){case oe:case 5120:l=oe;break;case fe:case 5122:l=fe;break;case ue:case 5124:l=ue;break;default:_.raise(\"unsupported type for element array\")}a.buffer.dtype=l}a.type=l,_(l!==ue||!!r.oes_element_index_uint,\"32 bit element buffers not supported, enable oes_element_index_uint first\");var m=u;m<0&&(m=a.buffer.byteLength,l===fe?m>>=1:l===ue&&(m>>=2)),a.vertCount=m;var p=f;if(f<0){p=4;var h=a.buffer.dimension;1===h&&(p=0),2===h&&(p=1),3===h&&(p=4)}a.primType=p}function l(e){a.elementsCount--,_(null!==e.buffer,\"must not double destroy elements\"),delete i[e.id],e.buffer.destroy(),e.buffer=null}return{create:function(t,r){var i=n.create(null,se,!0),o=new u(i._buffer);function s(t){if(t)if(\"number\"==typeof t)i(t),o.primType=4,o.vertCount=0|t,o.type=oe;else{var r=null,n=35044,a=-1,u=-1,l=0,d=0;Array.isArray(t)||e(t)||G(t)?r=t:(_.type(t,\"object\",\"invalid arguments for elements\"),\"data\"in t&&(r=t.data,_(Array.isArray(r)||e(r)||G(r),\"invalid data for element buffer\")),\"usage\"in t&&(_.parameter(t.usage,$,\"invalid element buffer usage\"),n=$[t.usage]),\"primitive\"in t&&(_.parameter(t.primitive,ie,\"invalid element buffer primitive\"),a=ie[t.primitive]),\"count\"in t&&(_(\"number\"==typeof t.count&&t.count>=0,\"invalid vertex count for elements\"),u=0|t.count),\"type\"in t&&(_.parameter(t.type,f,\"invalid buffer type\"),d=f[t.type]),\"length\"in t?l=0|t.length:(l=u,d===fe||5122===d?l*=2:d!==ue&&5124!==d||(l*=4))),c(o,r,n,a,u,l,d)}else i(),o.primType=4,o.vertCount=0,o.type=oe;return s}return a.elementsCount++,s(t),s._reglType=\"elements\",s._elements=o,s.subdata=function(e,t){return i.subdata(e,t),s},s.destroy=function(){l(o)},s},createStream:function(e){var t=s.pop();return t||(t=new u(n.create(null,se,!0,!1)._buffer)),c(t,e,35040,-1,-1,0,0),t},destroyStream:function(e){s.push(e)},getElements:function(e){return\"function\"==typeof e&&e._elements instanceof u?e._elements:null},clear:function(){H(i).forEach(l)}}}(a,d,x,l),A=function(t,r,n,a,i,o,f){for(var u=n.maxAttributes,s=new Array(u),c=0;c{for(var e=Object.keys(t),r=0;r=0,'invalid option for vao: \"'+e[r]+'\" valid options are '+Et)})),_(Array.isArray(a),\"attributes must be an array\")}_(a.length0,\"must specify at least one attribute\");var c={},l=n.attributes;l.length=a.length;for(var d=0;d=b.byteLength?m.subdata(b):(m.destroy(),n.buffers[d]=null)),n.buffers[d]||(m=n.buffers[d]=i.create(p,34962,!1,!0)),h.buffer=i.getBuffer(m),h.size=0|h.buffer.dimension,h.normalized=!1,h.type=h.buffer.dtype,h.offset=0,h.stride=0,h.divisor=0,h.state=1,c[d]=1):i.getBuffer(p)?(h.buffer=i.getBuffer(p),h.size=0|h.buffer.dimension,h.normalized=!1,h.type=h.buffer.dtype,h.offset=0,h.stride=0,h.divisor=0,h.state=1):i.getBuffer(p.buffer)?(h.buffer=i.getBuffer(p.buffer),h.size=0|(+p.size||h.buffer.dimension),h.normalized=!!p.normalized||!1,\"type\"in p?(_.parameter(p.type,X,\"invalid buffer type\"),h.type=X[p.type]):h.type=h.buffer.dtype,h.offset=0|(p.offset||0),h.stride=0|(p.stride||0),h.divisor=0|(p.divisor||0),h.state=1,_(h.size>=1&&h.size<=4,\"size must be between 1 and 4\"),_(h.offset>=0,\"invalid offset\"),_(h.stride>=0&&h.stride<=255,\"stride must be between 0 and 255\"),_(h.divisor>=0,\"divisor must be positive\"),_(!h.divisor||!!r.angle_instanced_arrays,\"ANGLE_instanced_arrays must be enabled to use divisor\")):\"x\"in p?(_(d>0,\"first attribute must not be a constant\"),h.x=+p.x||0,h.y=+p.y||0,h.z=+p.z||0,h.w=+p.w||0,h.state=2):_(!1,\"invalid attribute spec for location \"+d)}for(var v=0;v1)for(var v=0;v1&&(y=y.replace(\"[0]\",\"\")),u(b,new f(y,r.id(y),e.getUniformLocation(m,y),c))}var x=e.getProgramParameter(m,35721);a.profile&&(t.stats.attributesCount=x);var w=t.attributes;for(o=0;oe&&(e=t.stats.uniformsCount)})),e},n.getMaxAttributesCount=function(){var e=0;return l.forEach((function(t){t.stats.attributesCount>e&&(e=t.stats.attributesCount)})),e}),{clear:function(){var t=e.deleteShader.bind(e);H(i).forEach(t),i={},H(o).forEach(t),o={},l.forEach((function(t){e.deleteProgram(t.program)})),l.length=0,c={},n.shaderCount=0},program:function(r,a,f,u){_.command(r>=0,\"missing vertex shader\",f),_.command(a>=0,\"missing fragment shader\",f);var s=c[a];s||(s=c[a]={});var d=s[r];if(d&&(d.refCount++,!u))return d;var h=new m(a,r);return n.shaderCount++,p(h,f,u),d||(s[r]=h),l.push(h),t(h,{destroy:function(){if(h.refCount--,h.refCount<=0){e.deleteProgram(h.program);var t=l.indexOf(h);l.splice(t,1),n.shaderCount--}s[h.vertId].refCount<=0&&(e.deleteShader(o[h.vertId]),delete o[h.vertId],delete c[h.fragId][h.vertId]),Object.keys(c[h.fragId]).length||(e.deleteShader(i[h.fragId]),delete i[h.fragId],delete c[h.fragId])}})},restore:function(){i={},o={};for(var e=0;e=2,\"invalid renderbuffer shape\"),f=0|m[0],u=0|m[1]}else\"radius\"in d&&(f=u=0|d.radius),\"width\"in d&&(f=0|d.width),\"height\"in d&&(u=0|d.height);\"format\"in d&&(_.parameter(d.format,i,\"invalid renderbuffer format\"),s=i[d.format])}else\"number\"==typeof t?(f=0|t,u=\"number\"==typeof n?0|n:f):t?_.raise(\"invalid arguments to renderbuffer constructor\"):f=u=1;if(_(f>0&&u>0&&f<=r.maxRenderbufferSize&&u<=r.maxRenderbufferSize,\"invalid renderbuffer size\"),f!==c.width||u!==c.height||s!==c.format)return l.width=c.width=f,l.height=c.height=u,c.format=s,e.bindRenderbuffer(mt,c.renderbuffer),e.renderbufferStorage(mt,s,f,u),_(0===e.getError(),\"invalid render buffer format\"),a.profile&&(c.stats.size=bt(c.format,c.width,c.height)),l.format=o[c.format],l}return u[c.id]=c,n.renderbufferCount++,l(t,f),l.resize=function(t,n){var i=0|t,o=0|n||i;return i===c.width&&o===c.height||(_(i>0&&o>0&&i<=r.maxRenderbufferSize&&o<=r.maxRenderbufferSize,\"invalid renderbuffer size\"),l.width=c.width=i,l.height=c.height=o,e.bindRenderbuffer(mt,c.renderbuffer),e.renderbufferStorage(mt,c.format,i,o),_(0===e.getError(),\"invalid render buffer format\"),a.profile&&(c.stats.size=bt(c.format,c.width,c.height))),l},l._reglType=\"renderbuffer\",l._renderbuffer=c,a.profile&&(l.stats=c.stats),l.destroy=function(){c.decRef()},l},clear:function(){H(u).forEach(c)},restore:function(){H(u).forEach((function(t){t.renderbuffer=e.createRenderbuffer(),e.bindRenderbuffer(mt,t.renderbuffer),e.renderbufferStorage(mt,t.format,t.width,t.height)})),e.bindRenderbuffer(mt,null)}}}(a,d,y,l,n),E=function(e,r,n,a,i,o){var f={cur:null,next:null,dirty:!1,setFBO:null},u=[\"rgba\"],s=[\"rgba4\",\"rgb565\",\"rgb5 a1\"];r.ext_srgb&&s.push(\"srgba\"),r.ext_color_buffer_half_float&&s.push(\"rgba16f\",\"rgb16f\"),r.webgl_color_buffer_float&&s.push(\"rgba32f\");var c=[\"uint8\"];function l(e,t,r){this.target=e,this.texture=t,this.renderbuffer=r;var n=0,a=0;t?(n=t.width,a=t.height):r&&(n=r.width,a=r.height),this.width=n,this.height=a}function d(e){e&&(e.texture&&e.texture._texture.decRef(),e.renderbuffer&&e.renderbuffer._renderbuffer.decRef())}function m(e,t,r){if(e)if(e.texture){var n=e.texture._texture,a=Math.max(1,n.width),i=Math.max(1,n.height);_(a===t&&i===r,\"inconsistent width/height for supplied texture\"),n.refCount+=1}else{var o=e.renderbuffer._renderbuffer;_(o.width===t&&o.height===r,\"inconsistent width/height for renderbuffer\"),o.refCount+=1}}function p(t,r){r&&(r.texture?e.framebufferTexture2D(vt,t,r.target,r.texture._texture.texture,0):e.framebufferRenderbuffer(vt,t,gt,r.renderbuffer._renderbuffer.renderbuffer))}function h(e){var t=yt,r=null,n=null,a=e;\"object\"==typeof e&&(a=e.data,\"target\"in e&&(t=0|e.target)),_.type(a,\"function\",\"invalid attachment data\");var i=a._reglType;return\"texture2d\"===i?(r=a,_(t===yt)):\"textureCube\"===i?(r=a,_(t>=xt&&t<34075,\"invalid cube map target\")):\"renderbuffer\"===i?(n=a,t=gt):_.raise(\"invalid regl object for attachment\"),new l(t,r,n)}function b(e,t,r,n,o){if(r){var f=a.create2D({width:e,height:t,format:n,type:o});return f._texture.refCount=0,new l(yt,f,null)}var u=i.create({width:e,height:t,format:n});return u._renderbuffer.refCount=0,new l(gt,null,u)}function v(e){return e&&(e.texture||e.renderbuffer)}function g(e,t,r){e&&(e.texture?e.texture.resize(t,r):e.renderbuffer&&e.renderbuffer.resize(t,r),e.width=t,e.height=r)}r.oes_texture_half_float&&c.push(\"half float\",\"float16\"),r.oes_texture_float&&c.push(\"float\",\"float32\");var y=0,x={};function w(){this.id=y++,x[this.id]=this,this.framebuffer=e.createFramebuffer(),this.width=0,this.height=0,this.colorAttachments=[],this.depthAttachment=null,this.stencilAttachment=null,this.depthStencilAttachment=null}function A(e){e.colorAttachments.forEach(d),d(e.depthAttachment),d(e.stencilAttachment),d(e.depthStencilAttachment)}function k(t){var r=t.framebuffer;_(r,\"must not double destroy framebuffer\"),e.deleteFramebuffer(r),t.framebuffer=null,o.framebufferCount--,delete x[t.id]}function S(t){var r;e.bindFramebuffer(vt,t.framebuffer);var a=t.colorAttachments;for(r=0;r=2,\"invalid shape for framebuffer\"),o=z[0],d=z[1]}else\"radius\"in C&&(o=d=C.radius),\"width\"in C&&(o=C.width),\"height\"in C&&(d=C.height);(\"color\"in C||\"colors\"in C)&&(y=C.color||C.colors,Array.isArray(y)&&_(1===y.length||r.webgl_draw_buffers,\"multiple render targets not supported\")),y||(\"colorCount\"in C&&(O=0|C.colorCount,_(O>0,\"invalid color buffer count\")),\"colorTexture\"in C&&(x=!!C.colorTexture,w=\"rgba4\"),\"colorType\"in C&&(k=C.colorType,x?(_(r.oes_texture_float||!(\"float\"===k||\"float32\"===k),\"you must enable OES_texture_float in order to use floating point framebuffer objects\"),_(r.oes_texture_half_float||!(\"half float\"===k||\"float16\"===k),\"you must enable OES_texture_half_float in order to use 16-bit floating point framebuffer objects\")):\"half float\"===k||\"float16\"===k?(_(r.ext_color_buffer_half_float,\"you must enable EXT_color_buffer_half_float to use 16-bit render buffers\"),w=\"rgba16f\"):\"float\"!==k&&\"float32\"!==k||(_(r.webgl_color_buffer_float,\"you must enable WEBGL_color_buffer_float in order to use 32-bit floating point renderbuffers\"),w=\"rgba32f\"),_.oneOf(k,c,\"invalid color type\")),\"colorFormat\"in C&&(w=C.colorFormat,u.indexOf(w)>=0?x=!0:s.indexOf(w)>=0?x=!1:_.optional((function(){x?_.oneOf(C.colorFormat,u,\"invalid color format for texture\"):_.oneOf(C.colorFormat,s,\"invalid color format for renderbuffer\")})))),(\"depthTexture\"in C||\"depthStencilTexture\"in C)&&(j=!(!C.depthTexture&&!C.depthStencilTexture),_(!j||r.webgl_depth_texture,\"webgl_depth_texture extension not supported\")),\"depth\"in C&&(\"boolean\"==typeof C.depth?p=C.depth:(E=C.depth,g=!1)),\"stencil\"in C&&(\"boolean\"==typeof C.stencil?g=C.stencil:(T=C.stencil,p=!1)),\"depthStencil\"in C&&(\"boolean\"==typeof C.depthStencil?p=g=C.depthStencil:(D=C.depthStencil,p=!1,g=!1))}else o=d=1;var F=null,B=null,V=null,I=null;if(Array.isArray(y))F=y.map(h);else if(y)F=[h(y)];else for(F=new Array(O),a=0;a=0||F[a].renderbuffer&&kt.indexOf(F[a].renderbuffer._renderbuffer.format)>=0,\"framebuffer color attachment \"+a+\" is invalid\"),F[a]&&F[a].texture){var L=At[F[a].texture._texture.format]*_t[F[a].texture._texture.type];null===P?P=L:_(P===L,\"all color attachments much have the same number of bits per pixel.\")}return m(B,o,d),_(!B||B.texture&&6402===B.texture._texture.format||B.renderbuffer&&33189===B.renderbuffer._renderbuffer.format,\"invalid depth attachment for framebuffer object\"),m(V,o,d),_(!V||V.renderbuffer&&36168===V.renderbuffer._renderbuffer.format,\"invalid stencil attachment for framebuffer object\"),m(I,o,d),_(!I||I.texture&&34041===I.texture._texture.format||I.renderbuffer&&34041===I.renderbuffer._renderbuffer.format,\"invalid depth-stencil attachment for framebuffer object\"),A(i),i.width=o,i.height=d,i.colorAttachments=F,i.depthAttachment=B,i.stencilAttachment=V,i.depthStencilAttachment=I,l.color=F.map(v),l.depth=v(B),l.stencil=v(V),l.depthStencil=v(I),l.width=i.width,l.height=i.height,S(i),l}return o.framebufferCount++,l(e,a),t(l,{resize:function(e,t){_(f.next!==i,\"can not resize a framebuffer which is currently in use\");var r=Math.max(0|e,1),n=Math.max(0|t||r,1);if(r===i.width&&n===i.height)return l;for(var a=i.colorAttachments,o=0;o=2,\"invalid shape for framebuffer\"),_(g[0]===g[1],\"cube framebuffer must be square\"),d=g[0]}else\"radius\"in v&&(d=0|v.radius),\"width\"in v?(d=0|v.width,\"height\"in v&&_(v.height===d,\"must be square\")):\"height\"in v&&(d=0|v.height);(\"color\"in v||\"colors\"in v)&&(m=v.color||v.colors,Array.isArray(m)&&_(1===m.length||r.webgl_draw_buffers,\"multiple render targets not supported\")),m||(\"colorCount\"in v&&(b=0|v.colorCount,_(b>0,\"invalid color buffer count\")),\"colorType\"in v&&(_.oneOf(v.colorType,c,\"invalid color type\"),h=v.colorType),\"colorFormat\"in v&&(p=v.colorFormat,_.oneOf(v.colorFormat,u,\"invalid color format for texture\"))),\"depth\"in v&&(l.depth=v.depth),\"stencil\"in v&&(l.stencil=v.stencil),\"depthStencil\"in v&&(l.depthStencil=v.depthStencil)}else d=1;if(m)if(Array.isArray(m))for(s=[],n=0;n0&&(l.depth=i[0].depth,l.stencil=i[0].stencil,l.depthStencil=i[0].depthStencil),i[n]?i[n](l):i[n]=O(l)}return t(o,{width:d,height:d,color:s})}return o(e),t(o,{faces:i,resize:function(e){var t,r=0|e;if(_(r>0&&r<=n.maxCubeMapSize,\"invalid radius for cube fbo\"),r===o.width)return o;var a=o.color;for(t=0;t=0;--e){var t=I[e];t&&t(v,null,0)}a.flush(),m&&m.update()}function ce(){!Q&&I.length>0&&(Q=j.next(Y))}function le(){Q&&(j.cancel(Y),Q=null)}function de(e){e.preventDefault(),o=!0,le(),P.forEach((function(e){e()}))}function me(e){a.getError(),o=!1,f.restore(),k.restore(),x.restore(),S.restore(),O.restore(),E.restore(),A.restore(),m&&m.restore(),T.procs.refresh(),ce(),N.forEach((function(e){e()}))}function pe(e){function r(e,t){var r={},n={};return Object.keys(e).forEach((function(a){var i=e[a];if(D.isDynamic(i))n[a]=D.unbox(i,a);else{if(t&&Array.isArray(i))for(var o=0;o0)return l.call(this,function(e){for(;m.length=0,\"cannot cancel a frame twice\"),I[t]=function e(){var t=dn(I,e);I[t]=I[I.length-1],I.length-=1,I.length<=0&&le()}}}}function ge(){var e=F.viewport,t=F.scissor_box;e[0]=e[1]=t[0]=t[1]=0,v.viewportWidth=v.framebufferWidth=v.drawingBufferWidth=e[2]=t[2]=a.drawingBufferWidth,v.viewportHeight=v.framebufferHeight=v.drawingBufferHeight=e[3]=t[3]=a.drawingBufferHeight}function ye(){v.tick+=1,v.time=we(),ge(),T.procs.poll()}function xe(){S.refresh(),ge(),T.procs.refresh(),m&&m.update()}function we(){return(C()-p)/1e3}xe();var Ae=t(pe,{clear:function(e){if(_(\"object\"==typeof e&&e,\"regl.clear() takes an object as input\"),\"framebuffer\"in e)if(e.framebuffer&&\"framebufferCube\"===e.framebuffer_reglType)for(var r=0;r<6;++r)he(t({framebuffer:e.framebuffer.faces[r]},e),be);else he(e,be);else be(0,e)},prop:D.define.bind(null,1),context:D.define.bind(null,2),this:D.define.bind(null,3),draw:pe({}),buffer:function(e){return x.create(e,34962,!1,!1)},elements:function(e){return w.create(e,!1)},texture:S.create2D,cube:S.createCube,renderbuffer:O.create,framebuffer:E.create,framebufferCube:E.createCube,vao:A.createVAO,attributes:i,frame:ve,on:function(e,t){var r;switch(_.type(t,\"function\",\"listener callback must be a function\"),e){case\"frame\":return ve(t);case\"lost\":r=P;break;case\"restore\":r=N;break;case\"destroy\":r=q;break;default:_.raise(\"invalid event, must be one of frame,lost,restore,destroy\")}return r.push(t),{cancel:function(){for(var e=0;e=0},read:z,destroy:function(){I.length=0,le(),V&&(V.removeEventListener(cn,de),V.removeEventListener(ln,me)),k.clear(),E.clear(),O.clear(),A.clear(),S.clear(),w.clear(),x.clear(),m&&m.clear(),q.forEach((function(e){e()}))},_gl:a,_refresh:xe,poll:function(){ye(),m&&m.update()},now:we,stats:l});return n.onDone(null,Ae),Ae}},\"object\"==typeof r&&void 0!==t?t.exports=o():\"function\"==typeof define&&define.amd?define(o):i.createREGL=o()},\n", - " 413: function _(t,e,a,s,r){s();const n=t(414),_=t(9),o=t(12);class c{constructor(t){this._regl=t,this._map=new Map}_create_texture(t){const e=t.length;let a=0;const s=[];let r=0,_=0;for(let n=0;nc[f+1]&&f++;const s=t[f],n=c[f]+.5*s;let o=.5*s-Math.abs(a-n);f%2==1&&(o=-o),m[e]=Math.round(255*(o-r)/(_-r))}return[[a,u,r,_],this._regl.texture({shape:[l,1,1],data:m,wrapS:\"repeat\",format:\"alpha\",type:\"uint8\",mag:\"linear\",min:\"linear\"})]}_get_key(t){return t.join(\",\")}_get_or_create(t){const e=this._get_key(t);let a=this._map.get(e);if(null==a){const s=(0,n.gcd)(t);if(s>1){t=(0,o.map)(t,(t=>t/s)),a=this._get_or_create(t);const[r,n,_]=a;a=[r,n,s],this._map.set(e,a)}else{const[r,n]=this._create_texture(t);a=[r,n,s],this._map.set(e,a)}}return a}get(t){return t.length%2==1&&(t=(0,_.concat)([t,t])),this._get_or_create(t)}}a.DashCache=c,c.__name__=\"DashCache\"},\n", - " 414: function _(n,t,e,r,o){function u(n,t){let e,r;n>t?(e=n,r=t):(e=t,r=n);let o=e%r;for(;0!=o;)e=r,r=o,o=e%r;return r}r(),e.gcd=function(n){let t=n[0];for(let e=1;e= 0.0 ? 1.0 : -1.0;\\n}\\n\\nvoid main()\\n{\\n if (a_show_curr < 0.5) {\\n // Line segment has non-finite value at one or both ends, do not render.\\n gl_Position = vec4(-2.0, -2.0, 0.0, 1.0);\\n return;\\n }\\n\\n const float min_miter_factor_round_join_mesh = sqrt(2.0);\\n\\n int join_type = int(u_line_join + 0.5);\\n int cap_type = int(u_line_cap + 0.5);\\n float halfwidth = 0.5*(u_linewidth + u_antialias);\\n vec2 segment_along = normalize(a_point_end - a_point_start); // unit vector.\\n v_segment_length = length(a_point_end - a_point_start);\\n vec2 segment_right = right_vector(segment_along); // unit vector.\\n vec2 xy;\\n\\n bool miter_too_large_start = false;\\n bool miter_too_large_end = false;\\n\\n v_coords.y = a_position.y*halfwidth; // Overwritten later for end points.\\n\\n bool has_start_cap = a_show_prev < 0.5;\\n bool has_end_cap = a_show_next < 0.5;\\n\\n vec2 point_normal_start;\\n float cos_theta_start;\\n float turn_right_start;\\n if (has_start_cap)\\n point_normal_start = segment_right;\\n else {\\n vec2 prev_right = right_vector(normalize(a_point_start - a_point_prev));\\n point_normal_start = normalize(segment_right + prev_right);\\n cos_theta_start = dot(segment_right, point_normal_start); // Always +ve\\n turn_right_start = sign_no_zero(dot(segment_right, a_point_prev - a_point_start));\\n }\\n\\n vec2 point_normal_end;\\n float cos_theta_end;\\n float turn_right_end;\\n if (has_end_cap)\\n point_normal_end = segment_right;\\n else {\\n vec2 next_right = right_vector(normalize(a_point_next - a_point_end));\\n point_normal_end = normalize(segment_right + next_right);\\n cos_theta_end = dot(segment_right, point_normal_end); // Always +ve\\n turn_right_end = sign_no_zero(dot(segment_right, a_point_next - a_point_end));\\n }\\n\\n float miter_factor_start = 1.0 / dot(segment_right, point_normal_start);\\n float miter_factor_end = 1.0 / dot(segment_right, point_normal_end);\\n if (join_type == miter_join) {\\n // If miter too large, use bevel join instead.\\n miter_too_large_start = (miter_factor_start > u_miter_limit);\\n miter_too_large_end = (miter_factor_end > u_miter_limit);\\n }\\n\\n float sign_at_start = -sign(a_position.x); // +ve at segment start, -ve end.\\n vec2 point = sign_at_start > 0.0 ? a_point_start : a_point_end;\\n vec2 adjacent_point =\\n sign_at_start > 0.0 ? (has_start_cap ? a_point_start : a_point_prev)\\n : (has_end_cap ? a_point_end : a_point_next);\\n\\n if ( (has_start_cap && sign_at_start > 0.0) ||\\n (has_end_cap && sign_at_start < 0.0) ) {\\n // Cap.\\n xy = point - segment_right*(halfwidth*a_position.y);\\n if (cap_type == butt_cap)\\n xy -= sign_at_start*0.5*u_antialias*segment_along;\\n else\\n xy -= sign_at_start*halfwidth*segment_along;\\n }\\n else { // Join.\\n // +ve if turning to right, -ve if to left.\\n float turn_sign = sign_at_start > 0.0 ? turn_right_start : turn_right_end;\\n\\n vec2 adjacent_right = sign_at_start*normalize(right_vector(point - adjacent_point));\\n vec2 point_right = normalize(segment_right + adjacent_right);\\n float miter_factor = sign_at_start > 0.0 ? miter_factor_start : miter_factor_end;\\n bool miter_too_large = sign_at_start > 0.0 ? miter_too_large_start : miter_too_large_end;\\n\\n if (abs(a_position.x) > 1.5) {\\n // Outer point, meets prev/next segment.\\n float factor; // multiplied by halfwidth...\\n\\n if (join_type == bevel_join || (join_type == miter_join && miter_too_large))\\n factor = 1.0 / miter_factor; // cos_theta.\\n else if (join_type == round_join &&\\n miter_factor > min_miter_factor_round_join_mesh)\\n factor = 1.0;\\n else // miter, or round (small angle only).\\n factor = miter_factor;\\n\\n xy = point - point_right*(halfwidth*turn_sign*factor);\\n v_coords.y = turn_sign*halfwidth*factor / miter_factor;\\n }\\n else if (turn_sign*a_position.y < 0.0) {\\n // Inner point, meets prev/next segment.\\n float len = halfwidth*miter_factor;\\n float segment_len = v_segment_length;\\n float adjacent_len = distance(point, adjacent_point);\\n\\n if (len <= min(segment_len, adjacent_len))\\n // Normal behaviour.\\n xy = point - point_right*(len*a_position.y);\\n else\\n // For short wide line segments the inner point using the above\\n // calculation can be outside of the line. Here clipping it.\\n xy = point + segment_right*(halfwidth*turn_sign);\\n }\\n else {\\n // Point along outside edge.\\n xy = point - segment_right*(halfwidth*a_position.y);\\n if (join_type == round_join &&\\n miter_factor > min_miter_factor_round_join_mesh) {\\n xy = line_intersection(xy, segment_along,\\n point - turn_sign*point_right*halfwidth,\\n right_vector(point_right));\\n }\\n }\\n }\\n\\n vec2 pos = xy + 0.5; // Bokeh's offset.\\n pos /= u_canvas_size / u_pixel_ratio; // in 0..1\\n gl_Position = vec4(2.0*pos.x - 1.0, 1.0 - 2.0*pos.y, 0.0, 1.0);\\n\\n v_coords.x = dot(xy - a_point_start, segment_along);\\n v_flags = float(int(has_start_cap) +\\n 2*int(has_end_cap) +\\n 4*int(miter_too_large_start) +\\n 8*int(miter_too_large_end));\\n v_cos_theta_turn_right_start = cos_theta_start*turn_right_start;\\n v_cos_theta_turn_right_end = cos_theta_end*turn_right_end;\\n\\n#ifdef DASHED\\n v_length_so_far = a_length_so_far;\\n#endif\\n}\\n\"},\n", - " 416: function _(n,t,a,i,e){i();a.default=\"\\nprecision mediump float;\\n\\nconst int butt_cap = 0;\\nconst int round_cap = 1;\\nconst int square_cap = 2;\\n\\nconst int miter_join = 0;\\nconst int round_join = 1;\\nconst int bevel_join = 2;\\n\\nuniform float u_linewidth;\\nuniform float u_antialias;\\nuniform float u_line_join;\\nuniform float u_line_cap;\\nuniform vec4 u_line_color;\\n#ifdef DASHED\\nuniform sampler2D u_dash_tex;\\nuniform vec4 u_dash_tex_info;\\nuniform float u_dash_scale;\\nuniform float u_dash_offset;\\n#endif\\n\\nvarying float v_segment_length;\\nvarying vec2 v_coords;\\nvarying float v_flags;\\nvarying float v_cos_theta_turn_right_start;\\nvarying float v_cos_theta_turn_right_end;\\n#ifdef DASHED\\nvarying float v_length_so_far;\\n#endif\\n\\nfloat cross_z(in vec2 v0, in vec2 v1)\\n{\\n return v0.x*v1.y - v0.y*v1.x;\\n}\\n\\nfloat point_line_side(in vec2 point, in vec2 start, in vec2 end)\\n{\\n // +ve if point to right of line.\\n // Alternatively could do dot product with right_vector.\\n return cross_z(point - start, end - start);\\n}\\n\\nfloat point_line_distance(in vec2 point, in vec2 start, in vec2 end)\\n{\\n return point_line_side(point, start, end) / distance(start, end);\\n}\\n\\nvec2 right_vector(in vec2 v)\\n{\\n return vec2(v.y, -v.x);\\n}\\n\\nfloat bevel_join_distance(in float sign_start, in float halfwidth)\\n{\\n float cos_theta_turn_right = sign_start > 0.0 ? v_cos_theta_turn_right_start\\n : v_cos_theta_turn_right_end;\\n float cos_theta = abs(cos_theta_turn_right);\\n float turn_right = sign(cos_theta_turn_right);\\n float distance_along = sign_start > 0.0 ? 0.0 : v_segment_length;\\n\\n // In v_coords reference frame (x is along segment, y across).\\n vec2 line_start = vec2(distance_along, halfwidth*turn_right);\\n float sin_alpha = cos_theta;\\n float cos_alpha = sqrt(1.0 - sin_alpha*sin_alpha);\\n vec2 line_along = vec2(-sign_start*turn_right*sin_alpha, -cos_alpha);\\n\\n return halfwidth + sign_start*point_line_distance(\\n v_coords, line_start, line_start+line_along);\\n}\\n\\nfloat cap(in int cap_type, in float x, in float y)\\n{\\n // x is distance along segment in direction away from end of segment,\\n // y is distance across segment.\\n if (cap_type == butt_cap)\\n return max(0.5*u_linewidth - x, abs(y));\\n else if (cap_type == square_cap)\\n return max(-x, abs(y));\\n else // cap_type == round_cap\\n return distance(vec2(min(x, 0.0), y), vec2(0.0, 0.0));\\n}\\n\\nfloat distance_to_alpha(in float dist)\\n{\\n return 1.0 - smoothstep(0.5*(u_linewidth - u_antialias),\\n 0.5*(u_linewidth + u_antialias), dist);\\n}\\n\\n#ifdef DASHED\\nfloat dash_distance(in float x)\\n{\\n // x is in direction of v_coords.x, i.e. along segment.\\n float tex_length = u_dash_tex_info.x;\\n float tex_offset = u_dash_tex_info.y;\\n float tex_dist_min = u_dash_tex_info.z;\\n float tex_dist_max = u_dash_tex_info.w;\\n\\n // Apply offset.\\n x += v_length_so_far - u_dash_scale*tex_offset + u_dash_offset;\\n\\n // Interpolate within texture to obtain distance to dash.\\n float dist = texture2D(u_dash_tex,\\n vec2(x / (tex_length*u_dash_scale), 0.0)).a;\\n\\n // Scale distance within min and max limits.\\n dist = tex_dist_min + dist*(tex_dist_max - tex_dist_min);\\n\\n return u_dash_scale*dist;\\n}\\n\\nfloat clip_dash_distance(in float x, in float offset, in float sign_along)\\n{\\n // Return clipped dash distance, sign_along is +1.0 if looking forward\\n // into next segment and -1.0 if looking backward into previous segment.\\n float half_antialias = 0.5*u_antialias;\\n\\n if (sign_along*x > half_antialias) {\\n // Outside antialias region, use usual dash distance.\\n return dash_distance(offset + x);\\n }\\n else {\\n // Inside antialias region.\\n // Dash distance at edge of antialias region clipped to half_antialias.\\n float edge_dist = min(dash_distance(offset + sign_along*half_antialias), half_antialias);\\n\\n // Physical distance from dash distance at edge of antialias region.\\n return edge_dist + sign_along*x - half_antialias;\\n }\\n}\\n\\nmat2 rotation_matrix(in float sign_start)\\n{\\n // Rotation matrix for v_coords from this segment to prev or next segment.\\n float cos_theta_turn_right = sign_start > 0.0 ? v_cos_theta_turn_right_start\\n : v_cos_theta_turn_right_end;\\n float cos_theta = abs(cos_theta_turn_right);\\n float turn_right = sign(cos_theta_turn_right);\\n\\n float sin_theta = sqrt(1.0 - cos_theta*cos_theta)*sign_start*turn_right;\\n float cos_2theta = 2.0*cos_theta*cos_theta - 1.0;\\n float sin_2theta = 2.0*sin_theta*cos_theta;\\n return mat2(cos_2theta, -sin_2theta, sin_2theta, cos_2theta);\\n}\\n#endif\\n\\nvoid main()\\n{\\n int join_type = int(u_line_join + 0.5);\\n int cap_type = int(u_line_cap + 0.5);\\n float halfwidth = 0.5*(u_linewidth + u_antialias);\\n float half_antialias = 0.5*u_antialias;\\n\\n // Extract flags.\\n int flags = int(v_flags + 0.5);\\n bool miter_too_large_end = (flags / 8 > 0);\\n flags -= 8*int(miter_too_large_end);\\n bool miter_too_large_start = (flags / 4 > 0);\\n flags -= 4*int(miter_too_large_start);\\n bool has_end_cap = (flags / 2 > 0);\\n flags -= 2*int(has_end_cap);\\n bool has_start_cap = flags > 0;\\n\\n float dist = v_coords.y; // For straight segment, and miter join.\\n\\n // Along-segment coords with respect to end of segment, +ve inside segment\\n // so equivalent to v_coords.x at start of segment.\\n float end_coords_x = v_segment_length - v_coords.x;\\n\\n if (v_coords.x <= half_antialias) {\\n // At start of segment, either cap or join.\\n if (has_start_cap)\\n dist = cap(cap_type, v_coords.x, v_coords.y);\\n else if (join_type == round_join)\\n dist = distance(v_coords, vec2(0.0, 0.0));\\n else if (join_type == bevel_join ||\\n (join_type == miter_join && miter_too_large_start))\\n dist = max(abs(dist), bevel_join_distance(1.0, halfwidth));\\n // else a miter join which uses the default dist calculation.\\n }\\n else if (end_coords_x <= half_antialias) {\\n // At end of segment, either cap or join.\\n if (has_end_cap)\\n dist = cap(cap_type, end_coords_x, v_coords.y);\\n else if (join_type == round_join)\\n dist = distance(v_coords, vec2(v_segment_length, 0));\\n else if ((join_type == bevel_join ||\\n (join_type == miter_join && miter_too_large_end)))\\n dist = max(abs(dist), bevel_join_distance(-1.0, halfwidth));\\n // else a miter join which uses the default dist calculation.\\n }\\n\\n float alpha = distance_to_alpha(abs(dist));\\n\\n#ifdef DASHED\\n if (u_dash_tex_info.x >= 0.0) {\\n // Dashes in straight segments (outside of joins) are easily calculated.\\n dist = dash_distance(v_coords.x);\\n\\n if (!has_start_cap && cap_type == butt_cap) {\\n if (v_coords.x < half_antialias) {\\n // Outer of start join rendered solid color or not at all\\n // depending on whether corner point is in dash or gap, with\\n // antialiased ends.\\n if (dash_distance(0.0) > 0.0) {\\n // Corner is solid color.\\n dist = max(dist, min(half_antialias, -v_coords.x));\\n // Avoid visible antialiasing band between corner and dash.\\n dist = max(dist, dash_distance(half_antialias));\\n }\\n else {\\n // Use large negative value so corner not colored.\\n dist = -halfwidth;\\n\\n if (v_coords.x > -half_antialias) {\\n // Consider antialias region of dash after start region.\\n float edge_dist = min(dash_distance(half_antialias), half_antialias);\\n dist = max(dist, edge_dist + v_coords.x - half_antialias);\\n }\\n }\\n }\\n\\n vec2 prev_coords = rotation_matrix(1.0)*v_coords;\\n\\n if (abs(prev_coords.y) < halfwidth && prev_coords.x < half_antialias) {\\n // Extend dashes across from end of previous segment, with antialiased end.\\n float new_dist = clip_dash_distance(prev_coords.x, 0.0, -1.0);\\n new_dist = min(new_dist, 0.5*u_linewidth - abs(prev_coords.y));\\n dist = max(dist, new_dist);\\n }\\n }\\n\\n if (!has_end_cap && cap_type == butt_cap) {\\n if (end_coords_x < half_antialias) {\\n // Similar for end join.\\n if (dash_distance(v_segment_length) > 0.0) {\\n // Corner is solid color.\\n dist = max(dist, min(half_antialias, -end_coords_x));\\n // Avoid visible antialiasing band between corner and dash.\\n dist = max(dist, dash_distance(v_segment_length - half_antialias));\\n }\\n else {\\n // Use large negative value so corner not colored.\\n dist = -halfwidth;\\n\\n if (end_coords_x > -half_antialias) {\\n // Consider antialias region of dash before end region.\\n float edge_dist = min(dash_distance(v_segment_length - half_antialias),\\n half_antialias);\\n dist = max(dist, edge_dist + end_coords_x - half_antialias);\\n }\\n }\\n }\\n\\n vec2 next_coords = rotation_matrix(-1.0)*(v_coords - vec2(v_segment_length, 0.0));\\n\\n if (abs(next_coords.y) < halfwidth && next_coords.x > -half_antialias) {\\n // Extend dashes across from next segment, with antialiased end.\\n float new_dist = clip_dash_distance(next_coords.x, v_segment_length, 1.0);\\n new_dist = min(new_dist, 0.5*u_linewidth - abs(next_coords.y));\\n dist = max(dist, new_dist);\\n }\\n }\\n\\n dist = cap(cap_type, dist, v_coords.y);\\n\\n float dash_alpha = distance_to_alpha(dist);\\n alpha = min(alpha, dash_alpha);\\n }\\n#endif\\n\\n alpha = u_line_color.a*alpha;\\n gl_FragColor = vec4(u_line_color.rgb*alpha, alpha); // Premultiplied alpha.\\n}\\n\"},\n", - " 417: function _(n,i,e,t,a){t();e.default=\"\\nprecision mediump float;\\n\\nattribute vec2 a_position;\\nattribute vec2 a_center;\\nattribute float a_width;\\nattribute float a_height;\\nattribute float a_angle; // In radians\\nattribute float a_linewidth;\\nattribute vec4 a_line_color;\\nattribute vec4 a_fill_color;\\nattribute float a_line_cap;\\nattribute float a_line_join;\\nattribute float a_show;\\n#ifdef HATCH\\nattribute float a_hatch_pattern;\\nattribute float a_hatch_scale;\\nattribute float a_hatch_weight;\\nattribute vec4 a_hatch_color;\\n#endif\\n\\nuniform float u_pixel_ratio;\\nuniform vec2 u_canvas_size;\\nuniform float u_antialias;\\nuniform float u_size_hint;\\n\\nvarying float v_linewidth;\\nvarying vec2 v_size; // 2D size for rects compared to 1D for markers.\\nvarying vec4 v_line_color;\\nvarying vec4 v_fill_color;\\nvarying float v_line_cap;\\nvarying float v_line_join;\\nvarying vec2 v_coords;\\n#ifdef HATCH\\nvarying float v_hatch_pattern;\\nvarying float v_hatch_scale;\\nvarying float v_hatch_weight;\\nvarying vec4 v_hatch_color;\\nvarying vec2 v_hatch_coords;\\n#endif\\n\\nvoid main()\\n{\\n if (a_show < 0.5) {\\n // Do not show this rect.\\n gl_Position = vec4(-2.0, -2.0, 0.0, 1.0);\\n return;\\n }\\n\\n v_size = vec2(a_width, a_height);\\n v_linewidth = a_linewidth;\\n v_line_color = a_line_color;\\n v_fill_color = a_fill_color;\\n v_line_cap = a_line_cap;\\n v_line_join = a_line_join;\\n\\n if (v_linewidth < 1.0) {\\n // Linewidth less than 1 is implemented as 1 but with reduced alpha.\\n v_line_color.a *= v_linewidth;\\n v_linewidth = 1.0;\\n }\\n\\n#ifdef HATCH\\n v_hatch_pattern = a_hatch_pattern;\\n v_hatch_scale = a_hatch_scale;\\n v_hatch_weight = a_hatch_weight;\\n v_hatch_color = a_hatch_color;\\n#endif\\n\\n vec2 enclosing_size;\\n // Need extra size of (v_linewidth+u_antialias) if edge of marker parallel to\\n // edge of bounding box. If symmetric spike towards edge then multiply by\\n // 1/cos(theta) where theta is angle between spike and bbox edges.\\n int size_hint = int(u_size_hint + 0.5);\\n if (size_hint == 1) // Dash\\n enclosing_size = vec2(v_size.x + v_linewidth + u_antialias,\\n v_linewidth + u_antialias);\\n else if (size_hint == 2) // Dot\\n enclosing_size = 0.25*v_size + u_antialias;\\n else if (size_hint == 3) // Diamond\\n enclosing_size = vec2(v_size.x*(2.0/3.0) + (v_linewidth + u_antialias)*1.20185,\\n v_size.y + (v_linewidth + u_antialias)*1.80278);\\n else if (size_hint == 4) // Hex\\n enclosing_size = v_size + (v_linewidth + u_antialias)*vec2(2.0/sqrt(3.0), 1.0);\\n else if (size_hint == 5) // Square pin\\n enclosing_size = v_size + (v_linewidth + u_antialias)*3.1;\\n else if (size_hint == 6) // Triangle\\n enclosing_size = vec2(v_size.x + (v_linewidth + u_antialias)*sqrt(3.0),\\n v_size.y*(2.0/sqrt(3.0)) + (v_linewidth + u_antialias)*2.0);\\n else if (size_hint == 7) // Triangle pin\\n enclosing_size = v_size + (v_linewidth + u_antialias)*vec2(4.8, 6.0);\\n else if (size_hint == 8) // Star\\n enclosing_size = vec2(v_size.x*0.95106 + (v_linewidth + u_antialias)*3.0,\\n v_size.y + (v_linewidth + u_antialias)*3.2);\\n else\\n enclosing_size = v_size + v_linewidth + u_antialias;\\n\\n // Coordinates in rotated frame with respect to center of marker, used for\\n // distance functions in fragment shader.\\n v_coords = a_position*enclosing_size;\\n\\n float c = cos(-a_angle);\\n float s = sin(-a_angle);\\n mat2 rotation = mat2(c, -s, s, c);\\n\\n vec2 pos = a_center + rotation*v_coords;\\n#ifdef HATCH\\n // Coordinates for hatching in unrotated frame of reference.\\n v_hatch_coords = pos - 0.5;\\n#endif\\n pos += 0.5; // Make up for Bokeh's offset.\\n pos /= u_canvas_size / u_pixel_ratio; // 0 to 1.\\n gl_Position = vec4(2.0*pos.x - 1.0, 1.0 - 2.0*pos.y, 0.0, 1.0);\\n}\\n\"},\n", - " 418: function _(n,i,e,t,a){t();e.default=\"\\nprecision mediump float;\\n\\nconst float SQRT2 = sqrt(2.0);\\nconst float SQRT3 = sqrt(3.0);\\nconst float PI = 3.14159265358979323846;\\n\\nconst int butt_cap = 0;\\nconst int round_cap = 1;\\nconst int square_cap = 2;\\n\\nconst int miter_join = 0;\\nconst int round_join = 1;\\nconst int bevel_join = 2;\\n\\n#ifdef HATCH\\nconst int hatch_dot = 1;\\nconst int hatch_ring = 2;\\nconst int hatch_horizontal_line = 3;\\nconst int hatch_vertical_line = 4;\\nconst int hatch_cross = 5;\\nconst int hatch_horizontal_dash = 6;\\nconst int hatch_vertical_dash = 7;\\nconst int hatch_spiral = 8;\\nconst int hatch_right_diagonal_line = 9;\\nconst int hatch_left_diagonal_line = 10;\\nconst int hatch_diagonal_cross = 11;\\nconst int hatch_right_diagonal_dash = 12;\\nconst int hatch_left_diagonal_dash = 13;\\nconst int hatch_horizontal_wave = 14;\\nconst int hatch_vertical_wave = 15;\\nconst int hatch_criss_cross = 16;\\n#endif\\n\\nuniform float u_antialias;\\n\\nvarying float v_linewidth;\\nvarying vec2 v_size;\\nvarying vec4 v_line_color;\\nvarying vec4 v_fill_color;\\nvarying float v_line_cap;\\nvarying float v_line_join;\\nvarying vec2 v_coords;\\n#ifdef HATCH\\nvarying float v_hatch_pattern;\\nvarying float v_hatch_scale;\\nvarying float v_hatch_weight;\\nvarying vec4 v_hatch_color;\\nvarying vec2 v_hatch_coords;\\n#endif\\n\\n// Lines within the marker (dot, cross, x and y) are added at the end as they are\\n// on top of the fill rather than astride it.\\n#if defined(USE_CIRCLE_DOT) || defined(USE_DIAMOND_DOT) || defined(USE_DOT) || defined(USE_HEX_DOT) || defined(USE_SQUARE_DOT) || defined(USE_STAR_DOT) || defined(USE_TRIANGLE_DOT)\\n #define APPEND_DOT\\n#endif\\n\\n#if defined(USE_CIRCLE_CROSS) || defined(USE_SQUARE_CROSS)\\n #define APPEND_CROSS\\n#endif\\n\\n#ifdef USE_DIAMOND_CROSS\\n #define APPEND_CROSS_2\\n#endif\\n\\n#ifdef USE_CIRCLE_X\\n #define APPEND_X\\n #define APPEND_X_LEN (0.5*v_size.x)\\n#endif\\n\\n#ifdef USE_SQUARE_X\\n #define APPEND_X\\n #define APPEND_X_LEN (v_size.x/SQRT2)\\n#endif\\n\\n#ifdef USE_CIRCLE_Y\\n #define APPEND_Y\\n#endif\\n\\n#if defined(USE_ASTERISK) || defined(USE_CROSS) || defined(USE_DASH) || defined(USE_DOT) || defined(USE_X) || defined(USE_Y)\\n // No fill.\\n #define LINE_ONLY\\n#endif\\n\\n#if defined(LINE_ONLY) || defined(APPEND_CROSS) || defined(APPEND_CROSS_2) || defined(APPEND_X) || defined(APPEND_Y)\\nfloat end_cap_distance(in vec2 p, in vec2 end_point, in vec2 unit_direction, in int line_cap)\\n{\\n vec2 offset = p - end_point;\\n if (line_cap == butt_cap)\\n return dot(offset, unit_direction) + 0.5*v_linewidth;\\n else if (line_cap == square_cap)\\n return dot(offset, unit_direction);\\n else if (line_cap == round_cap && dot(offset, unit_direction) > 0.0)\\n return length(offset);\\n else\\n // Default is outside of line and should be -0.5*(v_linewidth+u_antialias) or less,\\n // so here avoid the multiplication.\\n return -v_linewidth-u_antialias;\\n}\\n#endif\\n\\n#if !(defined(LINE_ONLY) || defined(USE_SQUARE_PIN) || defined(USE_TRIANGLE_PIN))\\n// For line join at a vec2 corner where 2 line segments meet, consider bevel points which are the 2\\n// points obtained by moving half a linewidth away from the corner point in the directions normal to\\n// the line segments. The line through these points is the bevel line, characterised by a vec2\\n// unit_normal and offset distance from the corner point. Edge of bevel join straddles this line,\\n// round join occurs outside of this line centred on the corner point. In general\\n// offset = (linewidth/2)*sin(alpha/2)\\n// where alpha is the angle between the 2 line segments at the corner.\\nfloat line_join_distance_no_miter(\\n in vec2 p, in vec2 corner, in vec2 unit_normal, in float offset, in int line_join)\\n{\\n // Simplified version of line_join_distance ignoring miter which most markers do implicitly\\n // as they are composed of straight line segments.\\n float dist_outside = dot((p - corner), unit_normal) - offset;\\n\\n if (line_join == bevel_join && dist_outside > -0.5*u_antialias)\\n return dist_outside + 0.5*v_linewidth;\\n else if (dist_outside > 0.0) // round_join\\n return distance(p, corner);\\n else\\n // Default is outside of line and should be -0.5*(v_linewidth+u_antialias) or less,\\n // so here avoid the multiplication.\\n return -v_linewidth-u_antialias;\\n}\\n#endif\\n\\n#if defined(USE_SQUARE_PIN) || defined(USE_TRIANGLE_PIN)\\n// Line join distance including miter but only one-sided check as assuming use of symmetry in\\n// calling function.\\nfloat line_join_distance_incl_miter(\\n in vec2 p, in vec2 corner, in vec2 unit_normal, in float offset, in int line_join,\\n vec2 miter_unit_normal)\\n{\\n float dist_outside = dot((p - corner), unit_normal) - offset;\\n\\n if (line_join == miter_join && dist_outside > 0.0)\\n return dot((p - corner), miter_unit_normal);\\n else if (line_join == bevel_join && dist_outside > -0.5*u_antialias)\\n return dist_outside + 0.5*v_linewidth;\\n else if (dist_outside > 0.0) // round_join\\n return distance(p, corner);\\n else\\n return -v_linewidth-u_antialias;\\n}\\n#endif\\n\\n#if defined(APPEND_CROSS) || defined(APPEND_X) || defined(USE_ASTERISK) || defined(USE_CROSS) || defined(USE_X)\\nfloat one_cross(in vec2 p, in int line_cap, in float len)\\n{\\n p = abs(p);\\n p = (p.y > p.x) ? p.yx : p.xy;\\n float dist = p.y;\\n float end_dist = end_cap_distance(p, vec2(len, 0.0), vec2(1.0, 0.0), line_cap);\\n return max(dist, end_dist);\\n}\\n#endif\\n\\n#ifdef APPEND_CROSS_2\\nfloat one_cross_2(in vec2 p, in int line_cap, in vec2 lengths)\\n{\\n // Cross with different length in x and y directions.\\n p = abs(p);\\n bool switch_xy = (p.y > p.x);\\n p = switch_xy ? p.yx : p.xy;\\n float len = switch_xy ? lengths.y : lengths.x;\\n float dist = p.y;\\n float end_dist = end_cap_distance(p, vec2(len, 0.0), vec2(1.0, 0.0), line_cap);\\n return max(dist, end_dist);\\n}\\n#endif\\n\\n#if defined(APPEND_Y) || defined(USE_Y)\\nfloat one_y(in vec2 p, in int line_cap, in float len)\\n{\\n p = vec2(abs(p.x), -p.y);\\n\\n // End point of line to right is (1/2, 1/3)*len*SQRT3.\\n // Unit vector along line is (1/2, 1/3)*k where k = 6/SQRT13.\\n const float k = 6.0/sqrt(13.0);\\n vec2 unit_along = vec2(0.5*k, k/3.0);\\n vec2 end_point = vec2(0.5*len*SQRT3, len*SQRT3/3.0);\\n float dist = max(abs(dot(p, vec2(-unit_along.y, unit_along.x))),\\n end_cap_distance(p, end_point, unit_along, line_cap));\\n\\n if (p.y < 0.0) {\\n // Vertical line.\\n float vert_dist = max(p.x,\\n end_cap_distance(p, vec2(0.0, -len), vec2(0.0, -1.0), line_cap));\\n dist = min(dist, vert_dist);\\n }\\n return dist;\\n}\\n#endif\\n\\n// One marker_distance function per marker type.\\n// Distance is zero on edge of marker, +ve outside and -ve inside.\\n\\n#ifdef USE_ASTERISK\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n vec2 p_diag = vec2((p.x + p.y)/SQRT2, (p.x - p.y)/SQRT2);\\n float len = 0.5*v_size.x;\\n return min(one_cross(p, line_cap, len), // cross\\n one_cross(p_diag, line_cap, len)); // x\\n}\\n#endif\\n\\n#if defined(USE_CIRCLE) || defined(USE_CIRCLE_CROSS) || defined(USE_CIRCLE_DOT) || defined(USE_CIRCLE_X) || defined(USE_CIRCLE_Y)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n return length(p) - 0.5*v_size.x;\\n}\\n#endif\\n\\n#ifdef USE_CROSS\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n return one_cross(p, line_cap, 0.5*v_size.x);\\n}\\n#endif\\n\\n#ifdef USE_DASH\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n p = abs(p);\\n float dist = p.y;\\n float end_dist = end_cap_distance(p, vec2(0.5*v_size.x, 0.0), vec2(1.0, 0.0), line_cap);\\n return max(dist, end_dist);\\n}\\n#endif\\n\\n#if defined(USE_DIAMOND) || defined(USE_DIAMOND_CROSS) || defined(USE_DIAMOND_DOT)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n // Only need to consider +ve quadrant, the 2 end points are (2r/3, 0) and (0, r)\\n // where r = radius = v_size.x/2.\\n // Line has outward-facing unit normal vec2(1, 2/3)/k where k = SQRT13/3\\n // hence vec2(3, 2)/SQRT13, and distance from origin of 2r/(3k) = 2r/SQRT13.\\n p = abs(p);\\n float r = 0.5*v_size.x;\\n const float SQRT13 = sqrt(13.0);\\n float dist = dot(p, vec2(3.0, 2.0))/SQRT13 - 2.0*r/SQRT13;\\n\\n if (line_join != miter_join) {\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(0.0, r), vec2(0.0, 1.0), v_linewidth/SQRT13, line_join));\\n\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(r*2.0/3.0, 0.0), vec2(1.0, 0.0), v_linewidth*(1.5/SQRT13), line_join));\\n }\\n\\n return dist;\\n}\\n#endif\\n\\n#ifdef USE_DOT\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Dot is always appended.\\n return v_linewidth+u_antialias;\\n}\\n#endif\\n\\n#if defined(USE_HEX) || defined(USE_HEX_DOT)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // A regular hexagon has v_size.x == v.size_y = r where r is the length of\\n // each of the 3 sides of the 6 equilateral triangles that comprise the hex.\\n // Only consider +ve quadrant, the 3 corners are at (0, h), (rx/2, h), (rx, 0)\\n // where rx = 0.5*v_size.x, ry = 0.5*v_size.y and h = ry*SQRT3/2.\\n // Sloping line has outward normal vec2(h, rx/2). Length of this is\\n // len = sqrt(h**2 + rx**2/4) to give unit normal (h, rx/2)/len and distance\\n // from origin of this line is rx*h/len.\\n p = abs(p);\\n float rx = v_size.x/2.0;\\n float h = v_size.y*(SQRT3/4.0);\\n float len_normal = sqrt(h*h + 0.25*rx*rx);\\n vec2 unit_normal = vec2(h, 0.5*rx) / len_normal;\\n float dist = max(dot(p, unit_normal) - rx*h/len_normal, // Distance from sloping line.\\n p.y - h); // Distance from horizontal line.\\n\\n if (line_join != miter_join) {\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(rx, 0.0), vec2(1.0, 0.0), 0.5*v_linewidth*unit_normal.x, line_join));\\n\\n unit_normal = normalize(unit_normal + vec2(0.0, 1.0)); // At (rx/2, h) corner.\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(0.5*rx, h), unit_normal, 0.5*v_linewidth*unit_normal.y, line_join));\\n }\\n return dist;\\n}\\n#endif\\n\\n#ifdef USE_PLUS\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n // Only need to consider one octant, the +ve quadrant with x >= y.\\n p = abs(p);\\n p = (p.y > p.x) ? p.yx : p.xy;\\n\\n // 3 corners are (r, 0), (r, 3r/8) and (3r/8, 3r/8).\\n float r = 0.5*v_size.x;\\n p = p - vec2(r, 0.375*r); // Distance with respect to outside corner\\n float dist = max(p.x, p.y);\\n\\n if (line_join != miter_join) {\\n // Outside corner\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(0.0, 0.0), vec2(1.0/SQRT2, 1.0/SQRT2), v_linewidth/(2.0*SQRT2), line_join));\\n\\n // Inside corner\\n dist = min(dist, -line_join_distance_no_miter(\\n p, vec2(-5.0*r/8.0, 0.0), vec2(-1.0/SQRT2, -1.0/SQRT2), v_linewidth/(2.0*SQRT2), line_join));\\n }\\n\\n return dist;\\n}\\n#endif\\n\\n#if defined(USE_SQUARE) || defined(USE_SQUARE_CROSS) || defined(USE_SQUARE_DOT) || defined(USE_SQUARE_X)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n vec2 p2 = abs(p) - v_size/2.0; // Offset from corner\\n float dist = max(p2.x, p2.y);\\n\\n if (line_join != miter_join)\\n dist = max(dist, line_join_distance_no_miter(\\n p2, vec2(0.0, 0.0), vec2(1.0/SQRT2, 1.0/SQRT2), v_linewidth/(2.0*SQRT2), line_join));\\n\\n return dist;\\n}\\n#endif\\n\\n#ifdef USE_SQUARE_PIN\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n p = abs(p);\\n p = (p.y > p.x) ? p.yx : p.xy;\\n // p is in octant between y=0 and y=x.\\n // Quadratic bezier curve passes through (r, r), (11r/16, 0) and (r, -r).\\n // Circular arc that passes through the same points has center at\\n // x = r + 231r/160 = 2.44275r and y = 0 and hence radius is\\n // x - 11r/16 = 1.75626 precisely.\\n float r = 0.5*v_size.x;\\n float center_x = r*2.44375;\\n float radius = r*1.75626;\\n float dist = radius - distance(p, vec2(center_x, 0.0));\\n\\n // Magic number is 0.5*sin(atan(8/5) - pi/4)\\n dist = max(dist, line_join_distance_incl_miter(\\n p, vec2(r, r), vec2(1.0/SQRT2, 1.0/SQRT2), v_linewidth*0.1124297533493792, line_join,\\n vec2(8.0/sqrt(89.0), -5.0/sqrt(89.0))));\\n\\n return dist;\\n}\\n#endif\\n\\n#if defined(USE_STAR) || defined(USE_STAR_DOT)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n const float SQRT5 = sqrt(5.0);\\n const float COS72 = 0.25*(SQRT5 - 1.0);\\n const float SIN72 = sqrt((5.0+SQRT5) / 8.0);\\n\\n float angle = atan(p.x, p.y); // In range -pi to +pi clockwise from +y direction.\\n angle = mod(angle, 0.4*PI) - 0.2*PI; // In range -pi/5 to +pi/5 clockwise from +y direction.\\n p = length(p)*vec2(cos(angle), abs(sin(angle))); // (x,y) in pi/10 (36 degree) sector.\\n\\n // 2 corners are at (r, 0) and (r-a*SIN72, a*COS72) where a = r sqrt(5-2*sqrt(5)).\\n // Line has outward-facing unit normal vec2(COS72, SIN72) and distance from\\n // origin of dot(vec2(r, 0), vec2(COS72, SIN72)) = r*COS72\\n float r = 0.5*v_size.x;\\n float a = r*sqrt(5.0 - 2.0*SQRT5);\\n float dist = dot(p, vec2(COS72, SIN72)) - r*COS72;\\n\\n if (line_join != miter_join) {\\n // Outside corner\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(r, 0.0), vec2(1.0, 0.0), v_linewidth*(0.5*COS72), line_join));\\n\\n // Inside corner\\n const float COS36 = sqrt(0.5 + COS72/2.0);\\n const float SIN36 = sqrt(0.5 - COS72/2.0);\\n dist = min(dist, -line_join_distance_no_miter(\\n p, vec2(r-a*SIN72, a*COS72), vec2(-COS36, -SIN36), v_linewidth*(0.5*COS36), line_join));\\n }\\n\\n return dist;\\n}\\n#endif\\n\\n#if defined(USE_TRIANGLE) || defined(USE_TRIANGLE_DOT) || defined(USE_INVERTED_TRIANGLE)\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n // For normal triangle 3 corners are at (-r, a), (r, a), (0, a-h)=(0, -2h/3)\\n // given r = radius = v_size.x/2, h = SQRT3*r, a = h/3.\\n // Sloping line has outward-facing unit normal vec2(h, -r)/2r = vec2(SQRT3, -1)/2\\n // and distance from origin of a. Horizontal line has outward-facing unit normal\\n // vec2(0, 1) and distance from origin of a.\\n float r = 0.5*v_size.x;\\n float a = r*SQRT3/3.0;\\n\\n // Only need to consider +ve x.\\n#ifdef USE_INVERTED_TRIANGLE\\n p = vec2(abs(p.x), -p.y);\\n#else\\n p = vec2(abs(p.x), p.y);\\n#endif\\n\\n float dist = max(0.5*dot(p, vec2(SQRT3, -1.0)) - a, // Distance from sloping line.\\n p.y - a); // Distance from horizontal line.\\n\\n if (line_join != miter_join) {\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(0.0, -(2.0/SQRT3)*r), vec2(0.0, -1.0), v_linewidth*0.25, line_join));\\n\\n dist = max(dist, line_join_distance_no_miter(\\n p, vec2(r, a), vec2(SQRT3/2.0, 0.5), v_linewidth*0.25, line_join));\\n }\\n\\n return dist;\\n}\\n#endif\\n\\n#ifdef USE_TRIANGLE_PIN\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n float angle = atan(p.x, -p.y); // In range -pi to +pi.\\n angle = mod(angle, PI*2.0/3.0) - PI/3.0; // In range -pi/3 to pi/3.\\n p = length(p)*vec2(cos(angle), abs(sin(angle))); // (x,y) in range 0 to pi/3.\\n // Quadratic bezier curve passes through (a, r), ((a+b)/2, 0) and (a, -r) where\\n // a = r/SQRT3, b = 3a/8 = r SQRT3/8. Circular arc that passes through the same points has\\n // center at (a+x, 0) and radius x+c where c = (a-b)/2 and x = (r**2 - c**2) / (2c).\\n // Ignore r factor until the end so can use const.\\n const float a = 1.0/SQRT3;\\n const float b = SQRT3/8.0;\\n const float c = (a-b)/2.0;\\n const float x = (1.0 - c*c) / (2.0*c);\\n const float center_x = x + a;\\n const float radius = x + c;\\n float r = 0.5*v_size.x;\\n float dist = r*radius - distance(p, vec2(r*center_x, 0.0));\\n\\n // Magic number is 0.5*sin(atan(8*sqrt(3)/5) - pi/3)\\n dist = max(dist, line_join_distance_incl_miter(\\n p, vec2(a*r, r), vec2(0.5, 0.5*SQRT3), v_linewidth*0.0881844526878324, line_join,\\n vec2(8.0*SQRT3, -5.0)/sqrt(217.0)));\\n\\n return dist;\\n}\\n#endif\\n\\n#ifdef USE_X\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n p = vec2((p.x + p.y)/SQRT2, (p.x - p.y)/SQRT2);\\n return one_cross(p, line_cap, 0.5*v_size.x);\\n}\\n#endif\\n\\n#ifdef USE_Y\\nfloat marker_distance(in vec2 p, in int line_cap, in int line_join)\\n{\\n // Assuming v_size.x == v.size_y\\n return one_y(p, line_cap, 0.5*v_size.x);\\n}\\n#endif\\n\\n// Convert distance from edge of marker to fraction in range 0 to 1, depending\\n// on antialiasing width.\\nfloat distance_to_fraction(in float dist)\\n{\\n return 1.0 - smoothstep(-0.5*u_antialias, 0.5*u_antialias, dist);\\n}\\n\\n// Return fraction from 0 (no fill color) to 1 (full fill color).\\nfloat fill_fraction(in float dist)\\n{\\n return distance_to_fraction(dist);\\n}\\n\\n// Return fraction in range 0 (no line color) to 1 (full line color).\\nfloat line_fraction(in float dist)\\n{\\n return distance_to_fraction(abs(dist) - 0.5*v_linewidth);\\n}\\n\\n// Return fraction (in range 0 to 1) of a color, with premultiplied alpha.\\nvec4 fractional_color(in vec4 color, in float fraction)\\n{\\n color.a *= fraction;\\n color.rgb *= color.a;\\n return color;\\n}\\n\\n// Blend colors that have premultiplied alpha.\\nvec4 blend_colors(in vec4 src, in vec4 dest)\\n{\\n return (1.0 - src.a)*dest + src;\\n}\\n\\n#ifdef APPEND_DOT\\nfloat dot_fraction(in vec2 p)\\n{\\n // Assuming v_size.x == v_size.y\\n float radius = 0.125*v_size.x;\\n float dot_distance = max(length(p) - radius, -0.5*u_antialias);\\n return fill_fraction(dot_distance);\\n}\\n#endif\\n\\n#ifdef HATCH\\n// Wrap coordinate(s) by removing integer part to give distance from center of\\n// repeat, in the range -0.5 to +0.5.\\nfloat wrap(in float x)\\n{\\n return fract(x) - 0.5;\\n}\\n\\nvec2 wrap(in vec2 xy)\\n{\\n return fract(xy) - 0.5;\\n}\\n\\n// Return fraction from 0 (no hatch color) to 1 (full hatch color).\\nfloat hatch_fraction(in vec2 coords, in int hatch_pattern)\\n{\\n float scale = v_hatch_scale; // Hatch repeat distance.\\n\\n // Coordinates and linewidth/halfwidth are scaled to hatch repeat distance.\\n coords = coords / scale;\\n float halfwidth = 0.5*v_hatch_weight / scale; // Half the hatch linewidth.\\n\\n // Default is to return fraction of zero, i.e. no pattern.\\n float dist = u_antialias;\\n\\n if (hatch_pattern == hatch_dot) {\\n const float dot_radius = 0.25;\\n dist = length(wrap(coords)) - dot_radius;\\n }\\n else if (hatch_pattern == hatch_ring) {\\n const float ring_radius = 0.25;\\n dist = abs(length(wrap(coords)) - ring_radius) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_horizontal_line) {\\n dist = abs(wrap(coords.y)) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_vertical_line) {\\n dist = abs(wrap(coords.x)) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_cross) {\\n dist = min(abs(wrap(coords.x)), abs(wrap(coords.y))) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_horizontal_dash) {\\n // Dashes have square caps.\\n const float halflength = 0.25;\\n dist = max(abs(wrap(coords.y)),\\n abs(wrap(coords.x) + 0.25) - halflength) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_vertical_dash) {\\n const float halflength = 0.25;\\n dist = max(abs(wrap(coords.x)),\\n abs(wrap(coords.y) + 0.25) - halflength) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_spiral) {\\n vec2 wrap2 = wrap(coords);\\n float angle = wrap(atan(wrap2.y, wrap2.x) / (2.0*PI));\\n // Canvas spiral radius increases by scale*pi/15 each rotation.\\n const float dr = PI/15.0;\\n float radius = length(wrap2);\\n // At any angle, spiral lines are equally spaced dr apart.\\n // Find distance to nearest of these lines.\\n float frac = fract((radius - dr*angle) / dr); // 0 to 1.\\n dist = dr*(abs(frac - 0.5));\\n dist = min(dist, radius) - halfwidth; // Consider center point also.\\n }\\n else if (hatch_pattern == hatch_right_diagonal_line) {\\n dist = abs(wrap(2.0*coords.x + coords.y))/sqrt(5.0) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_left_diagonal_line) {\\n dist = abs(wrap(2.0*coords.x - coords.y))/sqrt(5.0) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_diagonal_cross) {\\n coords = vec2(coords.x + coords.y + 0.5, coords.x - coords.y + 0.5);\\n dist = min(abs(wrap(coords.x)), abs(wrap(coords.y))) / SQRT2 - halfwidth;\\n }\\n else if (hatch_pattern == hatch_right_diagonal_dash) {\\n float across = coords.x + coords.y + 0.5;\\n dist = abs(wrap(across)) / SQRT2; // Distance to nearest solid line.\\n\\n across = floor(across); // Offset for dash.\\n float along = wrap(0.5*(coords.x - coords.y + across));\\n const float halflength = 0.25;\\n along = abs(along) - halflength; // Distance along line.\\n\\n dist = max(dist, along) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_left_diagonal_dash) {\\n float across = coords.x - coords.y + 0.5;\\n dist = abs(wrap(across)) / SQRT2; // Distance to nearest solid line.\\n\\n across = floor(across); // Offset for dash.\\n float along = wrap(0.5*(coords.x + coords.y + across));\\n const float halflength = 0.25;\\n along = abs(along) - halflength; // Distance along line.\\n\\n dist = max(dist, along) - halfwidth;\\n }\\n else if (hatch_pattern == hatch_horizontal_wave) {\\n float wrapx = wrap(coords.x);\\n float wrapy = wrap(coords.y - 0.25 + abs(wrapx));\\n dist = abs(wrapy) / SQRT2 - halfwidth;\\n }\\n else if (hatch_pattern == hatch_vertical_wave) {\\n float wrapy = wrap(coords.y);\\n float wrapx = wrap(coords.x - 0.25 + abs(wrapy));\\n dist = abs(wrapx) / SQRT2 - halfwidth;\\n }\\n else if (hatch_pattern == hatch_criss_cross) {\\n float plus = min(abs(wrap(coords.x)), abs(wrap(coords.y)));\\n\\n coords = vec2(coords.x + coords.y + 0.5, coords.x - coords.y + 0.5);\\n float X = min(abs(wrap(coords.x)), abs(wrap(coords.y))) / SQRT2;\\n\\n dist = min(plus, X) - halfwidth;\\n }\\n\\n return distance_to_fraction(dist*scale);\\n}\\n#endif\\n\\nvoid main()\\n{\\n int line_cap = int(v_line_cap + 0.5);\\n int line_join = int(v_line_join + 0.5);\\n#ifdef HATCH\\n int hatch_pattern = int(v_hatch_pattern + 0.5);\\n#endif\\n\\n float dist = marker_distance(v_coords, line_cap, line_join);\\n\\n#ifdef LINE_ONLY\\n vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\\n#else\\n float fill_frac = fill_fraction(dist);\\n vec4 color = fractional_color(v_fill_color, fill_frac);\\n#endif\\n\\n#if defined(HATCH) && !defined(LINE_ONLY)\\n if (hatch_pattern > 0 && fill_frac > 0.0) {\\n float hatch_frac = hatch_fraction(v_hatch_coords, hatch_pattern);\\n vec4 hatch_color = fractional_color(v_hatch_color, hatch_frac*fill_frac);\\n color = blend_colors(hatch_color, color);\\n }\\n#endif\\n\\n float line_frac = line_fraction(dist);\\n\\n#ifdef APPEND_DOT\\n line_frac = max(line_frac, dot_fraction(v_coords));\\n#endif\\n#ifdef APPEND_CROSS\\n line_frac = max(line_frac, line_fraction(one_cross(v_coords, line_cap, 0.5*v_size.x)));\\n#endif\\n#ifdef APPEND_CROSS_2\\n vec2 lengths = vec2(v_size.x/3.0, v_size.x/2.0);\\n line_frac = max(line_frac, line_fraction(one_cross_2(v_coords, line_cap, lengths)));\\n#endif\\n#ifdef APPEND_X\\n vec2 p = vec2((v_coords.x + v_coords.y)/SQRT2, (v_coords.x - v_coords.y)/SQRT2);\\n line_frac = max(line_frac, line_fraction(one_cross(p, line_cap, APPEND_X_LEN)));\\n#endif\\n#ifdef APPEND_Y\\n line_frac = max(line_frac, line_fraction(one_y(v_coords, line_cap, 0.5*v_size.x)));\\n#endif\\n\\n if (line_frac > 0.0) {\\n vec4 line_color = fractional_color(v_line_color, line_frac);\\n color = blend_colors(line_color, color);\\n }\\n\\n gl_FragColor = color;\\n}\\n\"},\n", - " 419: function _(t,_,i,h,e){h();const s=t(420),a=t(421),r=t(422);class l extends s.BaseGLGlyph{constructor(t,_){super(t,_),this.glyph=_,this._antialias=1.5,this._show_all=!1}_draw_one_marker_type(t,_,i){const h={scissor:this.regl_wrapper.scissor,viewport:this.regl_wrapper.viewport,canvas_size:[_.width,_.height],pixel_ratio:_.pixel_ratio,center:i._centers,width:i._widths,height:i._heights,angle:i._angles,size_hint:(0,r.marker_type_to_size_hint)(t),nmarkers:i.nvertices,antialias:this._antialias,linewidth:this._linewidths,line_color:this._line_rgba,fill_color:this._fill_rgba,line_cap:this._line_caps,line_join:this._line_joins,show:this._show};if(this._have_hatch){const _=Object.assign(Object.assign({},h),{hatch_pattern:this._hatch_patterns,hatch_scale:this._hatch_scales,hatch_weight:this._hatch_weights,hatch_color:this._hatch_rgba});this.regl_wrapper.marker_hatch(t)(_)}else this.regl_wrapper.marker_no_hatch(t)(h)}_set_visuals(){const t=this._get_visuals(),_=t.fill,i=t.line;if(null==this._linewidths&&(this._linewidths=new a.Float32Buffer(this.regl_wrapper),this._line_caps=new a.Uint8Buffer(this.regl_wrapper),this._line_joins=new a.Uint8Buffer(this.regl_wrapper),this._line_rgba=new a.NormalizedUint8Buffer(this.regl_wrapper),this._fill_rgba=new a.NormalizedUint8Buffer(this.regl_wrapper)),this._linewidths.set_from_prop(i.line_width),this._line_caps.set_from_line_cap(i.line_cap),this._line_joins.set_from_line_join(i.line_join),this._line_rgba.set_from_color(i.line_color,i.line_alpha),this._fill_rgba.set_from_color(_.fill_color,_.fill_alpha),this._have_hatch=t.hatch.doit,this._have_hatch){const _=t.hatch;null==this._hatch_patterns&&(this._hatch_patterns=new a.Uint8Buffer(this.regl_wrapper),this._hatch_scales=new a.Float32Buffer(this.regl_wrapper),this._hatch_weights=new a.Float32Buffer(this.regl_wrapper),this._hatch_rgba=new a.NormalizedUint8Buffer(this.regl_wrapper)),this._hatch_patterns.set_from_hatch_pattern(_.hatch_pattern),this._hatch_scales.set_from_prop(_.hatch_scale),this._hatch_weights.set_from_prop(_.hatch_weight),this._hatch_rgba.set_from_color(_.hatch_color,_.hatch_alpha)}}}i.BaseMarkerGL=l,l.__name__=\"BaseMarkerGL\",l.missing_point=-1e4},\n", - " 420: function _(e,t,s,i,h){i();class a{constructor(e,t){this.glyph=t,this.nvertices=0,this.size_changed=!1,this.data_changed=!1,this.visuals_changed=!1,this.regl_wrapper=e}set_data_changed(){const{data_size:e}=this.glyph;e!=this.nvertices&&(this.nvertices=e,this.size_changed=!0),this.data_changed=!0}set_visuals_changed(){this.visuals_changed=!0}render(e,t,s){if(0==t.length)return!0;const{width:i,height:h}=this.glyph.renderer.plot_view.canvas_view.webgl.canvas,a={pixel_ratio:this.glyph.renderer.plot_view.canvas_view.pixel_ratio,width:i,height:h};return this.draw(t,s,a),!0}}s.BaseGLGlyph=a,a.__name__=\"BaseGLGlyph\"},\n", - " 421: function _(r,t,a,e,s){e();const i=r(422),_=r(22);class n{constructor(r){this.regl_wrapper=r,this.is_scalar=!0}get_sized_array(r){return null!=this.array&&this.array.length==r||(this.array=this.new_array(r)),this.array}is_normalized(){return!1}get length(){return null!=this.array?this.array.length:0}set_from_array(r){const t=r.length,a=this.get_sized_array(t);for(let e=0;e0}_set_data(){const s=this.glyph.sx.length,i=s-1;this._is_closed=s>2&&this.glyph.sx[0]==this.glyph.sx[s-1]&&this.glyph.sy[0]==this.glyph.sy[s-1]&&isFinite(this.glyph.sx[0])&&isFinite(this.glyph.sy[0]),null==this._points&&(this._points=new o.Float32Buffer(this.regl_wrapper));const t=this._points.get_sized_array(2*(s+2));for(let i=1;is/255)),this._linewidth=s.line_width.value,this._linewidth<1&&(this._color[3]*=this._linewidth,this._linewidth=1),this._line_dash=(0,a.resolve_line_dash)(s.line_dash.value),this._is_dashed()&&([this._dash_tex_info,this._dash_tex,this._dash_scale]=this.regl_wrapper.get_dash(this._line_dash),this._dash_offset=s.line_dash_offset.value)}}t.LineGL=r,r.__name__=\"LineGL\"},\n", - " 427: function _(s,t,i,e,r){e();const h=s(421),a=s(424);class n extends a.SingleMarkerGL{constructor(s,t){super(s,t),this.glyph=t}draw(s,t,i){this._draw_impl(s,i,t.glglyph,\"square\")}_get_visuals(){return this.glyph.visuals}_set_data(){const s=this.nvertices;null==this._centers&&(this._centers=new h.Float32Buffer(this.regl_wrapper),this._widths=new h.Float32Buffer(this.regl_wrapper),this._heights=new h.Float32Buffer(this.regl_wrapper),this._angles=new h.Float32Buffer(this.regl_wrapper),this._angles.set_from_scalar(0));const t=this._centers.get_sized_array(2*s),i=this._heights.get_sized_array(s),e=this._widths.get_sized_array(s);for(let r=0;r1||s.length<_){this._show_all=!1,n.fill(0),r=0;for(const e of s)1!=h&&i._marker_types.get(e)!=t||(n[e]=255,r++)}else this._show_all&&a==_||(this._show_all=!0,n.fill(255));this._show.update(),0!=r&&this._draw_one_marker_type(t,e,i)}}_get_visuals(){return this.glyph.visuals}_set_data(){const s=this.nvertices;null==this._centers&&(this._centers=new r.Float32Buffer(this.regl_wrapper),this._widths=new r.Float32Buffer(this.regl_wrapper),this._heights=this._widths,this._angles=new r.Float32Buffer(this.regl_wrapper));const t=this._centers.get_sized_array(2*s);for(let e=0;ethis.render()))}remove(){null!=this.icon_view&&this.icon_view.remove(),super.remove()}styles(){return[...super.styles(),d.default]}_render_button(...t){return(0,c.button)({type:\"button\",disabled:this.model.disabled,class:[h.btn,h[`btn_${this.model.button_type}`]]},...t)}render(){super.render(),this.button_el=this._render_button(this.model.label),this.button_el.addEventListener(\"click\",(()=>this.click())),null!=this.icon_view&&(\"\"!=this.model.label?(0,c.prepend)(this.button_el,this.icon_view.el,(0,c.nbsp)()):(0,c.prepend)(this.button_el,this.icon_view.el),this.icon_view.render()),this.group_el=(0,c.div)({class:h.btn_group},this.button_el),this.el.appendChild(this.group_el)}click(){}}n.AbstractButtonView=b,b.__name__=\"AbstractButtonView\";class p extends _.Control{constructor(t){super(t)}}n.AbstractButton=p,o=p,p.__name__=\"AbstractButton\",o.define((({String:t,Ref:e,Nullable:n})=>({label:[t,\"Button\"],icon:[n(e(a.AbstractIcon)),null],button_type:[r.ButtonType,\"default\"]})))},\n", - " 442: function _(t,e,o,s,n){s();const i=t(512),l=t(43);class c extends i.WidgetView{connect_signals(){super.connect_signals();const t=this.model.properties;this.on_change(t.disabled,(()=>{for(const t of this.controls())(0,l.toggle_attribute)(t,\"disabled\",this.model.disabled)}))}}o.ControlView=c,c.__name__=\"ControlView\";class r extends i.Widget{constructor(t){super(t)}}o.Control=r,r.__name__=\"Control\"},\n", - " 512: function _(i,e,t,n,o){var r;n();const s=i(312);class _ extends s.HTMLBoxView{get orientation(){return\"horizontal\"}get default_size(){return this.model.default_size}_width_policy(){return\"horizontal\"==this.orientation?super._width_policy():\"fixed\"}_height_policy(){return\"horizontal\"==this.orientation?\"fixed\":super._height_policy()}box_sizing(){const i=super.box_sizing();return\"horizontal\"==this.orientation?null==i.width&&(i.width=this.default_size):null==i.height&&(i.height=this.default_size),i}}t.WidgetView=_,_.__name__=\"WidgetView\";class h extends s.HTMLBox{constructor(i){super(i)}}t.Widget=h,r=h,h.__name__=\"Widget\",r.define((({Number:i})=>({default_size:[i,300]}))),r.override({margin:[5,5,5,5]})},\n", - " 444: function _(c,t,s,n,e){n();const o=c(53),_=c(226);class a extends _.DOMView{}s.AbstractIconView=a,a.__name__=\"AbstractIconView\";class r extends o.Model{constructor(c){super(c)}}s.AbstractIcon=r,r.__name__=\"AbstractIcon\"},\n", - " 445: function _(e,t,n,s,i){s();const h=e(1);var o;const _=e(446),u=e(43),r=e(10),c=(0,h.__importStar)(e(229)),a=c;class l extends _.TextInputView{constructor(){super(...arguments),this._open=!1,this._last_value=\"\",this._hover_index=0}styles(){return[...super.styles(),c.default]}render(){super.render(),this.input_el.addEventListener(\"keydown\",(e=>this._keydown(e))),this.input_el.addEventListener(\"keyup\",(e=>this._keyup(e))),this.menu=(0,u.div)({class:[a.menu,a.below]}),this.menu.addEventListener(\"click\",(e=>this._menu_click(e))),this.menu.addEventListener(\"mouseover\",(e=>this._menu_hover(e))),this.el.appendChild(this.menu),(0,u.undisplay)(this.menu)}change_input(){this._open&&this.menu.children.length>0?(this.model.value=this.menu.children[this._hover_index].textContent,this.input_el.focus(),this._hide_menu()):this.model.restrict||super.change_input()}_update_completions(e){(0,u.empty)(this.menu);for(const t of e){const e=(0,u.div)(t);this.menu.appendChild(e)}e.length>0&&this.menu.children[0].classList.add(a.active)}_show_menu(){if(!this._open){this._open=!0,this._hover_index=0,this._last_value=this.model.value,(0,u.display)(this.menu);const e=t=>{const{target:n}=t;n instanceof HTMLElement&&!this.el.contains(n)&&(document.removeEventListener(\"click\",e),this._hide_menu())};document.addEventListener(\"click\",e)}}_hide_menu(){this._open&&(this._open=!1,(0,u.undisplay)(this.menu))}_menu_click(e){e.target!=e.currentTarget&&e.target instanceof Element&&(this.model.value=e.target.textContent,this.input_el.focus(),this._hide_menu())}_menu_hover(e){if(e.target!=e.currentTarget&&e.target instanceof Element){let t=0;for(t=0;t0&&(this.menu.children[this._hover_index].classList.remove(a.active),this._hover_index=(0,r.clamp)(e,0,t-1),this.menu.children[this._hover_index].classList.add(a.active))}_keydown(e){}_keyup(e){switch(e.keyCode){case u.Keys.Enter:this.change_input();break;case u.Keys.Esc:this._hide_menu();break;case u.Keys.Up:this._bump_hover(this._hover_index-1);break;case u.Keys.Down:this._bump_hover(this._hover_index+1);break;default:{const e=this.input_el.value;if(e.lengthe:e=>e.toLowerCase();for(const n of this.model.completions)s(n).startsWith(s(e))&&t.push(n);this._update_completions(t),0==t.length?this._hide_menu():this._show_menu()}}}}n.AutocompleteInputView=l,l.__name__=\"AutocompleteInputView\";class d extends _.TextInput{constructor(e){super(e)}}n.AutocompleteInput=d,o=d,d.__name__=\"AutocompleteInput\",o.prototype.default_view=l,o.define((({Boolean:e,Int:t,String:n,Array:s})=>({completions:[s(n),[]],min_characters:[t,2],case_sensitive:[e,!0],restrict:[e,!0]})))},\n", - " 446: function _(t,e,n,p,_){p();const u=t(1);var i;const s=t(447),r=t(43),x=(0,u.__importStar)(t(449));class a extends s.TextLikeInputView{_render_input(){this.input_el=(0,r.input)({type:\"text\",class:x.input})}}n.TextInputView=a,a.__name__=\"TextInputView\";class c extends s.TextLikeInput{constructor(t){super(t)}}n.TextInput=c,i=c,c.__name__=\"TextInput\",i.prototype.default_view=a},\n", - " 447: function _(e,t,n,i,l){var s;i();const h=e(448);class a extends h.InputWidgetView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.name.change,(()=>{var e;return this.input_el.name=null!==(e=this.model.name)&&void 0!==e?e:\"\"})),this.connect(this.model.properties.value.change,(()=>this.input_el.value=this.model.value)),this.connect(this.model.properties.value_input.change,(()=>this.input_el.value=this.model.value_input)),this.connect(this.model.properties.disabled.change,(()=>this.input_el.disabled=this.model.disabled)),this.connect(this.model.properties.placeholder.change,(()=>this.input_el.placeholder=this.model.placeholder)),this.connect(this.model.properties.max_length.change,(()=>{const{max_length:e}=this.model;null!=e?this.input_el.maxLength=e:this.input_el.removeAttribute(\"maxLength\")}))}render(){var e;super.render(),this._render_input();const{input_el:t}=this;t.name=null!==(e=this.model.name)&&void 0!==e?e:\"\",t.value=this.model.value,t.disabled=this.model.disabled,t.placeholder=this.model.placeholder,null!=this.model.max_length&&(t.maxLength=this.model.max_length),t.addEventListener(\"change\",(()=>this.change_input())),t.addEventListener(\"input\",(()=>this.change_input_value())),this.group_el.appendChild(t)}change_input(){this.model.value=this.input_el.value,super.change_input()}change_input_value(){this.model.value_input=this.input_el.value,super.change_input()}}n.TextLikeInputView=a,a.__name__=\"TextLikeInputView\";class u extends h.InputWidget{constructor(e){super(e)}}n.TextLikeInput=u,s=u,u.__name__=\"TextLikeInput\",s.define((({Int:e,String:t,Nullable:n})=>({value:[t,\"\"],value_input:[t,\"\"],placeholder:[t,\"\"],max_length:[n(e),null]})))},\n", - " 448: function _(e,t,n,s,l){s();const i=e(1);var o;const r=e(442),_=e(43),p=(0,i.__importStar)(e(449)),a=p;class c extends r.ControlView{*controls(){yield this.input_el}connect_signals(){super.connect_signals(),this.connect(this.model.properties.title.change,(()=>{this.label_el.textContent=this.model.title}))}styles(){return[...super.styles(),p.default]}render(){super.render();const{title:e}=this.model;this.label_el=(0,_.label)({style:{display:0==e.length?\"none\":\"\"}},e),this.group_el=(0,_.div)({class:a.input_group},this.label_el),this.el.appendChild(this.group_el)}change_input(){}}n.InputWidgetView=c,c.__name__=\"InputWidgetView\";class d extends r.Control{constructor(e){super(e)}}n.InputWidget=d,o=d,d.__name__=\"InputWidget\",o.define((({String:e})=>({title:[e,\"\"]})))},\n", - " 449: function _(o,p,t,n,i){n(),t.root=\"bk-root\",t.input=\"bk-input\",t.input_group=\"bk-input-group\",t.inline=\"bk-inline\",t.spin_wrapper=\"bk-spin-wrapper\",t.spin_btn=\"bk-spin-btn\",t.spin_btn_up=\"bk-spin-btn-up\",t.spin_btn_down=\"bk-spin-btn-down\",t.default='.bk-root .bk-input{display:inline-block;width:100%;flex-grow:1;min-height:31px;padding:0 12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;}.bk-root .bk-input:focus{border-color:#66afe9;outline:0;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);}.bk-root .bk-input::placeholder,.bk-root .bk-input:-ms-input-placeholder,.bk-root .bk-input::-moz-placeholder,.bk-root .bk-input::-webkit-input-placeholder{color:#999;opacity:1;}.bk-root .bk-input[disabled]{cursor:not-allowed;background-color:#eee;opacity:1;}.bk-root select:not([multiple]).bk-input,.bk-root select:not([size]).bk-input{height:auto;appearance:none;-webkit-appearance:none;background-image:url(\\'data:image/svg+xml;utf8,\\');background-position:right 0.5em center;background-size:8px 6px;background-repeat:no-repeat;}.bk-root select[multiple].bk-input,.bk-root select[size].bk-input,.bk-root textarea.bk-input{height:auto;}.bk-root .bk-input-group{width:100%;height:100%;display:inline-flex;flex-wrap:nowrap;align-items:start;flex-direction:column;white-space:nowrap;}.bk-root .bk-input-group.bk-inline{flex-direction:row;}.bk-root .bk-input-group.bk-inline > *:not(:first-child){margin-left:5px;}.bk-root .bk-input-group input[type=\"checkbox\"] + span,.bk-root .bk-input-group input[type=\"radio\"] + span{position:relative;top:-2px;margin-left:3px;}.bk-root .bk-input-group > .bk-spin-wrapper{display:inherit;width:inherit;height:inherit;position:relative;overflow:hidden;padding:0;vertical-align:middle;}.bk-root .bk-input-group > .bk-spin-wrapper input{padding-right:20px;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn{position:absolute;display:block;height:50%;min-height:0;min-width:0;width:30px;padding:0;margin:0;right:0;border:none;background:none;cursor:pointer;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn:before{content:\"\";display:inline-block;transform:translateY(-50%);border-left:5px solid transparent;border-right:5px solid transparent;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-up{top:0;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-up:before{border-bottom:5px solid black;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-up:disabled:before{border-bottom-color:grey;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-down{bottom:0;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-down:before{border-top:5px solid black;}.bk-root .bk-input-group > .bk-spin-wrapper > .bk-spin-btn.bk-spin-btn-down:disabled:before{border-top-color:grey;}'},\n", - " 450: function _(t,e,n,o,c){var s;o();const u=t(441),r=t(251);class i extends u.AbstractButtonView{click(){this.model.trigger_event(new r.ButtonClick),super.click()}}n.ButtonView=i,i.__name__=\"ButtonView\";class _ extends u.AbstractButton{constructor(t){super(t)}}n.Button=_,s=_,_.__name__=\"Button\",s.prototype.default_view=i,s.override({label:\"Button\"})},\n", - " 451: function _(t,e,o,c,a){c();const s=t(1);var n;const i=t(452),r=t(43),u=(0,s.__importStar)(t(318));class _ extends i.ButtonGroupView{get active(){return new Set(this.model.active)}change_active(t){const{active:e}=this;e.has(t)?e.delete(t):e.add(t),this.model.active=[...e].sort()}_update_active(){const{active:t}=this;this._buttons.forEach(((e,o)=>{(0,r.classes)(e).toggle(u.active,t.has(o))}))}}o.CheckboxButtonGroupView=_,_.__name__=\"CheckboxButtonGroupView\";class h extends i.ButtonGroup{constructor(t){super(t)}}o.CheckboxButtonGroup=h,n=h,h.__name__=\"CheckboxButtonGroup\",n.prototype.default_view=_,n.define((({Int:t,Array:e})=>({active:[e(t),[]]})))},\n", - " 452: function _(t,e,n,s,i){s();const o=t(1);var r;const a=t(453),l=t(20),d=t(43),u=(0,o.__importStar)(t(318)),_=u;class c extends a.OrientedControlView{get default_size(){return\"horizontal\"==this.orientation?this.model.default_size:void 0}*controls(){yield*this._buttons}connect_signals(){super.connect_signals();const t=this.model.properties;this.on_change(t.button_type,(()=>this.render())),this.on_change(t.labels,(()=>this.render())),this.on_change(t.active,(()=>this._update_active()))}styles(){return[...super.styles(),u.default]}render(){super.render(),this._buttons=this.model.labels.map(((t,e)=>{const n=(0,d.div)({class:[_.btn,_[`btn_${this.model.button_type}`]],disabled:this.model.disabled},t);return n.addEventListener(\"click\",(()=>this.change_active(e))),n})),this._update_active();const t=\"horizontal\"==this.model.orientation?_.horizontal:_.vertical,e=(0,d.div)({class:[_.btn_group,t]},this._buttons);this.el.appendChild(e)}}n.ButtonGroupView=c,c.__name__=\"ButtonGroupView\";class h extends a.OrientedControl{constructor(t){super(t)}}n.ButtonGroup=h,r=h,h.__name__=\"ButtonGroup\",r.define((({String:t,Array:e})=>({labels:[e(t),[]],button_type:[l.ButtonType,\"default\"]})))},\n", - " 453: function _(n,t,e,o,r){var i;o();const a=n(442),l=n(20);class s extends a.ControlView{get orientation(){return this.model.orientation}}e.OrientedControlView=s,s.__name__=\"OrientedControlView\";class _ extends a.Control{constructor(n){super(n)}}e.OrientedControl=_,i=_,_.__name__=\"OrientedControl\",i.define((()=>({orientation:[l.Orientation,\"horizontal\"]})))},\n", - " 454: function _(e,t,n,i,s){i();const o=e(1);var a;const c=e(455),l=e(43),d=e(9),p=(0,o.__importStar)(e(449));class r extends c.InputGroupView{render(){super.render();const e=(0,l.div)({class:[p.input_group,this.model.inline?p.inline:null]});this.el.appendChild(e);const{active:t,labels:n}=this.model;this._inputs=[];for(let i=0;ithis.change_active(i))),this._inputs.push(s),this.model.disabled&&(s.disabled=!0),(0,d.includes)(t,i)&&(s.checked=!0);const o=(0,l.label)(s,(0,l.span)(n[i]));e.appendChild(o)}}change_active(e){const t=new Set(this.model.active);t.has(e)?t.delete(e):t.add(e),this.model.active=[...t].sort()}}n.CheckboxGroupView=r,r.__name__=\"CheckboxGroupView\";class h extends c.InputGroup{constructor(e){super(e)}}n.CheckboxGroup=h,a=h,h.__name__=\"CheckboxGroup\",a.prototype.default_view=r,a.define((({Boolean:e,Int:t,String:n,Array:i})=>({active:[i(t),[]],labels:[i(n),[]],inline:[e,!1]})))},\n", - " 455: function _(n,t,e,s,o){s();const r=n(1),u=n(442),c=(0,r.__importDefault)(n(449));class _ extends u.ControlView{*controls(){yield*this._inputs}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.render()))}styles(){return[...super.styles(),c.default]}}e.InputGroupView=_,_.__name__=\"InputGroupView\";class i extends u.Control{constructor(n){super(n)}}e.InputGroup=i,i.__name__=\"InputGroup\"},\n", - " 456: function _(e,t,i,n,o){n();const s=e(1);var l;const r=e(448),c=e(43),a=e(22),d=(0,s.__importStar)(e(449));class h extends r.InputWidgetView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.name.change,(()=>{var e;return this.input_el.name=null!==(e=this.model.name)&&void 0!==e?e:\"\"})),this.connect(this.model.properties.color.change,(()=>this.input_el.value=(0,a.color2hexrgb)(this.model.color))),this.connect(this.model.properties.disabled.change,(()=>this.input_el.disabled=this.model.disabled))}render(){super.render(),this.input_el=(0,c.input)({type:\"color\",class:d.input,name:this.model.name,value:this.model.color,disabled:this.model.disabled}),this.input_el.addEventListener(\"change\",(()=>this.change_input())),this.group_el.appendChild(this.input_el)}change_input(){this.model.color=this.input_el.value,super.change_input()}}i.ColorPickerView=h,h.__name__=\"ColorPickerView\";class p extends r.InputWidget{constructor(e){super(e)}}i.ColorPicker=p,l=p,p.__name__=\"ColorPicker\",l.prototype.default_view=h,l.define((({Color:e})=>({color:[e,\"#000000\"]})))},\n", - " 457: function _(e,t,i,n,s){n();const a=e(1);var l;const o=(0,a.__importDefault)(e(458)),d=e(448),r=e(43),c=e(20),u=e(8),h=(0,a.__importStar)(e(449)),_=(0,a.__importDefault)(e(459));function p(e){const t=[];for(const i of e)if((0,u.isString)(i))t.push(i);else{const[e,n]=i;t.push({from:e,to:n})}return t}class m extends d.InputWidgetView{connect_signals(){super.connect_signals();const{value:e,min_date:t,max_date:i,disabled_dates:n,enabled_dates:s,position:a,inline:l}=this.model.properties;this.connect(e.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.setDate(this.model.value)})),this.connect(t.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"minDate\",this.model.min_date)})),this.connect(i.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"maxDate\",this.model.max_date)})),this.connect(n.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"disable\",this.model.disabled_dates)})),this.connect(s.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"enable\",this.model.enabled_dates)})),this.connect(a.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"position\",this.model.position)})),this.connect(l.change,(()=>{var e;return null===(e=this._picker)||void 0===e?void 0:e.set(\"inline\",this.model.inline)}))}remove(){var e;null===(e=this._picker)||void 0===e||e.destroy(),super.remove()}styles(){return[...super.styles(),_.default]}render(){var e,t;null==this._picker&&(super.render(),this.input_el=(0,r.input)({type:\"text\",class:h.input,disabled:this.model.disabled}),this.group_el.appendChild(this.input_el),this._picker=(0,o.default)(this.input_el,{defaultDate:this.model.value,minDate:null!==(e=this.model.min_date)&&void 0!==e?e:void 0,maxDate:null!==(t=this.model.max_date)&&void 0!==t?t:void 0,inline:this.model.inline,position:this.model.position,disable:p(this.model.disabled_dates),enable:p(this.model.enabled_dates),onChange:(e,t,i)=>this._on_change(e,t,i)}))}_on_change(e,t,i){this.model.value=t,this.change_input()}}i.DatePickerView=m,m.__name__=\"DatePickerView\";class v extends d.InputWidget{constructor(e){super(e)}}i.DatePicker=v,l=v,v.__name__=\"DatePicker\",l.prototype.default_view=m,l.define((({Boolean:e,String:t,Array:i,Tuple:n,Or:s,Nullable:a})=>{const l=i(s(t,n(t,t)));return{value:[t],min_date:[a(t),null],max_date:[a(t),null],disabled_dates:[l,[]],enabled_dates:[l,[]],position:[c.CalendarPosition,\"auto\"],inline:[e,!1]}}))},\n", - " 458: function _(e,n,t,a,i){\n", - " /* flatpickr v4.6.6, @license MIT */var o,r;o=this,r=function(){\"use strict\";\n", - " /*! *****************************************************************************\n", - " Copyright (c) Microsoft Corporation.\n", - " \n", - " Permission to use, copy, modify, and/or distribute this software for any\n", - " purpose with or without fee is hereby granted.\n", - " \n", - " THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n", - " REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n", - " AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n", - " INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n", - " LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n", - " OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n", - " PERFORMANCE OF THIS SOFTWARE.\n", - " ***************************************************************************** */var e=function(){return e=Object.assign||function(e){for(var n,t=1,a=arguments.length;t\",noCalendar:!1,now:new Date,onChange:[],onClose:[],onDayCreate:[],onDestroy:[],onKeyDown:[],onMonthChange:[],onOpen:[],onParseConfig:[],onReady:[],onValueUpdate:[],onYearChange:[],onPreCalendarPosition:[],plugins:[],position:\"auto\",positionElement:void 0,prevArrow:\"\",shorthandCurrentMonth:!1,showMonths:1,static:!1,time_24hr:!1,weekNumbers:!1,wrap:!1},i={weekdays:{shorthand:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],longhand:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]},months:{shorthand:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],longhand:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"]},daysInMonth:[31,28,31,30,31,30,31,31,30,31,30,31],firstDayOfWeek:0,ordinal:function(e){var n=e%100;if(n>3&&n<21)return\"th\";switch(n%10){case 1:return\"st\";case 2:return\"nd\";case 3:return\"rd\";default:return\"th\"}},rangeSeparator:\" to \",weekAbbreviation:\"Wk\",scrollTitle:\"Scroll to increment\",toggleTitle:\"Click to toggle\",amPM:[\"AM\",\"PM\"],yearAriaLabel:\"Year\",monthAriaLabel:\"Month\",hourAriaLabel:\"Hour\",minuteAriaLabel:\"Minute\",time_24hr:!1},o=function(e,n){return void 0===n&&(n=2),(\"000\"+e).slice(-1*n)},r=function(e){return!0===e?1:0};function l(e,n,t){var a;return void 0===t&&(t=!1),function(){var i=this,o=arguments;null!==a&&clearTimeout(a),a=window.setTimeout((function(){a=null,t||e.apply(i,o)}),n),t&&!a&&e.apply(i,o)}}var c=function(e){return e instanceof Array?e:[e]};function d(e,n,t){if(!0===t)return e.classList.add(n);e.classList.remove(n)}function s(e,n,t){var a=window.document.createElement(e);return n=n||\"\",t=t||\"\",a.className=n,void 0!==t&&(a.textContent=t),a}function u(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function f(e,n){return n(e)?e:e.parentNode?f(e.parentNode,n):void 0}function m(e,n){var t=s(\"div\",\"numInputWrapper\"),a=s(\"input\",\"numInput \"+e),i=s(\"span\",\"arrowUp\"),o=s(\"span\",\"arrowDown\");if(-1===navigator.userAgent.indexOf(\"MSIE 9.0\")?a.type=\"number\":(a.type=\"text\",a.pattern=\"\\\\d*\"),void 0!==n)for(var r in n)a.setAttribute(r,n[r]);return t.appendChild(a),t.appendChild(i),t.appendChild(o),t}function g(e){try{return\"function\"==typeof e.composedPath?e.composedPath()[0]:e.target}catch(n){return e.target}}var p=function(){},h=function(e,n,t){return t.months[n?\"shorthand\":\"longhand\"][e]},v={D:p,F:function(e,n,t){e.setMonth(t.months.longhand.indexOf(n))},G:function(e,n){e.setHours(parseFloat(n))},H:function(e,n){e.setHours(parseFloat(n))},J:function(e,n){e.setDate(parseFloat(n))},K:function(e,n,t){e.setHours(e.getHours()%12+12*r(new RegExp(t.amPM[1],\"i\").test(n)))},M:function(e,n,t){e.setMonth(t.months.shorthand.indexOf(n))},S:function(e,n){e.setSeconds(parseFloat(n))},U:function(e,n){return new Date(1e3*parseFloat(n))},W:function(e,n,t){var a=parseInt(n),i=new Date(e.getFullYear(),0,2+7*(a-1),0,0,0,0);return i.setDate(i.getDate()-i.getDay()+t.firstDayOfWeek),i},Y:function(e,n){e.setFullYear(parseFloat(n))},Z:function(e,n){return new Date(n)},d:function(e,n){e.setDate(parseFloat(n))},h:function(e,n){e.setHours(parseFloat(n))},i:function(e,n){e.setMinutes(parseFloat(n))},j:function(e,n){e.setDate(parseFloat(n))},l:p,m:function(e,n){e.setMonth(parseFloat(n)-1)},n:function(e,n){e.setMonth(parseFloat(n)-1)},s:function(e,n){e.setSeconds(parseFloat(n))},u:function(e,n){return new Date(parseFloat(n))},w:p,y:function(e,n){e.setFullYear(2e3+parseFloat(n))}},D={D:\"(\\\\w+)\",F:\"(\\\\w+)\",G:\"(\\\\d\\\\d|\\\\d)\",H:\"(\\\\d\\\\d|\\\\d)\",J:\"(\\\\d\\\\d|\\\\d)\\\\w+\",K:\"\",M:\"(\\\\w+)\",S:\"(\\\\d\\\\d|\\\\d)\",U:\"(.+)\",W:\"(\\\\d\\\\d|\\\\d)\",Y:\"(\\\\d{4})\",Z:\"(.+)\",d:\"(\\\\d\\\\d|\\\\d)\",h:\"(\\\\d\\\\d|\\\\d)\",i:\"(\\\\d\\\\d|\\\\d)\",j:\"(\\\\d\\\\d|\\\\d)\",l:\"(\\\\w+)\",m:\"(\\\\d\\\\d|\\\\d)\",n:\"(\\\\d\\\\d|\\\\d)\",s:\"(\\\\d\\\\d|\\\\d)\",u:\"(.+)\",w:\"(\\\\d\\\\d|\\\\d)\",y:\"(\\\\d{2})\"},w={Z:function(e){return e.toISOString()},D:function(e,n,t){return n.weekdays.shorthand[w.w(e,n,t)]},F:function(e,n,t){return h(w.n(e,n,t)-1,!1,n)},G:function(e,n,t){return o(w.h(e,n,t))},H:function(e){return o(e.getHours())},J:function(e,n){return void 0!==n.ordinal?e.getDate()+n.ordinal(e.getDate()):e.getDate()},K:function(e,n){return n.amPM[r(e.getHours()>11)]},M:function(e,n){return h(e.getMonth(),!0,n)},S:function(e){return o(e.getSeconds())},U:function(e){return e.getTime()/1e3},W:function(e,n,t){return t.getWeek(e)},Y:function(e){return o(e.getFullYear(),4)},d:function(e){return o(e.getDate())},h:function(e){return e.getHours()%12?e.getHours()%12:12},i:function(e){return o(e.getMinutes())},j:function(e){return e.getDate()},l:function(e,n){return n.weekdays.longhand[e.getDay()]},m:function(e){return o(e.getMonth()+1)},n:function(e){return e.getMonth()+1},s:function(e){return e.getSeconds()},u:function(e){return e.getTime()},w:function(e){return e.getDay()},y:function(e){return String(e.getFullYear()).substring(2)}},b=function(e){var n=e.config,t=void 0===n?a:n,o=e.l10n,r=void 0===o?i:o,l=e.isMobile,c=void 0!==l&&l;return function(e,n,a){var i=a||r;return void 0===t.formatDate||c?n.split(\"\").map((function(n,a,o){return w[n]&&\"\\\\\"!==o[a-1]?w[n](e,i,t):\"\\\\\"!==n?n:\"\"})).join(\"\"):t.formatDate(e,n,i)}},C=function(e){var n=e.config,t=void 0===n?a:n,o=e.l10n,r=void 0===o?i:o;return function(e,n,i,o){if(0===e||e){var l,c=o||r,d=e;if(e instanceof Date)l=new Date(e.getTime());else if(\"string\"!=typeof e&&void 0!==e.toFixed)l=new Date(e);else if(\"string\"==typeof e){var s=n||(t||a).dateFormat,u=String(e).trim();if(\"today\"===u)l=new Date,i=!0;else if(/Z$/.test(u)||/GMT$/.test(u))l=new Date(e);else if(t&&t.parseDate)l=t.parseDate(e,s);else{l=t&&t.noCalendar?new Date((new Date).setHours(0,0,0,0)):new Date((new Date).getFullYear(),0,1,0,0,0,0);for(var f=void 0,m=[],g=0,p=0,h=\"\";gl&&(u=a===w.hourElement?u-l-r(!w.amPM):i,m&&H(void 0,1,w.hourElement)),w.amPM&&f&&(1===c?u+d===23:Math.abs(u-d)>c)&&(w.amPM.textContent=w.l10n.amPM[r(w.amPM.textContent===w.l10n.amPM[0])]),a.value=o(u)}}(e);var c=w._input.value;I(),be(),w._input.value!==c&&w._debouncedChange()}function I(){if(void 0!==w.hourElement&&void 0!==w.minuteElement){var e,n,t=(parseInt(w.hourElement.value.slice(-2),10)||0)%24,a=(parseInt(w.minuteElement.value,10)||0)%60,i=void 0!==w.secondElement?(parseInt(w.secondElement.value,10)||0)%60:0;void 0!==w.amPM&&(e=t,n=w.amPM.textContent,t=e%12+12*r(n===w.l10n.amPM[1]));var o=void 0!==w.config.minTime||w.config.minDate&&w.minDateHasTime&&w.latestSelectedDateObj&&0===M(w.latestSelectedDateObj,w.config.minDate,!0);if(void 0!==w.config.maxTime||w.config.maxDate&&w.maxDateHasTime&&w.latestSelectedDateObj&&0===M(w.latestSelectedDateObj,w.config.maxDate,!0)){var l=void 0!==w.config.maxTime?w.config.maxTime:w.config.maxDate;(t=Math.min(t,l.getHours()))===l.getHours()&&(a=Math.min(a,l.getMinutes())),a===l.getMinutes()&&(i=Math.min(i,l.getSeconds()))}if(o){var c=void 0!==w.config.minTime?w.config.minTime:w.config.minDate;(t=Math.max(t,c.getHours()))===c.getHours()&&(a=Math.max(a,c.getMinutes())),a===c.getMinutes()&&(i=Math.max(i,c.getSeconds()))}O(t,a,i)}}function S(e){var n=e||w.latestSelectedDateObj;n&&O(n.getHours(),n.getMinutes(),n.getSeconds())}function _(){var e=w.config.defaultHour,n=w.config.defaultMinute,t=w.config.defaultSeconds;if(void 0!==w.config.minDate){var a=w.config.minDate.getHours(),i=w.config.minDate.getMinutes();(e=Math.max(e,a))===a&&(n=Math.max(i,n)),e===a&&n===i&&(t=w.config.minDate.getSeconds())}if(void 0!==w.config.maxDate){var o=w.config.maxDate.getHours(),r=w.config.maxDate.getMinutes();(e=Math.min(e,o))===o&&(n=Math.min(r,n)),e===o&&n===r&&(t=w.config.maxDate.getSeconds())}return{hours:e,minutes:n,seconds:t}}function O(e,n,t){void 0!==w.latestSelectedDateObj&&w.latestSelectedDateObj.setHours(e%24,n,t||0,0),w.hourElement&&w.minuteElement&&!w.isMobile&&(w.hourElement.value=o(w.config.time_24hr?e:(12+e)%12+12*r(e%12==0)),w.minuteElement.value=o(n),void 0!==w.amPM&&(w.amPM.textContent=w.l10n.amPM[r(e>=12)]),void 0!==w.secondElement&&(w.secondElement.value=o(t)))}function F(e){var n=g(e),t=parseInt(n.value)+(e.delta||0);(t/1e3>1||\"Enter\"===e.key&&!/[^\\d]/.test(t.toString()))&&Q(t)}function N(e,n,t,a){return n instanceof Array?n.forEach((function(n){return N(e,n,t,a)})):e instanceof Array?e.forEach((function(e){return N(e,n,t,a)})):(e.addEventListener(n,t,a),void w._handlers.push({element:e,event:n,handler:t,options:a}))}function A(){pe(\"onChange\")}function P(e,n){var t=void 0!==e?w.parseDate(e):w.latestSelectedDateObj||(w.config.minDate&&w.config.minDate>w.now?w.config.minDate:w.config.maxDate&&w.config.maxDate=0&&M(e,w.selectedDates[1])<=0}(n)&&!ve(n)&&o.classList.add(\"inRange\"),w.weekNumbers&&1===w.config.showMonths&&\"prevMonthDay\"!==e&&t%7==1&&w.weekNumbers.insertAdjacentHTML(\"beforeend\",\"\"+w.config.getWeek(n)+\"\"),pe(\"onDayCreate\",o),o}function L(e){e.focus(),\"range\"===w.config.mode&&ae(e)}function W(e){for(var n=e>0?0:w.config.showMonths-1,t=e>0?w.config.showMonths:-1,a=n;a!=t;a+=e)for(var i=w.daysContainer.children[a],o=e>0?0:i.children.length-1,r=e>0?i.children.length:-1,l=o;l!=r;l+=e){var c=i.children[l];if(-1===c.className.indexOf(\"hidden\")&&X(c.dateObj))return c}}function R(e,n){var t=ee(document.activeElement||document.body),a=void 0!==e?e:t?document.activeElement:void 0!==w.selectedDateElem&&ee(w.selectedDateElem)?w.selectedDateElem:void 0!==w.todayDateElem&&ee(w.todayDateElem)?w.todayDateElem:W(n>0?1:-1);void 0===a?w._input.focus():t?function(e,n){for(var t=-1===e.className.indexOf(\"Month\")?e.dateObj.getMonth():w.currentMonth,a=n>0?w.config.showMonths:-1,i=n>0?1:-1,o=t-w.currentMonth;o!=a;o+=i)for(var r=w.daysContainer.children[o],l=t-w.currentMonth===o?e.$i+n:n<0?r.children.length-1:0,c=r.children.length,d=l;d>=0&&d0?c:-1);d+=i){var s=r.children[d];if(-1===s.className.indexOf(\"hidden\")&&X(s.dateObj)&&Math.abs(e.$i-d)>=Math.abs(n))return L(s)}w.changeMonth(i),R(W(i),0)}(a,n):L(a)}function B(e,n){for(var t=(new Date(e,n,1).getDay()-w.l10n.firstDayOfWeek+7)%7,a=w.utils.getDaysInMonth((n-1+12)%12,e),i=w.utils.getDaysInMonth(n,e),o=window.document.createDocumentFragment(),r=w.config.showMonths>1,l=r?\"prevMonthDay hidden\":\"prevMonthDay\",c=r?\"nextMonthDay hidden\":\"nextMonthDay\",d=a+1-t,u=0;d<=a;d++,u++)o.appendChild(j(l,new Date(e,n-1,d),d,u));for(d=1;d<=i;d++,u++)o.appendChild(j(\"\",new Date(e,n,d),d,u));for(var f=i+1;f<=42-t&&(1===w.config.showMonths||u%7!=0);f++,u++)o.appendChild(j(c,new Date(e,n+1,f%i),f,u));var m=s(\"div\",\"dayContainer\");return m.appendChild(o),m}function J(){if(void 0!==w.daysContainer){u(w.daysContainer),w.weekNumbers&&u(w.weekNumbers);for(var e=document.createDocumentFragment(),n=0;n1||\"dropdown\"!==w.config.monthSelectorType)){var e=function(e){return!(void 0!==w.config.minDate&&w.currentYear===w.config.minDate.getFullYear()&&ew.config.maxDate.getMonth())};w.monthsDropdownContainer.tabIndex=-1,w.monthsDropdownContainer.innerHTML=\"\";for(var n=0;n<12;n++)if(e(n)){var t=s(\"option\",\"flatpickr-monthDropdown-month\");t.value=new Date(w.currentYear,n).getMonth().toString(),t.textContent=h(n,w.config.shorthandCurrentMonth,w.l10n),t.tabIndex=-1,w.currentMonth===n&&(t.selected=!0),w.monthsDropdownContainer.appendChild(t)}}}function U(){var e,n=s(\"div\",\"flatpickr-month\"),t=window.document.createDocumentFragment();w.config.showMonths>1||\"static\"===w.config.monthSelectorType?e=s(\"span\",\"cur-month\"):(w.monthsDropdownContainer=s(\"select\",\"flatpickr-monthDropdown-months\"),w.monthsDropdownContainer.setAttribute(\"aria-label\",w.l10n.monthAriaLabel),N(w.monthsDropdownContainer,\"change\",(function(e){var n=g(e),t=parseInt(n.value,10);w.changeMonth(t-w.currentMonth),pe(\"onMonthChange\")})),K(),e=w.monthsDropdownContainer);var a=m(\"cur-year\",{tabindex:\"-1\"}),i=a.getElementsByTagName(\"input\")[0];i.setAttribute(\"aria-label\",w.l10n.yearAriaLabel),w.config.minDate&&i.setAttribute(\"min\",w.config.minDate.getFullYear().toString()),w.config.maxDate&&(i.setAttribute(\"max\",w.config.maxDate.getFullYear().toString()),i.disabled=!!w.config.minDate&&w.config.minDate.getFullYear()===w.config.maxDate.getFullYear());var o=s(\"div\",\"flatpickr-current-month\");return o.appendChild(e),o.appendChild(a),t.appendChild(o),n.appendChild(t),{container:n,yearElement:i,monthElement:e}}function q(){u(w.monthNav),w.monthNav.appendChild(w.prevMonthNav),w.config.showMonths&&(w.yearElements=[],w.monthElements=[]);for(var e=w.config.showMonths;e--;){var n=U();w.yearElements.push(n.yearElement),w.monthElements.push(n.monthElement),w.monthNav.appendChild(n.container)}w.monthNav.appendChild(w.nextMonthNav)}function $(){w.weekdayContainer?u(w.weekdayContainer):w.weekdayContainer=s(\"div\",\"flatpickr-weekdays\");for(var e=w.config.showMonths;e--;){var n=s(\"div\",\"flatpickr-weekdaycontainer\");w.weekdayContainer.appendChild(n)}return z(),w.weekdayContainer}function z(){if(w.weekdayContainer){var e=w.l10n.firstDayOfWeek,t=n(w.l10n.weekdays.shorthand);e>0&&e\\n \"+t.join(\"\")+\"\\n \\n \"}}function G(e,n){void 0===n&&(n=!0);var t=n?e:e-w.currentMonth;t<0&&!0===w._hidePrevMonthArrow||t>0&&!0===w._hideNextMonthArrow||(w.currentMonth+=t,(w.currentMonth<0||w.currentMonth>11)&&(w.currentYear+=w.currentMonth>11?1:-1,w.currentMonth=(w.currentMonth+12)%12,pe(\"onYearChange\"),K()),J(),pe(\"onMonthChange\"),De())}function V(e){return!(!w.config.appendTo||!w.config.appendTo.contains(e))||w.calendarContainer.contains(e)}function Z(e){if(w.isOpen&&!w.config.inline){var n=g(e),t=V(n),a=n===w.input||n===w.altInput||w.element.contains(n)||e.path&&e.path.indexOf&&(~e.path.indexOf(w.input)||~e.path.indexOf(w.altInput)),i=\"blur\"===e.type?a&&e.relatedTarget&&!V(e.relatedTarget):!a&&!t&&!V(e.relatedTarget),o=!w.config.ignoredFocusElements.some((function(e){return e.contains(n)}));i&&o&&(void 0!==w.timeContainer&&void 0!==w.minuteElement&&void 0!==w.hourElement&&\"\"!==w.input.value&&void 0!==w.input.value&&T(),w.close(),w.config&&\"range\"===w.config.mode&&1===w.selectedDates.length&&(w.clear(!1),w.redraw()))}}function Q(e){if(!(!e||w.config.minDate&&ew.config.maxDate.getFullYear())){var n=e,t=w.currentYear!==n;w.currentYear=n||w.currentYear,w.config.maxDate&&w.currentYear===w.config.maxDate.getFullYear()?w.currentMonth=Math.min(w.config.maxDate.getMonth(),w.currentMonth):w.config.minDate&&w.currentYear===w.config.minDate.getFullYear()&&(w.currentMonth=Math.max(w.config.minDate.getMonth(),w.currentMonth)),t&&(w.redraw(),pe(\"onYearChange\"),K())}}function X(e,n){void 0===n&&(n=!0);var t=w.parseDate(e,void 0,n);if(w.config.minDate&&t&&M(t,w.config.minDate,void 0!==n?n:!w.minDateHasTime)<0||w.config.maxDate&&t&&M(t,w.config.maxDate,void 0!==n?n:!w.maxDateHasTime)>0)return!1;if(0===w.config.enable.length&&0===w.config.disable.length)return!0;if(void 0===t)return!1;for(var a=w.config.enable.length>0,i=a?w.config.enable:w.config.disable,o=0,r=void 0;o=r.from.getTime()&&t.getTime()<=r.to.getTime())return a}return!a}function ee(e){return void 0!==w.daysContainer&&-1===e.className.indexOf(\"hidden\")&&-1===e.className.indexOf(\"flatpickr-disabled\")&&w.daysContainer.contains(e)}function ne(e){e.target!==w._input||e.relatedTarget&&V(e.relatedTarget)||w.setDate(w._input.value,!0,e.target===w.altInput?w.config.altFormat:w.config.dateFormat)}function te(e){var n=g(e),t=w.config.wrap?p.contains(n):n===w._input,a=w.config.allowInput,i=w.isOpen&&(!a||!t),o=w.config.inline&&t&&!a;if(13===e.keyCode&&t){if(a)return w.setDate(w._input.value,!0,n===w.altInput?w.config.altFormat:w.config.dateFormat),n.blur();w.open()}else if(V(n)||i||o){var r=!!w.timeContainer&&w.timeContainer.contains(n);switch(e.keyCode){case 13:r?(e.preventDefault(),T(),se()):ue(e);break;case 27:e.preventDefault(),se();break;case 8:case 46:t&&!w.config.allowInput&&(e.preventDefault(),w.clear());break;case 37:case 39:if(r||t)w.hourElement&&w.hourElement.focus();else if(e.preventDefault(),void 0!==w.daysContainer&&(!1===a||document.activeElement&&ee(document.activeElement))){var l=39===e.keyCode?1:-1;e.ctrlKey?(e.stopPropagation(),G(l),R(W(1),0)):R(void 0,l)}break;case 38:case 40:e.preventDefault();var c=40===e.keyCode?1:-1;w.daysContainer&&void 0!==n.$i||n===w.input||n===w.altInput?e.ctrlKey?(e.stopPropagation(),Q(w.currentYear-c),R(W(1),0)):r||R(void 0,7*c):n===w.currentYearElement?Q(w.currentYear-c):w.config.enableTime&&(!r&&w.hourElement&&w.hourElement.focus(),T(e),w._debouncedChange());break;case 9:if(r){var d=[w.hourElement,w.minuteElement,w.secondElement,w.amPM].concat(w.pluginElements).filter((function(e){return e})),s=d.indexOf(n);if(-1!==s){var u=d[s+(e.shiftKey?-1:1)];e.preventDefault(),(u||w._input).focus()}}else!w.config.noCalendar&&w.daysContainer&&w.daysContainer.contains(n)&&e.shiftKey&&(e.preventDefault(),w._input.focus())}}if(void 0!==w.amPM&&n===w.amPM)switch(e.key){case w.l10n.amPM[0].charAt(0):case w.l10n.amPM[0].charAt(0).toLowerCase():w.amPM.textContent=w.l10n.amPM[0],I(),be();break;case w.l10n.amPM[1].charAt(0):case w.l10n.amPM[1].charAt(0).toLowerCase():w.amPM.textContent=w.l10n.amPM[1],I(),be()}(t||V(n))&&pe(\"onKeyDown\",e)}function ae(e){if(1===w.selectedDates.length&&(!e||e.classList.contains(\"flatpickr-day\")&&!e.classList.contains(\"flatpickr-disabled\"))){for(var n=e?e.dateObj.getTime():w.days.firstElementChild.dateObj.getTime(),t=w.parseDate(w.selectedDates[0],void 0,!0).getTime(),a=Math.min(n,w.selectedDates[0].getTime()),i=Math.max(n,w.selectedDates[0].getTime()),o=!1,r=0,l=0,c=a;ca&&cr)?r=c:c>t&&(!l||c0&&m0&&m>l;return g?(f.classList.add(\"notAllowed\"),[\"inRange\",\"startRange\",\"endRange\"].forEach((function(e){f.classList.remove(e)})),\"continue\"):o&&!g?\"continue\":([\"startRange\",\"inRange\",\"endRange\",\"notAllowed\"].forEach((function(e){f.classList.remove(e)})),void(void 0!==e&&(e.classList.add(n<=w.selectedDates[0].getTime()?\"startRange\":\"endRange\"),tn&&m===t&&f.classList.add(\"endRange\"),m>=r&&(0===l||m<=l)&&(d=t,u=n,(c=m)>Math.min(d,u)&&c0||t.getMinutes()>0||t.getSeconds()>0),w.selectedDates&&(w.selectedDates=w.selectedDates.filter((function(e){return X(e)})),w.selectedDates.length||\"min\"!==e||S(t),be()),w.daysContainer&&(de(),void 0!==t?w.currentYearElement[e]=t.getFullYear().toString():w.currentYearElement.removeAttribute(e),w.currentYearElement.disabled=!!a&&void 0!==t&&a.getFullYear()===t.getFullYear())}}function re(){return w.config.wrap?p.querySelector(\"[data-input]\"):p}function le(){\"object\"!=typeof w.config.locale&&void 0===k.l10ns[w.config.locale]&&w.config.errorHandler(new Error(\"flatpickr: invalid locale \"+w.config.locale)),w.l10n=e(e({},k.l10ns.default),\"object\"==typeof w.config.locale?w.config.locale:\"default\"!==w.config.locale?k.l10ns[w.config.locale]:void 0),D.K=\"(\"+w.l10n.amPM[0]+\"|\"+w.l10n.amPM[1]+\"|\"+w.l10n.amPM[0].toLowerCase()+\"|\"+w.l10n.amPM[1].toLowerCase()+\")\",void 0===e(e({},v),JSON.parse(JSON.stringify(p.dataset||{}))).time_24hr&&void 0===k.defaultConfig.time_24hr&&(w.config.time_24hr=w.l10n.time_24hr),w.formatDate=b(w),w.parseDate=C({config:w.config,l10n:w.l10n})}function ce(e){if(void 0!==w.calendarContainer){pe(\"onPreCalendarPosition\");var n=e||w._positionElement,t=Array.prototype.reduce.call(w.calendarContainer.children,(function(e,n){return e+n.offsetHeight}),0),a=w.calendarContainer.offsetWidth,i=w.config.position.split(\" \"),o=i[0],r=i.length>1?i[1]:null,l=n.getBoundingClientRect(),c=window.innerHeight-l.bottom,s=\"above\"===o||\"below\"!==o&&ct,u=window.pageYOffset+l.top+(s?-t-2:n.offsetHeight+2);if(d(w.calendarContainer,\"arrowTop\",!s),d(w.calendarContainer,\"arrowBottom\",s),!w.config.inline){var f=window.pageXOffset+l.left,m=!1,g=!1;\"center\"===r?(f-=(a-l.width)/2,m=!0):\"right\"===r&&(f-=a-l.width,g=!0),d(w.calendarContainer,\"arrowLeft\",!m&&!g),d(w.calendarContainer,\"arrowCenter\",m),d(w.calendarContainer,\"arrowRight\",g);var p=window.document.body.offsetWidth-(window.pageXOffset+l.right),h=f+a>window.document.body.offsetWidth,v=p+a>window.document.body.offsetWidth;if(d(w.calendarContainer,\"rightMost\",h),!w.config.static)if(w.calendarContainer.style.top=u+\"px\",h)if(v){var D=function(){for(var e=null,n=0;nw.currentMonth+w.config.showMonths-1)&&\"range\"!==w.config.mode;if(w.selectedDateElem=t,\"single\"===w.config.mode)w.selectedDates=[a];else if(\"multiple\"===w.config.mode){var o=ve(a);o?w.selectedDates.splice(parseInt(o),1):w.selectedDates.push(a)}else\"range\"===w.config.mode&&(2===w.selectedDates.length&&w.clear(!1,!1),w.latestSelectedDateObj=a,w.selectedDates.push(a),0!==M(a,w.selectedDates[0],!0)&&w.selectedDates.sort((function(e,n){return e.getTime()-n.getTime()})));if(I(),i){var r=w.currentYear!==a.getFullYear();w.currentYear=a.getFullYear(),w.currentMonth=a.getMonth(),r&&(pe(\"onYearChange\"),K()),pe(\"onMonthChange\")}if(De(),J(),be(),i||\"range\"===w.config.mode||1!==w.config.showMonths?void 0!==w.selectedDateElem&&void 0===w.hourElement&&w.selectedDateElem&&w.selectedDateElem.focus():L(t),void 0!==w.hourElement&&void 0!==w.hourElement&&w.hourElement.focus(),w.config.closeOnSelect){var l=\"single\"===w.config.mode&&!w.config.enableTime,c=\"range\"===w.config.mode&&2===w.selectedDates.length&&!w.config.enableTime;(l||c)&&se()}A()}}w.parseDate=C({config:w.config,l10n:w.l10n}),w._handlers=[],w.pluginElements=[],w.loadedPlugins=[],w._bind=N,w._setHoursFromDate=S,w._positionCalendar=ce,w.changeMonth=G,w.changeYear=Q,w.clear=function(e,n){if(void 0===e&&(e=!0),void 0===n&&(n=!0),w.input.value=\"\",void 0!==w.altInput&&(w.altInput.value=\"\"),void 0!==w.mobileInput&&(w.mobileInput.value=\"\"),w.selectedDates=[],w.latestSelectedDateObj=void 0,!0===n&&(w.currentYear=w._initialDate.getFullYear(),w.currentMonth=w._initialDate.getMonth()),!0===w.config.enableTime){var t=_(),a=t.hours,i=t.minutes,o=t.seconds;O(a,i,o)}w.redraw(),e&&pe(\"onChange\")},w.close=function(){w.isOpen=!1,w.isMobile||(void 0!==w.calendarContainer&&w.calendarContainer.classList.remove(\"open\"),void 0!==w._input&&w._input.classList.remove(\"active\")),pe(\"onClose\")},w._createElement=s,w.destroy=function(){void 0!==w.config&&pe(\"onDestroy\");for(var e=w._handlers.length;e--;){var n=w._handlers[e];n.element.removeEventListener(n.event,n.handler,n.options)}if(w._handlers=[],w.mobileInput)w.mobileInput.parentNode&&w.mobileInput.parentNode.removeChild(w.mobileInput),w.mobileInput=void 0;else if(w.calendarContainer&&w.calendarContainer.parentNode)if(w.config.static&&w.calendarContainer.parentNode){var t=w.calendarContainer.parentNode;if(t.lastChild&&t.removeChild(t.lastChild),t.parentNode){for(;t.firstChild;)t.parentNode.insertBefore(t.firstChild,t);t.parentNode.removeChild(t)}}else w.calendarContainer.parentNode.removeChild(w.calendarContainer);w.altInput&&(w.input.type=\"text\",w.altInput.parentNode&&w.altInput.parentNode.removeChild(w.altInput),delete w.altInput),w.input&&(w.input.type=w.input._type,w.input.classList.remove(\"flatpickr-input\"),w.input.removeAttribute(\"readonly\")),[\"_showTimeInput\",\"latestSelectedDateObj\",\"_hideNextMonthArrow\",\"_hidePrevMonthArrow\",\"__hideNextMonthArrow\",\"__hidePrevMonthArrow\",\"isMobile\",\"isOpen\",\"selectedDateElem\",\"minDateHasTime\",\"maxDateHasTime\",\"days\",\"daysContainer\",\"_input\",\"_positionElement\",\"innerContainer\",\"rContainer\",\"monthNav\",\"todayDateElem\",\"calendarContainer\",\"weekdayContainer\",\"prevMonthNav\",\"nextMonthNav\",\"monthsDropdownContainer\",\"currentMonthElement\",\"currentYearElement\",\"navigationCurrentMonth\",\"selectedDateElem\",\"config\"].forEach((function(e){try{delete w[e]}catch(e){}}))},w.isEnabled=X,w.jumpToDate=P,w.open=function(e,n){if(void 0===n&&(n=w._positionElement),!0===w.isMobile){if(e){e.preventDefault();var t=g(e);t&&t.blur()}return void 0!==w.mobileInput&&(w.mobileInput.focus(),w.mobileInput.click()),void pe(\"onOpen\")}if(!w._input.disabled&&!w.config.inline){var a=w.isOpen;w.isOpen=!0,a||(w.calendarContainer.classList.add(\"open\"),w._input.classList.add(\"active\"),pe(\"onOpen\"),ce(n)),!0===w.config.enableTime&&!0===w.config.noCalendar&&(!1!==w.config.allowInput||void 0!==e&&w.timeContainer.contains(e.relatedTarget)||setTimeout((function(){return w.hourElement.select()}),50))}},w.redraw=de,w.set=function(e,n){if(null!==e&&\"object\"==typeof e)for(var a in Object.assign(w.config,e),e)void 0!==fe[a]&&fe[a].forEach((function(e){return e()}));else w.config[e]=n,void 0!==fe[e]?fe[e].forEach((function(e){return e()})):t.indexOf(e)>-1&&(w.config[e]=c(n));w.redraw(),be(!0)},w.setDate=function(e,n,t){if(void 0===n&&(n=!1),void 0===t&&(t=w.config.dateFormat),0!==e&&!e||e instanceof Array&&0===e.length)return w.clear(n);me(e,t),w.latestSelectedDateObj=w.selectedDates[w.selectedDates.length-1],w.redraw(),P(void 0,n),S(),0===w.selectedDates.length&&w.clear(!1),be(n),n&&pe(\"onChange\")},w.toggle=function(e){if(!0===w.isOpen)return w.close();w.open(e)};var fe={locale:[le,z],showMonths:[q,E,$],minDate:[P],maxDate:[P]};function me(e,n){var t=[];if(e instanceof Array)t=e.map((function(e){return w.parseDate(e,n)}));else if(e instanceof Date||\"number\"==typeof e)t=[w.parseDate(e,n)];else if(\"string\"==typeof e)switch(w.config.mode){case\"single\":case\"time\":t=[w.parseDate(e,n)];break;case\"multiple\":t=e.split(w.config.conjunction).map((function(e){return w.parseDate(e,n)}));break;case\"range\":t=e.split(w.l10n.rangeSeparator).map((function(e){return w.parseDate(e,n)}))}else w.config.errorHandler(new Error(\"Invalid date supplied: \"+JSON.stringify(e)));w.selectedDates=w.config.allowInvalidPreload?t:t.filter((function(e){return e instanceof Date&&X(e,!1)})),\"range\"===w.config.mode&&w.selectedDates.sort((function(e,n){return e.getTime()-n.getTime()}))}function ge(e){return e.slice().map((function(e){return\"string\"==typeof e||\"number\"==typeof e||e instanceof Date?w.parseDate(e,void 0,!0):e&&\"object\"==typeof e&&e.from&&e.to?{from:w.parseDate(e.from,void 0),to:w.parseDate(e.to,void 0)}:e})).filter((function(e){return e}))}function pe(e,n){if(void 0!==w.config){var t=w.config[e];if(void 0!==t&&t.length>0)for(var a=0;t[a]&&a1||\"static\"===w.config.monthSelectorType?w.monthElements[n].textContent=h(t.getMonth(),w.config.shorthandCurrentMonth,w.l10n)+\" \":w.monthsDropdownContainer.value=t.getMonth().toString(),e.value=t.getFullYear().toString()})),w._hidePrevMonthArrow=void 0!==w.config.minDate&&(w.currentYear===w.config.minDate.getFullYear()?w.currentMonth<=w.config.minDate.getMonth():w.currentYearw.config.maxDate.getMonth():w.currentYear>w.config.maxDate.getFullYear()))}function we(e){return w.selectedDates.map((function(n){return w.formatDate(n,e)})).filter((function(e,n,t){return\"range\"!==w.config.mode||w.config.enableTime||t.indexOf(e)===n})).join(\"range\"!==w.config.mode?w.config.conjunction:w.l10n.rangeSeparator)}function be(e){void 0===e&&(e=!0),void 0!==w.mobileInput&&w.mobileFormatStr&&(w.mobileInput.value=void 0!==w.latestSelectedDateObj?w.formatDate(w.latestSelectedDateObj,w.mobileFormatStr):\"\"),w.input.value=we(w.config.dateFormat),void 0!==w.altInput&&(w.altInput.value=we(w.config.altFormat)),!1!==e&&pe(\"onValueUpdate\")}function Ce(e){var n=g(e),t=w.prevMonthNav.contains(n),a=w.nextMonthNav.contains(n);t||a?G(t?-1:1):w.yearElements.indexOf(n)>=0?n.select():n.classList.contains(\"arrowUp\")?w.changeYear(w.currentYear+1):n.classList.contains(\"arrowDown\")&&w.changeYear(w.currentYear-1)}return function(){w.element=w.input=p,w.isOpen=!1,function(){var n=[\"wrap\",\"weekNumbers\",\"allowInput\",\"allowInvalidPreload\",\"clickOpens\",\"time_24hr\",\"enableTime\",\"noCalendar\",\"altInput\",\"shorthandCurrentMonth\",\"inline\",\"static\",\"enableSeconds\",\"disableMobile\"],i=e(e({},JSON.parse(JSON.stringify(p.dataset||{}))),v),o={};w.config.parseDate=i.parseDate,w.config.formatDate=i.formatDate,Object.defineProperty(w.config,\"enable\",{get:function(){return w.config._enable},set:function(e){w.config._enable=ge(e)}}),Object.defineProperty(w.config,\"disable\",{get:function(){return w.config._disable},set:function(e){w.config._disable=ge(e)}});var r=\"time\"===i.mode;if(!i.dateFormat&&(i.enableTime||r)){var l=k.defaultConfig.dateFormat||a.dateFormat;o.dateFormat=i.noCalendar||r?\"H:i\"+(i.enableSeconds?\":S\":\"\"):l+\" H:i\"+(i.enableSeconds?\":S\":\"\")}if(i.altInput&&(i.enableTime||r)&&!i.altFormat){var d=k.defaultConfig.altFormat||a.altFormat;o.altFormat=i.noCalendar||r?\"h:i\"+(i.enableSeconds?\":S K\":\" K\"):d+\" h:i\"+(i.enableSeconds?\":S\":\"\")+\" K\"}Object.defineProperty(w.config,\"minDate\",{get:function(){return w.config._minDate},set:oe(\"min\")}),Object.defineProperty(w.config,\"maxDate\",{get:function(){return w.config._maxDate},set:oe(\"max\")});var s=function(e){return function(n){w.config[\"min\"===e?\"_minTime\":\"_maxTime\"]=w.parseDate(n,\"H:i:S\")}};Object.defineProperty(w.config,\"minTime\",{get:function(){return w.config._minTime},set:s(\"min\")}),Object.defineProperty(w.config,\"maxTime\",{get:function(){return w.config._maxTime},set:s(\"max\")}),\"time\"===i.mode&&(w.config.noCalendar=!0,w.config.enableTime=!0),Object.assign(w.config,o,i);for(var u=0;u-1?w.config[m]=c(f[m]).map(x).concat(w.config[m]):void 0===i[m]&&(w.config[m]=f[m])}i.altInputClass||(w.config.altInputClass=re().className+\" \"+w.config.altInputClass),pe(\"onParseConfig\")}(),le(),w.input=re(),w.input?(w.input._type=w.input.type,w.input.type=\"text\",w.input.classList.add(\"flatpickr-input\"),w._input=w.input,w.config.altInput&&(w.altInput=s(w.input.nodeName,w.config.altInputClass),w._input=w.altInput,w.altInput.placeholder=w.input.placeholder,w.altInput.disabled=w.input.disabled,w.altInput.required=w.input.required,w.altInput.tabIndex=w.input.tabIndex,w.altInput.type=\"text\",w.input.setAttribute(\"type\",\"hidden\"),!w.config.static&&w.input.parentNode&&w.input.parentNode.insertBefore(w.altInput,w.input.nextSibling)),w.config.allowInput||w._input.setAttribute(\"readonly\",\"readonly\"),w._positionElement=w.config.positionElement||w._input):w.config.errorHandler(new Error(\"Invalid input element specified\")),function(){w.selectedDates=[],w.now=w.parseDate(w.config.now)||new Date;var e=w.config.defaultDate||(\"INPUT\"!==w.input.nodeName&&\"TEXTAREA\"!==w.input.nodeName||!w.input.placeholder||w.input.value!==w.input.placeholder?w.input.value:null);e&&me(e,w.config.dateFormat),w._initialDate=w.selectedDates.length>0?w.selectedDates[0]:w.config.minDate&&w.config.minDate.getTime()>w.now.getTime()?w.config.minDate:w.config.maxDate&&w.config.maxDate.getTime()0&&(w.latestSelectedDateObj=w.selectedDates[0]),void 0!==w.config.minTime&&(w.config.minTime=w.parseDate(w.config.minTime,\"H:i\")),void 0!==w.config.maxTime&&(w.config.maxTime=w.parseDate(w.config.maxTime,\"H:i\")),w.minDateHasTime=!!w.config.minDate&&(w.config.minDate.getHours()>0||w.config.minDate.getMinutes()>0||w.config.minDate.getSeconds()>0),w.maxDateHasTime=!!w.config.maxDate&&(w.config.maxDate.getHours()>0||w.config.maxDate.getMinutes()>0||w.config.maxDate.getSeconds()>0)}(),w.utils={getDaysInMonth:function(e,n){return void 0===e&&(e=w.currentMonth),void 0===n&&(n=w.currentYear),1===e&&(n%4==0&&n%100!=0||n%400==0)?29:w.l10n.daysInMonth[e]}},w.isMobile||function(){var e=window.document.createDocumentFragment();if(w.calendarContainer=s(\"div\",\"flatpickr-calendar\"),w.calendarContainer.tabIndex=-1,!w.config.noCalendar){if(e.appendChild((w.monthNav=s(\"div\",\"flatpickr-months\"),w.yearElements=[],w.monthElements=[],w.prevMonthNav=s(\"span\",\"flatpickr-prev-month\"),w.prevMonthNav.innerHTML=w.config.prevArrow,w.nextMonthNav=s(\"span\",\"flatpickr-next-month\"),w.nextMonthNav.innerHTML=w.config.nextArrow,q(),Object.defineProperty(w,\"_hidePrevMonthArrow\",{get:function(){return w.__hidePrevMonthArrow},set:function(e){w.__hidePrevMonthArrow!==e&&(d(w.prevMonthNav,\"flatpickr-disabled\",e),w.__hidePrevMonthArrow=e)}}),Object.defineProperty(w,\"_hideNextMonthArrow\",{get:function(){return w.__hideNextMonthArrow},set:function(e){w.__hideNextMonthArrow!==e&&(d(w.nextMonthNav,\"flatpickr-disabled\",e),w.__hideNextMonthArrow=e)}}),w.currentYearElement=w.yearElements[0],De(),w.monthNav)),w.innerContainer=s(\"div\",\"flatpickr-innerContainer\"),w.config.weekNumbers){var n=function(){w.calendarContainer.classList.add(\"hasWeeks\");var e=s(\"div\",\"flatpickr-weekwrapper\");e.appendChild(s(\"span\",\"flatpickr-weekday\",w.l10n.weekAbbreviation));var n=s(\"div\",\"flatpickr-weeks\");return e.appendChild(n),{weekWrapper:e,weekNumbers:n}}(),t=n.weekWrapper,a=n.weekNumbers;w.innerContainer.appendChild(t),w.weekNumbers=a,w.weekWrapper=t}w.rContainer=s(\"div\",\"flatpickr-rContainer\"),w.rContainer.appendChild($()),w.daysContainer||(w.daysContainer=s(\"div\",\"flatpickr-days\"),w.daysContainer.tabIndex=-1),J(),w.rContainer.appendChild(w.daysContainer),w.innerContainer.appendChild(w.rContainer),e.appendChild(w.innerContainer)}w.config.enableTime&&e.appendChild(function(){w.calendarContainer.classList.add(\"hasTime\"),w.config.noCalendar&&w.calendarContainer.classList.add(\"noCalendar\"),w.timeContainer=s(\"div\",\"flatpickr-time\"),w.timeContainer.tabIndex=-1;var e=s(\"span\",\"flatpickr-time-separator\",\":\"),n=m(\"flatpickr-hour\",{\"aria-label\":w.l10n.hourAriaLabel});w.hourElement=n.getElementsByTagName(\"input\")[0];var t=m(\"flatpickr-minute\",{\"aria-label\":w.l10n.minuteAriaLabel});if(w.minuteElement=t.getElementsByTagName(\"input\")[0],w.hourElement.tabIndex=w.minuteElement.tabIndex=-1,w.hourElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getHours():w.config.time_24hr?w.config.defaultHour:function(e){switch(e%24){case 0:case 12:return 12;default:return e%12}}(w.config.defaultHour)),w.minuteElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getMinutes():w.config.defaultMinute),w.hourElement.setAttribute(\"step\",w.config.hourIncrement.toString()),w.minuteElement.setAttribute(\"step\",w.config.minuteIncrement.toString()),w.hourElement.setAttribute(\"min\",w.config.time_24hr?\"0\":\"1\"),w.hourElement.setAttribute(\"max\",w.config.time_24hr?\"23\":\"12\"),w.minuteElement.setAttribute(\"min\",\"0\"),w.minuteElement.setAttribute(\"max\",\"59\"),w.timeContainer.appendChild(n),w.timeContainer.appendChild(e),w.timeContainer.appendChild(t),w.config.time_24hr&&w.timeContainer.classList.add(\"time24hr\"),w.config.enableSeconds){w.timeContainer.classList.add(\"hasSeconds\");var a=m(\"flatpickr-second\");w.secondElement=a.getElementsByTagName(\"input\")[0],w.secondElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getSeconds():w.config.defaultSeconds),w.secondElement.setAttribute(\"step\",w.minuteElement.getAttribute(\"step\")),w.secondElement.setAttribute(\"min\",\"0\"),w.secondElement.setAttribute(\"max\",\"59\"),w.timeContainer.appendChild(s(\"span\",\"flatpickr-time-separator\",\":\")),w.timeContainer.appendChild(a)}return w.config.time_24hr||(w.amPM=s(\"span\",\"flatpickr-am-pm\",w.l10n.amPM[r((w.latestSelectedDateObj?w.hourElement.value:w.config.defaultHour)>11)]),w.amPM.title=w.l10n.toggleTitle,w.amPM.tabIndex=-1,w.timeContainer.appendChild(w.amPM)),w.timeContainer}()),d(w.calendarContainer,\"rangeMode\",\"range\"===w.config.mode),d(w.calendarContainer,\"animate\",!0===w.config.animate),d(w.calendarContainer,\"multiMonth\",w.config.showMonths>1),w.calendarContainer.appendChild(e);var i=void 0!==w.config.appendTo&&void 0!==w.config.appendTo.nodeType;if((w.config.inline||w.config.static)&&(w.calendarContainer.classList.add(w.config.inline?\"inline\":\"static\"),w.config.inline&&(!i&&w.element.parentNode?w.element.parentNode.insertBefore(w.calendarContainer,w._input.nextSibling):void 0!==w.config.appendTo&&w.config.appendTo.appendChild(w.calendarContainer)),w.config.static)){var l=s(\"div\",\"flatpickr-wrapper\");w.element.parentNode&&w.element.parentNode.insertBefore(l,w.element),l.appendChild(w.element),w.altInput&&l.appendChild(w.altInput),l.appendChild(w.calendarContainer)}w.config.static||w.config.inline||(void 0!==w.config.appendTo?w.config.appendTo:window.document.body).appendChild(w.calendarContainer)}(),function(){if(w.config.wrap&&[\"open\",\"close\",\"toggle\",\"clear\"].forEach((function(e){Array.prototype.forEach.call(w.element.querySelectorAll(\"[data-\"+e+\"]\"),(function(n){return N(n,\"click\",w[e])}))})),w.isMobile)!function(){var e=w.config.enableTime?w.config.noCalendar?\"time\":\"datetime-local\":\"date\";w.mobileInput=s(\"input\",w.input.className+\" flatpickr-mobile\"),w.mobileInput.tabIndex=1,w.mobileInput.type=e,w.mobileInput.disabled=w.input.disabled,w.mobileInput.required=w.input.required,w.mobileInput.placeholder=w.input.placeholder,w.mobileFormatStr=\"datetime-local\"===e?\"Y-m-d\\\\TH:i:S\":\"date\"===e?\"Y-m-d\":\"H:i:S\",w.selectedDates.length>0&&(w.mobileInput.defaultValue=w.mobileInput.value=w.formatDate(w.selectedDates[0],w.mobileFormatStr)),w.config.minDate&&(w.mobileInput.min=w.formatDate(w.config.minDate,\"Y-m-d\")),w.config.maxDate&&(w.mobileInput.max=w.formatDate(w.config.maxDate,\"Y-m-d\")),w.input.getAttribute(\"step\")&&(w.mobileInput.step=String(w.input.getAttribute(\"step\"))),w.input.type=\"hidden\",void 0!==w.altInput&&(w.altInput.type=\"hidden\");try{w.input.parentNode&&w.input.parentNode.insertBefore(w.mobileInput,w.input.nextSibling)}catch(e){}N(w.mobileInput,\"change\",(function(e){w.setDate(g(e).value,!1,w.mobileFormatStr),pe(\"onChange\"),pe(\"onClose\")}))}();else{var e=l(ie,50);if(w._debouncedChange=l(A,300),w.daysContainer&&!/iPhone|iPad|iPod/i.test(navigator.userAgent)&&N(w.daysContainer,\"mouseover\",(function(e){\"range\"===w.config.mode&&ae(g(e))})),N(window.document.body,\"keydown\",te),w.config.inline||w.config.static||N(window,\"resize\",e),void 0!==window.ontouchstart?N(window.document,\"touchstart\",Z):N(window.document,\"click\",Z),N(window.document,\"focus\",Z,{capture:!0}),!0===w.config.clickOpens&&(N(w._input,\"focus\",w.open),N(w._input,\"click\",w.open)),void 0!==w.daysContainer&&(N(w.monthNav,\"click\",Ce),N(w.monthNav,[\"keyup\",\"increment\"],F),N(w.daysContainer,\"click\",ue)),void 0!==w.timeContainer&&void 0!==w.minuteElement&&void 0!==w.hourElement){var n=function(e){return g(e).select()};N(w.timeContainer,[\"increment\"],T),N(w.timeContainer,\"blur\",T,{capture:!0}),N(w.timeContainer,\"click\",Y),N([w.hourElement,w.minuteElement],[\"focus\",\"click\"],n),void 0!==w.secondElement&&N(w.secondElement,\"focus\",(function(){return w.secondElement&&w.secondElement.select()})),void 0!==w.amPM&&N(w.amPM,\"click\",(function(e){T(e),A()}))}w.config.allowInput&&N(w._input,\"blur\",ne)}}(),(w.selectedDates.length||w.config.noCalendar)&&(w.config.enableTime&&S(w.config.noCalendar?w.latestSelectedDateObj||w.config.minDate:void 0),be(!1)),E();var n=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);!w.isMobile&&n&&ce(),pe(\"onReady\")}(),w}function E(e,n){for(var t=Array.prototype.slice.call(e).filter((function(e){return e instanceof HTMLElement})),a=[],i=0;ithis.render()));const{start:s,end:l,value:o,step:r,title:n}=this.model.properties;this.on_change([s,l,o,r],(()=>{const{start:t,end:e,value:i,step:s}=this._calc_to();this._noUiSlider.updateOptions({range:{min:t,max:e},start:i,step:s},!0)}));const{bar_color:a}=this.model.properties;this.on_change(a,(()=>{this._set_bar_color()}));const{show_value:d}=this.model.properties;this.on_change([o,n,d],(()=>this._update_title()))}styles(){return[...super.styles(),p.default,u.default]}_update_title(){var t;(0,a.empty)(this.title_el);const e=null==this.model.title||0==this.model.title.length&&!this.model.show_value;if(this.title_el.style.display=e?\"none\":\"\",!e&&(0!=(null===(t=this.model.title)||void 0===t?void 0:t.length)&&(this.title_el.textContent=`${this.model.title}: `),this.model.show_value)){const{value:t}=this._calc_to(),e=t.map((t=>this.model.pretty(t))).join(\" .. \");this.title_el.appendChild((0,a.span)({class:m.slider_value},e))}}_set_bar_color(){if(!this.model.disabled){this.slider_el.querySelector(\".noUi-connect\").style.backgroundColor=(0,_.color2css)(this.model.bar_color)}}render(){super.render();const{start:t,end:e,value:i,step:s}=this._calc_to();let l;if(this.model.tooltips){const t={to:t=>this.model.pretty(t)};l=(0,d.repeat)(t,i.length)}else l=!1;if(null==this.slider_el){this.slider_el=(0,a.div)(),this._noUiSlider=n.default.create(this.slider_el,{range:{min:t,max:e},start:i,step:s,behaviour:this.model.behaviour,connect:this.model.connected,tooltips:l,orientation:this.model.orientation,direction:this.model.direction}),this._noUiSlider.on(\"slide\",((t,e,i)=>this._slide(i))),this._noUiSlider.on(\"change\",((t,e,i)=>this._change(i)));const o=(t,e)=>{if(!l)return;this.slider_el.querySelectorAll(\".noUi-handle\")[t].querySelector(\".noUi-tooltip\").style.display=e?\"block\":\"\"};this._noUiSlider.on(\"start\",((t,e)=>o(e,!0))),this._noUiSlider.on(\"end\",((t,e)=>o(e,!1)))}else this._noUiSlider.updateOptions({range:{min:t,max:e},start:i,step:s},!0);this._set_bar_color(),this.model.disabled?this.slider_el.setAttribute(\"disabled\",\"true\"):this.slider_el.removeAttribute(\"disabled\"),this.title_el=(0,a.div)({class:m.slider_title}),this._update_title(),this.group_el=(0,a.div)({class:v.input_group},this.title_el,this.slider_el),this.el.appendChild(this.group_el)}_slide(t){this.model.value=this._calc_from(t)}_change(t){const e=this._calc_from(t);this.model.setv({value:e,value_throttled:e})}}b.__name__=\"AbstractBaseSliderView\";class g extends b{_calc_to(){return{start:this.model.start,end:this.model.end,value:[this.model.value],step:this.model.step}}_calc_from([t]){return Number.isInteger(this.model.start)&&Number.isInteger(this.model.end)&&Number.isInteger(this.model.step)?Math.round(t):t}}i.AbstractSliderView=g,g.__name__=\"AbstractSliderView\";class f extends b{_calc_to(){return{start:this.model.start,end:this.model.end,value:this.model.value,step:this.model.step}}_calc_from(t){return t}}i.AbstractRangeSliderView=f,f.__name__=\"AbstractRangeSliderView\";class S extends h.OrientedControl{constructor(t){super(t),this.connected=!1}pretty(t){return this._formatter(t,this.format)}}i.AbstractSlider=S,r=S,S.__name__=\"AbstractSlider\",r.define((({Any:t,Boolean:e,Number:i,String:s,Color:l,Or:o,Enum:r,Ref:n,Nullable:a})=>({title:[a(s),\"\"],show_value:[e,!0],start:[t],end:[t],value:[t],value_throttled:[t],step:[i,1],format:[o(s,n(c.TickFormatter))],direction:[r(\"ltr\",\"rtl\"),\"ltr\"],tooltips:[e,!0],bar_color:[l,\"#e6e6e6\"]})))},\n", - " 462: function _(t,e,r,n,i){var o,s;o=this,s=function(t){\"use strict\";var e,r;function n(t){return\"object\"==typeof t&&\"function\"==typeof t.to}function i(t){t.parentElement.removeChild(t)}function o(t){return null!=t}function s(t){t.preventDefault()}function a(t){return\"number\"==typeof t&&!isNaN(t)&&isFinite(t)}function l(t,e,r){r>0&&(f(t,e),setTimeout((function(){d(t,e)}),r))}function u(t){return Math.max(Math.min(t,100),0)}function c(t){return Array.isArray(t)?t:[t]}function p(t){var e=(t=String(t)).split(\".\");return e.length>1?e[1].length:0}function f(t,e){t.classList&&!/\\s/.test(e)?t.classList.add(e):t.className+=\" \"+e}function d(t,e){t.classList&&!/\\s/.test(e)?t.classList.remove(e):t.className=t.className.replace(new RegExp(\"(^|\\\\b)\"+e.split(\" \").join(\"|\")+\"(\\\\b|$)\",\"gi\"),\" \")}function h(t){var e=void 0!==window.pageXOffset,r=\"CSS1Compat\"===(t.compatMode||\"\");return{x:e?window.pageXOffset:r?t.documentElement.scrollLeft:t.body.scrollLeft,y:e?window.pageYOffset:r?t.documentElement.scrollTop:t.body.scrollTop}}function m(t,e){return 100/(e-t)}function g(t,e,r){return 100*e/(t[r+1]-t[r])}function v(t,e){for(var r=1;t>=e[r];)r+=1;return r}function b(t,e,r){if(r>=t.slice(-1)[0])return 100;var n=v(r,t),i=t[n-1],o=t[n],s=e[n-1],a=e[n];return s+function(t,e){return g(t,t[0]<0?e+Math.abs(t[0]):e-t[0],0)}([i,o],r)/m(s,a)}function S(t,e,r,n){if(100===n)return n;var i=v(n,t),o=t[i-1],s=t[i];return r?n-o>(s-o)/2?s:o:e[i-1]?t[i-1]+function(t,e){return Math.round(t/e)*e}(n-t[i-1],e[i-1]):n}t.PipsMode=void 0,(e=t.PipsMode||(t.PipsMode={})).Range=\"range\",e.Steps=\"steps\",e.Positions=\"positions\",e.Count=\"count\",e.Values=\"values\",t.PipsType=void 0,(r=t.PipsType||(t.PipsType={}))[r.None=-1]=\"None\",r[r.NoValue=0]=\"NoValue\",r[r.LargeValue=1]=\"LargeValue\",r[r.SmallValue=2]=\"SmallValue\";var x=function(){function t(t,e,r){var n;this.xPct=[],this.xVal=[],this.xSteps=[],this.xNumSteps=[],this.xHighestCompleteStep=[],this.xSteps=[r||!1],this.xNumSteps=[!1],this.snap=e;var i=[];for(Object.keys(t).forEach((function(e){i.push([c(t[e]),e])})),i.sort((function(t,e){return t[0][0]-e[0][0]})),n=0;nthis.xPct[i+1];)i++;else t===this.xPct[this.xPct.length-1]&&(i=this.xPct.length-2);r||t!==this.xPct[i+1]||i++,null===e&&(e=[]);var o=1,s=e[i],a=0,l=0,u=0,c=0;for(n=r?(t-this.xPct[i])/(this.xPct[i+1]-this.xPct[i]):(this.xPct[i+1]-t)/(this.xPct[i+1]-this.xPct[i]);s>0;)a=this.xPct[i+1+c]-this.xPct[i+c],e[i+c]*o+100-100*n>100?(l=a*n,o=(s-100*n)/e[i+c],n=1):(l=e[i+c]*a/100*o,o=0),r?(u-=l,this.xPct.length+c>=1&&c--):(u+=l,this.xPct.length-c>=1&&c++),s=e[i+c]*o;return t+u},t.prototype.toStepping=function(t){return t=b(this.xVal,this.xPct,t)},t.prototype.fromStepping=function(t){return function(t,e,r){if(r>=100)return t.slice(-1)[0];var n=v(r,e),i=t[n-1],o=t[n],s=e[n-1];return function(t,e){return e*(t[1]-t[0])/100+t[0]}([i,o],(r-s)*m(s,e[n]))}(this.xVal,this.xPct,t)},t.prototype.getStep=function(t){return t=S(this.xPct,this.xSteps,this.snap,t)},t.prototype.getDefaultStep=function(t,e,r){var n=v(t,this.xPct);return(100===t||e&&t===this.xPct[n-1])&&(n=Math.max(n-1,1)),(this.xVal[n]-this.xVal[n-1])/r},t.prototype.getNearbySteps=function(t){var e=v(t,this.xPct);return{stepBefore:{startValue:this.xVal[e-2],step:this.xNumSteps[e-2],highestStep:this.xHighestCompleteStep[e-2]},thisStep:{startValue:this.xVal[e-1],step:this.xNumSteps[e-1],highestStep:this.xHighestCompleteStep[e-1]},stepAfter:{startValue:this.xVal[e],step:this.xNumSteps[e],highestStep:this.xHighestCompleteStep[e]}}},t.prototype.countStepDecimals=function(){var t=this.xNumSteps.map(p);return Math.max.apply(null,t)},t.prototype.hasNoSize=function(){return this.xVal[0]===this.xVal[this.xVal.length-1]},t.prototype.convert=function(t){return this.getStep(this.toStepping(t))},t.prototype.handleEntryPoint=function(t,e){var r;if(!a(r=\"min\"===t?0:\"max\"===t?100:parseFloat(t))||!a(e[0]))throw new Error(\"noUiSlider: 'range' value isn't numeric.\");this.xPct.push(r),this.xVal.push(e[0]);var n=Number(e[1]);r?this.xSteps.push(!isNaN(n)&&n):isNaN(n)||(this.xSteps[0]=n),this.xHighestCompleteStep.push(0)},t.prototype.handleStepPoint=function(t,e){if(e)if(this.xVal[t]!==this.xVal[t+1]){this.xSteps[t]=g([this.xVal[t],this.xVal[t+1]],e,0)/m(this.xPct[t],this.xPct[t+1]);var r=(this.xVal[t+1]-this.xVal[t])/this.xNumSteps[t],n=Math.ceil(Number(r.toFixed(3))-1),i=this.xVal[t]+this.xNumSteps[t]*n;this.xHighestCompleteStep[t]=i}else this.xSteps[t]=this.xHighestCompleteStep[t]=this.xVal[t]},t}(),y={to:function(t){return void 0===t?\"\":t.toFixed(2)},from:Number},w={target:\"target\",base:\"base\",origin:\"origin\",handle:\"handle\",handleLower:\"handle-lower\",handleUpper:\"handle-upper\",touchArea:\"touch-area\",horizontal:\"horizontal\",vertical:\"vertical\",background:\"background\",connect:\"connect\",connects:\"connects\",ltr:\"ltr\",rtl:\"rtl\",textDirectionLtr:\"txt-dir-ltr\",textDirectionRtl:\"txt-dir-rtl\",draggable:\"draggable\",drag:\"state-drag\",tap:\"state-tap\",active:\"active\",tooltip:\"tooltip\",pips:\"pips\",pipsHorizontal:\"pips-horizontal\",pipsVertical:\"pips-vertical\",marker:\"marker\",markerHorizontal:\"marker-horizontal\",markerVertical:\"marker-vertical\",markerNormal:\"marker-normal\",markerLarge:\"marker-large\",markerSub:\"marker-sub\",value:\"value\",valueHorizontal:\"value-horizontal\",valueVertical:\"value-vertical\",valueNormal:\"value-normal\",valueLarge:\"value-large\",valueSub:\"value-sub\"},E=\".__tooltips\",P=\".__aria\";function C(t,e){if(!a(e))throw new Error(\"noUiSlider: 'step' is not numeric.\");t.singleStep=e}function N(t,e){if(!a(e))throw new Error(\"noUiSlider: 'keyboardPageMultiplier' is not numeric.\");t.keyboardPageMultiplier=e}function V(t,e){if(!a(e))throw new Error(\"noUiSlider: 'keyboardMultiplier' is not numeric.\");t.keyboardMultiplier=e}function k(t,e){if(!a(e))throw new Error(\"noUiSlider: 'keyboardDefaultStep' is not numeric.\");t.keyboardDefaultStep=e}function M(t,e){if(\"object\"!=typeof e||Array.isArray(e))throw new Error(\"noUiSlider: 'range' is not an object.\");if(void 0===e.min||void 0===e.max)throw new Error(\"noUiSlider: Missing 'min' or 'max' in 'range'.\");t.spectrum=new x(e,t.snap||!1,t.singleStep)}function A(t,e){if(e=c(e),!Array.isArray(e)||!e.length)throw new Error(\"noUiSlider: 'start' option is incorrect.\");t.handles=e.length,t.start=e}function U(t,e){if(\"boolean\"!=typeof e)throw new Error(\"noUiSlider: 'snap' option must be a boolean.\");t.snap=e}function D(t,e){if(\"boolean\"!=typeof e)throw new Error(\"noUiSlider: 'animate' option must be a boolean.\");t.animate=e}function O(t,e){if(\"number\"!=typeof e)throw new Error(\"noUiSlider: 'animationDuration' option must be a number.\");t.animationDuration=e}function L(t,e){var r,n=[!1];if(\"lower\"===e?e=[!0,!1]:\"upper\"===e&&(e=[!1,!0]),!0===e||!1===e){for(r=1;r1)throw new Error(\"noUiSlider: 'padding' option must not exceed 100% of the range.\")}}function F(t,e){switch(e){case\"ltr\":t.dir=0;break;case\"rtl\":t.dir=1;break;default:throw new Error(\"noUiSlider: 'direction' option was not recognized.\")}}function R(t,e){if(\"string\"!=typeof e)throw new Error(\"noUiSlider: 'behaviour' must be a string containing options.\");var r=e.indexOf(\"tap\")>=0,n=e.indexOf(\"drag\")>=0,i=e.indexOf(\"fixed\")>=0,o=e.indexOf(\"snap\")>=0,s=e.indexOf(\"hover\")>=0,a=e.indexOf(\"unconstrained\")>=0,l=e.indexOf(\"drag-all\")>=0;if(i){if(2!==t.handles)throw new Error(\"noUiSlider: 'fixed' behaviour must be used with 2 handles\");j(t,t.start[1]-t.start[0])}if(a&&(t.margin||t.limit))throw new Error(\"noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit\");t.events={tap:r||o,drag:n,dragAll:l,fixed:i,snap:o,hover:s,unconstrained:a}}function _(t,e){if(!1!==e)if(!0===e||n(e)){t.tooltips=[];for(var r=0;r= 2) required for mode 'count'.\");for(var r=e.values-1,n=100/r,i=[];r--;)i[r]=r*n;return i.push(100),q(i,e.stepped)}return e.mode===t.PipsMode.Positions?q(e.values,e.stepped):e.mode===t.PipsMode.Values?e.stepped?e.values.map((function(t){return C.fromStepping(C.getStep(C.toStepping(t)))})):e.values:[]}(e),i={},o=C.xVal[0],s=C.xVal[C.xVal.length-1],a=!1,l=!1,u=0;return r=n.slice().sort((function(t,e){return t-e})),(n=r.filter((function(t){return!this[t]&&(this[t]=!0)}),{}))[0]!==o&&(n.unshift(o),a=!0),n[n.length-1]!==s&&(n.push(s),l=!0),n.forEach((function(r,o){var s,c,p,f,d,h,m,g,v,b,S=r,x=n[o+1],y=e.mode===t.PipsMode.Steps;for(y&&(s=C.xNumSteps[o]),s||(s=x-S),void 0===x&&(x=S),s=Math.max(s,1e-7),c=S;c<=x;c=Number((c+s).toFixed(7))){for(g=(d=(f=C.toStepping(c))-u)/(e.density||1),b=d/(v=Math.round(g)),p=1;p<=v;p+=1)i[(h=u+p*b).toFixed(5)]=[C.fromStepping(h),0];m=n.indexOf(c)>-1?t.PipsType.LargeValue:y?t.PipsType.SmallValue:t.PipsType.NoValue,!o&&a&&c!==x&&(m=0),c===x&&l||(i[f.toFixed(5)]=[c,m]),u=f}})),i}function Y(e,n,i){var o,s,a=U.createElement(\"div\"),l=((o={})[t.PipsType.None]=\"\",o[t.PipsType.NoValue]=r.cssClasses.valueNormal,o[t.PipsType.LargeValue]=r.cssClasses.valueLarge,o[t.PipsType.SmallValue]=r.cssClasses.valueSub,o),u=((s={})[t.PipsType.None]=\"\",s[t.PipsType.NoValue]=r.cssClasses.markerNormal,s[t.PipsType.LargeValue]=r.cssClasses.markerLarge,s[t.PipsType.SmallValue]=r.cssClasses.markerSub,s),c=[r.cssClasses.valueHorizontal,r.cssClasses.valueVertical],p=[r.cssClasses.markerHorizontal,r.cssClasses.markerVertical];function d(t,e){var n=e===r.cssClasses.value,i=n?l:u;return e+\" \"+(n?c:p)[r.ort]+\" \"+i[t]}return f(a,r.cssClasses.pips),f(a,0===r.ort?r.cssClasses.pipsHorizontal:r.cssClasses.pipsVertical),Object.keys(e).forEach((function(o){!function(e,o,s){if((s=n?n(o,s):s)!==t.PipsType.None){var l=T(a,!1);l.className=d(s,r.cssClasses.marker),l.style[r.style]=e+\"%\",s>t.PipsType.NoValue&&((l=T(a,!1)).className=d(s,r.cssClasses.value),l.setAttribute(\"data-value\",String(o)),l.style[r.style]=e+\"%\",l.innerHTML=String(i.to(o)))}}(o,e[o][0],e[o][1])})),a}function I(){g&&(i(g),g=null)}function W(t){I();var e=X(t),r=t.filter,n=t.format||{to:function(t){return String(Math.round(t))}};return g=w.appendChild(Y(e,r,n))}function $(){var t=a.getBoundingClientRect(),e=\"offset\"+[\"Width\",\"Height\"][r.ort];return 0===r.ort?t.width||a[e]:t.height||a[e]}function J(t,e,n,i){var o=function(o){var s,a,l=function(t,e,r){var n=0===t.type.indexOf(\"touch\"),i=0===t.type.indexOf(\"mouse\"),o=0===t.type.indexOf(\"pointer\"),s=0,a=0;if(0===t.type.indexOf(\"MSPointer\")&&(o=!0),\"mousedown\"===t.type&&!t.buttons&&!t.touches)return!1;if(n){var l=function(e){var n=e.target;return n===r||r.contains(n)||t.composed&&t.composedPath().shift()===r};if(\"touchstart\"===t.type){var u=Array.prototype.filter.call(t.touches,l);if(u.length>1)return!1;s=u[0].pageX,a=u[0].pageY}else{var c=Array.prototype.find.call(t.changedTouches,l);if(!c)return!1;s=c.pageX,a=c.pageY}}return e=e||h(U),(i||o)&&(s=t.clientX+e.x,a=t.clientY+e.y),t.pageOffset=e,t.points=[s,a],t.cursor=i||o,t}(o,i.pageOffset,i.target||e);return!!l&&!(F()&&!i.doNotReject)&&(s=w,a=r.cssClasses.tap,!((s.classList?s.classList.contains(a):new RegExp(\"\\\\b\"+a+\"\\\\b\").test(s.className))&&!i.doNotReject)&&!(t===x.start&&void 0!==l.buttons&&l.buttons>1)&&(!i.hover||!l.buttons)&&(y||l.preventDefault(),l.calcPoint=l.points[r.ort],void n(l,i)))},s=[];return t.split(\" \").forEach((function(t){e.addEventListener(t,o,!!y&&{passive:!0}),s.push([t,o])})),s}function K(t){var e,n,i,o,s,l,c=100*(t-(e=a,n=r.ort,i=e.getBoundingClientRect(),o=e.ownerDocument,s=o.documentElement,l=h(o),/webkit.*Chrome.*Mobile/i.test(navigator.userAgent)&&(l.x=0),n?i.top+l.y-s.clientTop:i.left+l.x-s.clientLeft))/$();return c=u(c),r.dir?100-c:c}function Q(t,e){\"mouseout\"===t.type&&\"HTML\"===t.target.nodeName&&null===t.relatedTarget&&tt(t,e)}function Z(t,e){if(-1===navigator.appVersion.indexOf(\"MSIE 9\")&&0===t.buttons&&0!==e.buttonsProperty)return tt(t,e);var n=(r.dir?-1:1)*(t.calcPoint-e.startCalcPoint);ut(n>0,100*n/e.baseSize,e.locations,e.handleNumbers,e.connect)}function tt(t,e){e.handle&&(d(e.handle,r.cssClasses.active),M-=1),e.listeners.forEach((function(t){D.removeEventListener(t[0],t[1])})),0===M&&(d(w,r.cssClasses.drag),pt(),t.cursor&&(O.style.cursor=\"\",O.removeEventListener(\"selectstart\",s))),e.handleNumbers.forEach((function(t){st(\"change\",t),st(\"set\",t),st(\"end\",t)}))}function et(t,e){if(!e.handleNumbers.some(R)){var n;1===e.handleNumbers.length&&(n=p[e.handleNumbers[0]].children[0],M+=1,f(n,r.cssClasses.active)),t.stopPropagation();var i=[],o=J(x.move,D,Z,{target:t.target,handle:n,connect:e.connect,listeners:i,startCalcPoint:t.calcPoint,baseSize:$(),pageOffset:t.pageOffset,handleNumbers:e.handleNumbers,buttonsProperty:t.buttons,locations:V.slice()}),a=J(x.end,D,tt,{target:t.target,handle:n,listeners:i,doNotReject:!0,handleNumbers:e.handleNumbers}),l=J(\"mouseout\",D,Q,{target:t.target,handle:n,listeners:i,doNotReject:!0,handleNumbers:e.handleNumbers});i.push.apply(i,o.concat(a,l)),t.cursor&&(O.style.cursor=getComputedStyle(t.target).cursor,p.length>1&&f(w,r.cssClasses.drag),O.addEventListener(\"selectstart\",s,!1)),e.handleNumbers.forEach((function(t){st(\"start\",t)}))}}function rt(t){t.stopPropagation();var e=K(t.calcPoint),n=function(t){var e=100,r=!1;return p.forEach((function(n,i){if(!R(i)){var o=V[i],s=Math.abs(o-t);(so||100===s&&100===e)&&(r=i,e=s)}})),r}(e);!1!==n&&(r.events.snap||l(w,r.cssClasses.tap,r.animationDuration),ft(n,e,!0,!0),pt(),st(\"slide\",n,!0),st(\"update\",n,!0),r.events.snap?et(t,{handleNumbers:[n]}):(st(\"change\",n,!0),st(\"set\",n,!0)))}function nt(t){var e=K(t.calcPoint),r=C.getStep(e),n=C.fromStepping(r);Object.keys(A).forEach((function(t){\"hover\"===t.split(\".\")[0]&&A[t].forEach((function(t){t.call(bt,n)}))}))}function it(t,e){A[t]=A[t]||[],A[t].push(e),\"update\"===t.split(\".\")[0]&&p.forEach((function(t,e){st(\"update\",e)}))}function ot(t){var e=t&&t.split(\".\")[0],r=e?t.substring(e.length):t;Object.keys(A).forEach((function(t){var n=t.split(\".\")[0],i=t.substring(n.length);e&&e!==n||r&&r!==i||function(t){return t===P||t===E}(i)&&r!==i||delete A[t]}))}function st(t,e,n){Object.keys(A).forEach((function(i){var o=i.split(\".\")[0];t===o&&A[i].forEach((function(t){t.call(bt,N.map(r.format.to),e,N.slice(),n||!1,V.slice(),bt)}))}))}function at(t,e,n,i,o,s){var a;return p.length>1&&!r.events.unconstrained&&(i&&e>0&&(a=C.getAbsoluteDistance(t[e-1],r.margin,!1),n=Math.max(n,a)),o&&e1&&r.limit&&(i&&e>0&&(a=C.getAbsoluteDistance(t[e-1],r.limit,!1),n=Math.min(n,a)),o&&e1?n.forEach((function(t,r){var n=at(o,t,o[t]+e,a[r],l[r],!1);!1===n?e=0:(e=n-o[t],o[t]=n)})):a=l=[!0];var u=!1;n.forEach((function(t,n){u=ft(t,r[t]+e,a[n],l[n])||u})),u&&(n.forEach((function(t){st(\"update\",t),st(\"slide\",t)})),null!=i&&st(\"drag\",s))}function ct(t,e){return r.dir?100-t-e:t}function pt(){k.forEach((function(t){var e=V[t]>50?-1:1,r=3+(p.length+e*t);p[t].style.zIndex=String(r)}))}function ft(t,e,n,i,o){return o||(e=at(V,t,e,n,i,!1)),!1!==e&&(function(t,e){V[t]=e,N[t]=C.fromStepping(e);var n=\"translate(\"+lt(10*(ct(e,0)-L)+\"%\",\"0\")+\")\";p[t].style[r.transformRule]=n,dt(t),dt(t+1)}(t,e),!0)}function dt(t){if(m[t]){var e=0,n=100;0!==t&&(e=V[t-1]),t!==m.length-1&&(n=V[t]);var i=n-e,o=\"translate(\"+lt(ct(e,i)+\"%\",\"0\")+\")\",s=\"scale(\"+lt(i/100,\"1\")+\")\";m[t].style[r.transformRule]=o+\" \"+s}}function ht(t,e){return null===t||!1===t||void 0===t?V[e]:(\"number\"==typeof t&&(t=String(t)),!1!==(t=r.format.from(t))&&(t=C.toStepping(t)),!1===t||isNaN(t)?V[e]:t)}function mt(t,e,n){var i=c(t),o=void 0===V[0];e=void 0===e||e,r.animate&&!o&&l(w,r.cssClasses.tap,r.animationDuration),k.forEach((function(t){ft(t,ht(i[t],t),!0,!1,n)}));var s=1===k.length?0:1;if(o&&C.hasNoSize()&&(n=!0,V[0]=0,k.length>1)){var a=100/(k.length-1);k.forEach((function(t){V[t]=t*a}))}for(;sn.stepAfter.startValue&&(o=n.stepAfter.startValue-i),s=i>n.thisStep.startValue?n.thisStep.step:!1!==n.stepBefore.step&&i-n.stepBefore.highestStep,100===e?o=null:0===e&&(s=null);var a=C.countStepDecimals();return null!==o&&!1!==o&&(o=Number(o.toFixed(a))),null!==s&&!1!==s&&(s=Number(s.toFixed(a))),[s,o]}f(b=w,r.cssClasses.target),0===r.dir?f(b,r.cssClasses.ltr):f(b,r.cssClasses.rtl),0===r.ort?f(b,r.cssClasses.horizontal):f(b,r.cssClasses.vertical),f(b,\"rtl\"===getComputedStyle(b).direction?r.cssClasses.textDirectionRtl:r.cssClasses.textDirectionLtr),a=T(b,r.cssClasses.base),function(t,e){var n=T(e,r.cssClasses.connects);p=[],(m=[]).push(z(n,t[0]));for(var i=0;i=0&&t .noUi-tooltip{-webkit-transform:translate(50%, 0);transform:translate(50%, 0);left:auto;bottom:10px;}.bk-root .noUi-vertical .noUi-origin > .noUi-tooltip{-webkit-transform:translate(0, -18px);transform:translate(0, -18px);top:auto;right:28px;}.bk-root .noUi-handle{cursor:grab;cursor:-webkit-grab;}.bk-root .noUi-handle.noUi-active{cursor:grabbing;cursor:-webkit-grabbing;}.bk-root .noUi-handle:after,.bk-root .noUi-handle:before{display:none;}.bk-root .noUi-tooltip{display:none;white-space:nowrap;}.bk-root .noUi-handle:hover .noUi-tooltip{display:block;}.bk-root .noUi-horizontal{width:100%;height:10px;}.bk-root .noUi-vertical{width:10px;height:100%;}.bk-root .noUi-horizontal .noUi-handle{width:14px;height:18px;right:-7px;top:-5px;}.bk-root .noUi-vertical .noUi-handle{width:18px;height:14px;right:-5px;top:-7px;}.bk-root .noUi-target.noUi-horizontal{margin:5px 0px;}.bk-root .noUi-target.noUi-vertical{margin:0px 5px;}'},\n", - " 465: function _(e,t,r,a,i){a();var s;const d=(0,e(1).__importDefault)(e(151)),o=e(461),_=e(8);class n extends o.AbstractSliderView{}r.DateSliderView=n,n.__name__=\"DateSliderView\";class c extends o.AbstractSlider{constructor(e){super(e),this.behaviour=\"tap\",this.connected=[!0,!1]}_formatter(e,t){return(0,_.isString)(t)?(0,d.default)(e,t):t.compute(e)}}r.DateSlider=c,s=c,c.__name__=\"DateSlider\",s.prototype.default_view=n,s.override({format:\"%d %b %Y\"})},\n", - " 466: function _(e,t,r,a,i){a();var n;const s=(0,e(1).__importDefault)(e(151)),d=e(461),o=e(8);class _ extends d.AbstractRangeSliderView{}r.DatetimeRangeSliderView=_,_.__name__=\"DatetimeRangeSliderView\";class c extends d.AbstractSlider{constructor(e){super(e),this.behaviour=\"drag\",this.connected=[!1,!0,!1]}_formatter(e,t){return(0,o.isString)(t)?(0,s.default)(e,t):t.compute(e)}}r.DatetimeRangeSlider=c,n=c,c.__name__=\"DatetimeRangeSlider\",n.prototype.default_view=_,n.override({format:\"%d %b %Y %H:%M:%S\",step:36e5})},\n", - " 467: function _(e,t,s,r,i){var _;r();const n=e(468);class a extends n.MarkupView{render(){super.render(),this.model.render_as_text?this.markup_el.textContent=this.model.text:this.markup_el.innerHTML=this.has_math_disabled()?this.model.text:this.process_tex()}}s.DivView=a,a.__name__=\"DivView\";class d extends n.Markup{constructor(e){super(e)}}s.Div=d,_=d,d.__name__=\"Div\",_.prototype.default_view=a,_.define((({Boolean:e})=>({render_as_text:[e,!1]})))},\n", - " 468: function _(t,e,s,i,r){i();const a=t(1);var n;const o=t(210),d=t(43),h=t(137),l=t(512),_=(0,a.__importStar)(t(469));class u extends l.WidgetView{get provider(){return h.default_provider}async lazy_initialize(){await super.lazy_initialize(),\"not_started\"==this.provider.status&&await this.provider.fetch(),\"not_started\"!=this.provider.status&&\"loading\"!=this.provider.status||this.provider.ready.connect((()=>{this.contains_tex_string()&&this.rerender()}))}after_layout(){super.after_layout(),\"loading\"===this.provider.status&&(this._has_finished=!1)}rerender(){this.layout.invalidate_cache(),this.render(),this.root.compute_layout()}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>{this.rerender()}))}styles(){return[...super.styles(),_.default]}_update_layout(){this.layout=new o.CachedVariadicBox(this.el),this.layout.set_sizing(this.box_sizing())}render(){super.render();const t=Object.assign(Object.assign({},this.model.style),{display:\"inline-block\"});this.markup_el=(0,d.div)({class:_.clearfix,style:t}),this.el.appendChild(this.markup_el),\"failed\"!=this.provider.status&&\"loaded\"!=this.provider.status||(this._has_finished=!0)}has_math_disabled(){return this.model.disable_math||!this.contains_tex_string()}process_tex(){if(!this.provider.MathJax)return this.model.text;const{text:t}=this.model,e=this.provider.MathJax.find_tex(t),s=[];let i=0;for(const r of e)s.push(t.slice(i,r.start.n)),s.push(this.provider.MathJax.tex2svg(r.math,{display:r.display}).outerHTML),i=r.end.n;return i0}}s.MarkupView=u,u.__name__=\"MarkupView\";class p extends l.Widget{constructor(t){super(t)}}s.Markup=p,n=p,p.__name__=\"Markup\",n.define((({Boolean:t,String:e,Dict:s})=>({text:[e,\"\"],style:[s(e),{}],disable_math:[t,!1]})))},\n", - " 469: function _(o,r,e,t,a){t(),e.root=\"bk-root\",e.clearfix=\"bk-clearfix\",e.default='.bk-root .bk-clearfix:before,.bk-root .bk-clearfix:after{content:\"\";display:table;}.bk-root .bk-clearfix:after{clear:both;}'},\n", - " 470: function _(e,t,i,n,s){n();const o=e(1);var l;const r=e(441),d=e(251),_=e(43),u=e(8),c=(0,o.__importStar)(e(318)),h=(0,o.__importStar)(e(229)),m=h;class p extends r.AbstractButtonView{constructor(){super(...arguments),this._open=!1}styles(){return[...super.styles(),h.default]}render(){super.render();const e=(0,_.div)({class:[m.caret,m.down]});if(this.model.is_split){const t=this._render_button(e);t.classList.add(c.dropdown_toggle),t.addEventListener(\"click\",(()=>this._toggle_menu())),this.group_el.appendChild(t)}else this.button_el.appendChild(e);const t=this.model.menu.map(((e,t)=>{if(null==e)return(0,_.div)({class:m.divider});{const i=(0,u.isString)(e)?e:e[0],n=(0,_.div)(i);return n.addEventListener(\"click\",(()=>this._item_click(t))),n}}));this.menu=(0,_.div)({class:[m.menu,m.below]},t),this.el.appendChild(this.menu),(0,_.undisplay)(this.menu)}_show_menu(){if(!this._open){this._open=!0,(0,_.display)(this.menu);const e=t=>{const{target:i}=t;i instanceof HTMLElement&&!this.el.contains(i)&&(document.removeEventListener(\"click\",e),this._hide_menu())};document.addEventListener(\"click\",e)}}_hide_menu(){this._open&&(this._open=!1,(0,_.undisplay)(this.menu))}_toggle_menu(){this._open?this._hide_menu():this._show_menu()}click(){this.model.is_split?(this._hide_menu(),this.model.trigger_event(new d.ButtonClick),super.click()):this._toggle_menu()}_item_click(e){this._hide_menu();const t=this.model.menu[e];if(null!=t){const i=(0,u.isString)(t)?t:t[1];(0,u.isString)(i)?this.model.trigger_event(new d.MenuItemClick(i)):i.execute(this.model,{index:e})}}}i.DropdownView=p,p.__name__=\"DropdownView\";class a extends r.AbstractButton{constructor(e){super(e)}get is_split(){return this.split}}i.Dropdown=a,l=a,a.__name__=\"Dropdown\",l.prototype.default_view=p,l.define((({Null:e,Boolean:t,String:i,Array:n,Tuple:s,Or:o})=>({split:[t,!1],menu:[n(o(i,s(i,o(i)),e)),[]]}))),l.override({label:\"Dropdown\"})},\n", - " 471: function _(e,l,i,t,s){var n;t();const a=e(43),o=e(512);class d extends o.WidgetView{connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.render()))}render(){const{multiple:e,accept:l,disabled:i,width:t}=this.model;null==this.dialog_el&&(this.dialog_el=(0,a.input)({type:\"file\",multiple:e}),this.dialog_el.onchange=()=>{const{files:e}=this.dialog_el;null!=e&&this.load_files(e)},this.el.appendChild(this.dialog_el)),null!=l&&\"\"!=l&&(this.dialog_el.accept=l),this.dialog_el.style.width=`${t}px`,this.dialog_el.disabled=i}async load_files(e){const l=[],i=[],t=[];for(const s of e){const e=await this._read_file(s),[,n=\"\",,a=\"\"]=e.split(/[:;,]/,4);l.push(a),i.push(s.name),t.push(n)}this.model.multiple?this.model.setv({value:l,filename:i,mime_type:t}):this.model.setv({value:l[0],filename:i[0],mime_type:t[0]})}_read_file(e){return new Promise(((l,i)=>{const t=new FileReader;t.onload=()=>{var s;const{result:n}=t;null!=n?l(n):i(null!==(s=t.error)&&void 0!==s?s:new Error(`unable to read '${e.name}'`))},t.readAsDataURL(e)}))}}i.FileInputView=d,d.__name__=\"FileInputView\";class r extends o.Widget{constructor(e){super(e)}}i.FileInput=r,n=r,r.__name__=\"FileInput\",n.prototype.default_view=d,n.define((({Boolean:e,String:l,Array:i,Or:t})=>({value:[t(l,i(l)),\"\"],mime_type:[t(l,i(l)),\"\"],filename:[t(l,i(l)),\"\"],accept:[l,\"\"],multiple:[e,!1]})))},\n", - " 472: function _(e,t,i,s,n){s();const l=e(1);var o;const r=e(43),c=e(8),h=e(448),p=(0,l.__importStar)(e(449));class d extends h.InputWidgetView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.value.change,(()=>this.render_selection())),this.connect(this.model.properties.options.change,(()=>this.render())),this.connect(this.model.properties.name.change,(()=>this.render())),this.connect(this.model.properties.title.change,(()=>this.render())),this.connect(this.model.properties.size.change,(()=>this.render())),this.connect(this.model.properties.disabled.change,(()=>this.render()))}render(){super.render();const e=this.model.options.map((e=>{let t,i;return(0,c.isString)(e)?t=i=e:[t,i]=e,(0,r.option)({value:t},i)}));this.input_el=(0,r.select)({multiple:!0,class:p.input,name:this.model.name,disabled:this.model.disabled},e),this.input_el.addEventListener(\"change\",(()=>this.change_input())),this.group_el.appendChild(this.input_el),this.render_selection()}render_selection(){const e=new Set(this.model.value);for(const t of this.el.querySelectorAll(\"option\"))t.selected=e.has(t.value);this.input_el.size=this.model.size}change_input(){const e=null!=this.el.querySelector(\"select:focus\"),t=[];for(const e of this.el.querySelectorAll(\"option\"))e.selected&&t.push(e.value);this.model.value=t,super.change_input(),e&&this.input_el.focus()}}i.MultiSelectView=d,d.__name__=\"MultiSelectView\";class u extends h.InputWidget{constructor(e){super(e)}}i.MultiSelect=u,o=u,u.__name__=\"MultiSelect\",o.prototype.default_view=d,o.define((({Int:e,String:t,Array:i,Tuple:s,Or:n})=>({value:[i(t),[]],options:[i(n(t,s(t,t))),[]],size:[e,4]})))},\n", - " 473: function _(e,a,r,t,s){var n;t();const p=e(468),_=e(43);class i extends p.MarkupView{render(){super.render();const e=(0,_.p)({style:{margin:0}});this.has_math_disabled()?e.textContent=this.model.text:e.innerHTML=this.process_tex(),this.markup_el.appendChild(e)}}r.ParagraphView=i,i.__name__=\"ParagraphView\";class h extends p.Markup{constructor(e){super(e)}}r.Paragraph=h,n=h,h.__name__=\"Paragraph\",n.prototype.default_view=i},\n", - " 474: function _(e,s,t,n,r){var p;n();const u=e(446);class a extends u.TextInputView{render(){super.render(),this.input_el.type=\"password\"}}t.PasswordInputView=a,a.__name__=\"PasswordInputView\";class o extends u.TextInput{constructor(e){super(e)}}t.PasswordInput=o,p=o,o.__name__=\"PasswordInput\",p.prototype.default_view=a},\n", - " 475: function _(e,t,i,l,s){l();const o=e(1);var n;const h=(0,o.__importDefault)(e(476)),a=e(43),u=e(8),c=e(210),_=(0,o.__importStar)(e(449)),d=(0,o.__importDefault)(e(477)),r=e(448);class m extends r.InputWidgetView{constructor(){super(...arguments),this._last_height=null}connect_signals(){super.connect_signals(),this.connect(this.model.properties.disabled.change,(()=>this.set_disabled()));const{value:e,max_items:t,option_limit:i,search_option_limit:l,delete_button:s,placeholder:o,options:n,name:h,title:a}=this.model.properties;this.on_change([e,t,i,l,s,o,n,h,a],(()=>this.render()))}styles(){return[...super.styles(),d.default]}_update_layout(){this.layout=new c.CachedVariadicBox(this.el),this.layout.set_sizing(this.box_sizing())}render(){super.render(),this.input_el=(0,a.select)({multiple:!0,class:_.input,name:this.model.name,disabled:this.model.disabled}),this.group_el.appendChild(this.input_el);const e=new Set(this.model.value),t=this.model.options.map((t=>{let i,l;return(0,u.isString)(t)?i=l=t:[i,l]=t,{value:i,label:l,selected:e.has(i)}})),i=this.model.solid?\"solid\":\"light\",l=`choices__item ${i}`,s=`choices__button ${i}`,o={choices:t,duplicateItemsAllowed:!1,removeItemButton:this.model.delete_button,classNames:{item:l,button:s}};null!=this.model.placeholder&&(o.placeholderValue=this.model.placeholder),null!=this.model.max_items&&(o.maxItemCount=this.model.max_items),null!=this.model.option_limit&&(o.renderChoiceLimit=this.model.option_limit),null!=this.model.search_option_limit&&(o.searchResultLimit=this.model.search_option_limit),this.choice_el=new h.default(this.input_el,o);const n=()=>this.choice_el.containerOuter.element.getBoundingClientRect().height;null!=this._last_height&&this._last_height!=n()&&this.root.invalidate_layout(),this._last_height=n(),this.input_el.addEventListener(\"change\",(()=>this.change_input()))}set_disabled(){this.model.disabled?this.choice_el.disable():this.choice_el.enable()}change_input(){const e=null!=this.el.querySelector(\"select:focus\"),t=[];for(const e of this.el.querySelectorAll(\"option\"))e.selected&&t.push(e.value);this.model.value=t,super.change_input(),e&&this.input_el.focus()}}i.MultiChoiceView=m,m.__name__=\"MultiChoiceView\";class p extends r.InputWidget{constructor(e){super(e)}}i.MultiChoice=p,n=p,p.__name__=\"MultiChoice\",n.prototype.default_view=m,n.define((({Boolean:e,Int:t,String:i,Array:l,Tuple:s,Or:o,Nullable:n})=>({value:[l(i),[]],options:[l(o(i,s(i,i))),[]],max_items:[n(t),null],delete_button:[e,!0],placeholder:[n(i),null],option_limit:[n(t),null],search_option_limit:[n(t),null],solid:[e,!0]})))},\n", - " 476: function _(e,t,i,n,s){\n", - " /*! choices.js v9.0.1 | © 2019 Josh Johnson | https://github.com/jshjohnson/Choices#readme */\n", - " var r,o;r=window,o=function(){return function(e){var t={};function i(n){if(t[n])return t[n].exports;var s=t[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}return i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var s in e)i.d(n,s,function(t){return e[t]}.bind(null,s));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,\"a\",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p=\"/public/assets/scripts/\",i(i.s=4)}([function(e,t,i){\"use strict\";var n=function(e){return function(e){return!!e&&\"object\"==typeof e}(e)&&!function(e){var t=Object.prototype.toString.call(e);return\"[object RegExp]\"===t||\"[object Date]\"===t||function(e){return e.$$typeof===s}(e)}(e)},s=\"function\"==typeof Symbol&&Symbol.for?Symbol.for(\"react.element\"):60103;function r(e,t){return!1!==t.clone&&t.isMergeableObject(e)?l((i=e,Array.isArray(i)?[]:{}),e,t):e;var i}function o(e,t,i){return e.concat(t).map((function(e){return r(e,i)}))}function a(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter((function(t){return e.propertyIsEnumerable(t)})):[]}(e))}function c(e,t,i){var n={};return i.isMergeableObject(e)&&a(e).forEach((function(t){n[t]=r(e[t],i)})),a(t).forEach((function(s){(function(e,t){try{return t in e&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}catch(e){return!1}})(e,s)||(i.isMergeableObject(t[s])&&e[s]?n[s]=function(e,t){if(!t.customMerge)return l;var i=t.customMerge(e);return\"function\"==typeof i?i:l}(s,i)(e[s],t[s],i):n[s]=r(t[s],i))})),n}function l(e,t,i){(i=i||{}).arrayMerge=i.arrayMerge||o,i.isMergeableObject=i.isMergeableObject||n,i.cloneUnlessOtherwiseSpecified=r;var s=Array.isArray(t);return s===Array.isArray(e)?s?i.arrayMerge(e,t,i):c(e,t,i):r(t,i)}l.all=function(e,t){if(!Array.isArray(e))throw new Error(\"first argument should be an array\");return e.reduce((function(e,i){return l(e,i,t)}),{})};var h=l;e.exports=h},function(e,t,i){\"use strict\";(function(e,n){var s,r=i(3);s=\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:void 0!==e?e:n;var o=Object(r.a)(s);t.a=o}).call(this,i(5),i(6)(e))},function(e,t,i){\n", - " /*!\n", - " * Fuse.js v3.4.5 - Lightweight fuzzy-search (http://fusejs.io)\n", - " *\n", - " * Copyright (c) 2012-2017 Kirollos Risk (http://kiro.me)\n", - " * All Rights Reserved. Apache Software License 2.0\n", - " *\n", - " * http://www.apache.org/licenses/LICENSE-2.0\n", - " */\n", - " e.exports=function(e){var t={};function i(n){if(t[n])return t[n].exports;var s=t[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}return i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var s in e)i.d(n,s,function(t){return e[t]}.bind(null,s));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,\"a\",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p=\"\",i(i.s=1)}([function(e,t){e.exports=function(e){return Array.isArray?Array.isArray(e):\"[object Array]\"===Object.prototype.toString.call(e)}},function(e,t,i){function n(e){return(n=\"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})(e)}function s(e,t){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{limit:!1};this._log('---------\\nSearch pattern: \"'.concat(e,'\"'));var i=this._prepareSearchers(e),n=i.tokenSearchers,s=i.fullSearcher,r=this._search(n,s),o=r.weights,a=r.results;return this._computeScore(o,a),this.options.shouldSort&&this._sort(a),t.limit&&\"number\"==typeof t.limit&&(a=a.slice(0,t.limit)),this._format(a)}},{key:\"_prepareSearchers\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"\",t=[];if(this.options.tokenize)for(var i=e.split(this.options.tokenSeparator),n=0,s=i.length;n0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1?arguments[1]:void 0,i=this.list,n={},s=[];if(\"string\"==typeof i[0]){for(var r=0,o=i.length;r1)throw new Error(\"Key weight has to be > 0 and <= 1\");p=p.name}else a[p]={weight:1};this._analyze({key:p,value:this.options.getFn(h,p),record:h,index:c},{resultMap:n,results:s,tokenSearchers:e,fullSearcher:t})}return{weights:a,results:s}}},{key:\"_analyze\",value:function(e,t){var i=e.key,n=e.arrayIndex,s=void 0===n?-1:n,r=e.value,o=e.record,c=e.index,l=t.tokenSearchers,h=void 0===l?[]:l,u=t.fullSearcher,d=void 0===u?[]:u,p=t.resultMap,m=void 0===p?{}:p,f=t.results,v=void 0===f?[]:f;if(null!=r){var g=!1,_=-1,b=0;if(\"string\"==typeof r){this._log(\"\\nKey: \".concat(\"\"===i?\"-\":i));var y=d.search(r);if(this._log('Full text: \"'.concat(r,'\", score: ').concat(y.score)),this.options.tokenize){for(var E=r.split(this.options.tokenSeparator),I=[],S=0;S-1&&(P=(P+_)/2),this._log(\"Score average:\",P);var D=!this.options.tokenize||!this.options.matchAllTokens||b>=h.length;if(this._log(\"\\nCheck Matches: \".concat(D)),(g||y.isMatch)&&D){var M=m[c];M?M.output.push({key:i,arrayIndex:s,value:r,score:P,matchedIndices:y.matchedIndices}):(m[c]={item:o,output:[{key:i,arrayIndex:s,value:r,score:P,matchedIndices:y.matchedIndices}]},v.push(m[c]))}}else if(a(r))for(var N=0,F=r.length;N-1&&(o.arrayIndex=r.arrayIndex),t.matches.push(o)}}})),this.options.includeScore&&s.push((function(e,t){t.score=e.score}));for(var r=0,o=e.length;ri)return s(e,this.pattern,n);var o=this.options,a=o.location,c=o.distance,l=o.threshold,h=o.findAllMatches,u=o.minMatchCharLength;return r(e,this.pattern,this.patternAlphabet,{location:a,distance:c,threshold:l,findAllMatches:h,minMatchCharLength:u})}}])&&n(t.prototype,i),a&&n(t,a),e}();e.exports=a},function(e,t){var i=/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g;e.exports=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:/ +/g,s=new RegExp(t.replace(i,\"\\\\$&\").replace(n,\"|\")),r=e.match(s),o=!!r,a=[];if(o)for(var c=0,l=r.length;c=P;N-=1){var F=N-1,j=i[e.charAt(F)];if(j&&(E[F]=1),M[N]=(M[N+1]<<1|1)&j,0!==T&&(M[N]|=(O[N+1]|O[N])<<1|1|O[N+1]),M[N]&L&&(C=n(t,{errors:T,currentLocation:F,expectedLocation:v,distance:l}))<=_){if(_=C,(b=F)<=v)break;P=Math.max(1,2*v-b)}}if(n(t,{errors:T+1,currentLocation:v,expectedLocation:v,distance:l})>_)break;O=M}return{isMatch:b>=0,score:0===C?.001:C,matchedIndices:s(E,f)}}},function(e,t){e.exports=function(e,t){var i=t.errors,n=void 0===i?0:i,s=t.currentLocation,r=void 0===s?0:s,o=t.expectedLocation,a=void 0===o?0:o,c=t.distance,l=void 0===c?100:c,h=n/e.length,u=Math.abs(a-r);return l?h+u/l:u?1:h}},function(e,t){e.exports=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,i=[],n=-1,s=-1,r=0,o=e.length;r=t&&i.push([n,s]),n=-1)}return e[r-1]&&r-n>=t&&i.push([n,r-1]),i}},function(e,t){e.exports=function(e){for(var t={},i=e.length,n=0;n/g,\"&rt;\").replace(/-1?e.map((function(e){var i=e;return i.id===parseInt(t.choiceId,10)&&(i.selected=!0),i})):e;case\"REMOVE_ITEM\":return t.choiceId>-1?e.map((function(e){var i=e;return i.id===parseInt(t.choiceId,10)&&(i.selected=!1),i})):e;case\"FILTER_CHOICES\":return e.map((function(e){var i=e;return i.active=t.results.some((function(e){var t=e.item,n=e.score;return t.id===i.id&&(i.score=n,!0)})),i}));case\"ACTIVATE_CHOICES\":return e.map((function(e){var i=e;return i.active=t.active,i}));case\"CLEAR_CHOICES\":return v;default:return e}},general:_}),A=function(e,t){var i=e;if(\"CLEAR_ALL\"===t.type)i=void 0;else if(\"RESET_TO\"===t.type)return O(t.state);return C(i,t)};function L(e,t){for(var i=0;i\"'+I(e)+'\"'},maxItemText:function(e){return\"Only \"+e+\" values can be added\"},valueComparer:function(e,t){return e===t},fuseOptions:{includeScore:!0},callbackOnInit:null,callbackOnCreateTemplates:null,classNames:{containerOuter:\"choices\",containerInner:\"choices__inner\",input:\"choices__input\",inputCloned:\"choices__input--cloned\",list:\"choices__list\",listItems:\"choices__list--multiple\",listSingle:\"choices__list--single\",listDropdown:\"choices__list--dropdown\",item:\"choices__item\",itemSelectable:\"choices__item--selectable\",itemDisabled:\"choices__item--disabled\",itemChoice:\"choices__item--choice\",placeholder:\"choices__placeholder\",group:\"choices__group\",groupHeading:\"choices__heading\",button:\"choices__button\",activeState:\"is-active\",focusState:\"is-focused\",openState:\"is-open\",disabledState:\"is-disabled\",highlightedState:\"is-highlighted\",selectedState:\"is-selected\",flippedState:\"is-flipped\",loadingState:\"is-loading\",noResults:\"has-no-results\",noChoices:\"has-no-choices\"}},D=\"showDropdown\",M=\"hideDropdown\",N=\"change\",F=\"choice\",j=\"search\",K=\"addItem\",R=\"removeItem\",H=\"highlightItem\",B=\"highlightChoice\",V=\"ADD_CHOICE\",G=\"FILTER_CHOICES\",q=\"ACTIVATE_CHOICES\",U=\"CLEAR_CHOICES\",z=\"ADD_GROUP\",W=\"ADD_ITEM\",X=\"REMOVE_ITEM\",$=\"HIGHLIGHT_ITEM\",J=46,Y=8,Z=13,Q=65,ee=27,te=38,ie=40,ne=33,se=34,re=\"text\",oe=\"select-one\",ae=\"select-multiple\",ce=function(){function e(e){var t=e.element,i=e.type,n=e.classNames,s=e.position;this.element=t,this.classNames=n,this.type=i,this.position=s,this.isOpen=!1,this.isFlipped=!1,this.isFocussed=!1,this.isDisabled=!1,this.isLoading=!1,this._onFocus=this._onFocus.bind(this),this._onBlur=this._onBlur.bind(this)}var t=e.prototype;return t.addEventListeners=function(){this.element.addEventListener(\"focus\",this._onFocus),this.element.addEventListener(\"blur\",this._onBlur)},t.removeEventListeners=function(){this.element.removeEventListener(\"focus\",this._onFocus),this.element.removeEventListener(\"blur\",this._onBlur)},t.shouldFlip=function(e){if(\"number\"!=typeof e)return!1;var t=!1;return\"auto\"===this.position?t=!window.matchMedia(\"(min-height: \"+(e+1)+\"px)\").matches:\"top\"===this.position&&(t=!0),t},t.setActiveDescendant=function(e){this.element.setAttribute(\"aria-activedescendant\",e)},t.removeActiveDescendant=function(){this.element.removeAttribute(\"aria-activedescendant\")},t.open=function(e){this.element.classList.add(this.classNames.openState),this.element.setAttribute(\"aria-expanded\",\"true\"),this.isOpen=!0,this.shouldFlip(e)&&(this.element.classList.add(this.classNames.flippedState),this.isFlipped=!0)},t.close=function(){this.element.classList.remove(this.classNames.openState),this.element.setAttribute(\"aria-expanded\",\"false\"),this.removeActiveDescendant(),this.isOpen=!1,this.isFlipped&&(this.element.classList.remove(this.classNames.flippedState),this.isFlipped=!1)},t.focus=function(){this.isFocussed||this.element.focus()},t.addFocusState=function(){this.element.classList.add(this.classNames.focusState)},t.removeFocusState=function(){this.element.classList.remove(this.classNames.focusState)},t.enable=function(){this.element.classList.remove(this.classNames.disabledState),this.element.removeAttribute(\"aria-disabled\"),this.type===oe&&this.element.setAttribute(\"tabindex\",\"0\"),this.isDisabled=!1},t.disable=function(){this.element.classList.add(this.classNames.disabledState),this.element.setAttribute(\"aria-disabled\",\"true\"),this.type===oe&&this.element.setAttribute(\"tabindex\",\"-1\"),this.isDisabled=!0},t.wrap=function(e){!function(e,t){void 0===t&&(t=document.createElement(\"div\")),e.nextSibling?e.parentNode.insertBefore(t,e.nextSibling):e.parentNode.appendChild(t),t.appendChild(e)}(e,this.element)},t.unwrap=function(e){this.element.parentNode.insertBefore(e,this.element),this.element.parentNode.removeChild(this.element)},t.addLoadingState=function(){this.element.classList.add(this.classNames.loadingState),this.element.setAttribute(\"aria-busy\",\"true\"),this.isLoading=!0},t.removeLoadingState=function(){this.element.classList.remove(this.classNames.loadingState),this.element.removeAttribute(\"aria-busy\"),this.isLoading=!1},t._onFocus=function(){this.isFocussed=!0},t._onBlur=function(){this.isFocussed=!1},e}();function le(e,t){for(var i=0;i0?this.element.scrollTop+o-s:e.offsetTop;requestAnimationFrame((function(){i._animateScroll(a,t)}))}},t._scrollDown=function(e,t,i){var n=(i-e)/t,s=n>1?n:1;this.element.scrollTop=e+s},t._scrollUp=function(e,t,i){var n=(e-i)/t,s=n>1?n:1;this.element.scrollTop=e-s},t._animateScroll=function(e,t){var i=this,n=this.element.scrollTop,s=!1;t>0?(this._scrollDown(n,4,e),ne&&(s=!0)),s&&requestAnimationFrame((function(){i._animateScroll(e,t)}))},e}();function de(e,t){for(var i=0;i0?\"treeitem\":\"option\"),Object.assign(g.dataset,{choice:\"\",id:l,value:h,selectText:i}),m?(g.classList.add(a),g.dataset.choiceDisabled=\"\",g.setAttribute(\"aria-disabled\",\"true\")):(g.classList.add(r),g.dataset.choiceSelectable=\"\"),g},input:function(e,t){var i=e.input,n=e.inputCloned,s=Object.assign(document.createElement(\"input\"),{type:\"text\",className:i+\" \"+n,autocomplete:\"off\",autocapitalize:\"off\",spellcheck:!1});return s.setAttribute(\"role\",\"textbox\"),s.setAttribute(\"aria-autocomplete\",\"list\"),s.setAttribute(\"aria-label\",t),s},dropdown:function(e){var t=e.list,i=e.listDropdown,n=document.createElement(\"div\");return n.classList.add(t,i),n.setAttribute(\"aria-expanded\",\"false\"),n},notice:function(e,t,i){var n=e.item,s=e.itemChoice,r=e.noResults,o=e.noChoices;void 0===i&&(i=\"\");var a=[n,s];return\"no-choices\"===i?a.push(o):\"no-results\"===i&&a.push(r),Object.assign(document.createElement(\"div\"),{innerHTML:t,className:a.join(\" \")})},option:function(e){var t=e.label,i=e.value,n=e.customProperties,s=e.active,r=e.disabled,o=new Option(t,i,!1,s);return n&&(o.dataset.customProperties=n),o.disabled=r,o}},be=function(e){return void 0===e&&(e=!0),{type:q,active:e}},ye=function(e,t){return{type:$,id:e,highlighted:t}},Ee=function(e){var t=e.value,i=e.id,n=e.active,s=e.disabled;return{type:z,value:t,id:i,active:n,disabled:s}},Ie=function(e){return{type:\"SET_IS_LOADING\",isLoading:e}};function Se(e,t){for(var i=0;i=0?this._store.getGroupById(s):null;return this._store.dispatch(ye(i,!0)),t&&this.passedElement.triggerEvent(H,{id:i,value:o,label:c,groupValue:l&&l.value?l.value:null}),this},r.unhighlightItem=function(e){if(!e)return this;var t=e.id,i=e.groupId,n=void 0===i?-1:i,s=e.value,r=void 0===s?\"\":s,o=e.label,a=void 0===o?\"\":o,c=n>=0?this._store.getGroupById(n):null;return this._store.dispatch(ye(t,!1)),this.passedElement.triggerEvent(H,{id:t,value:r,label:a,groupValue:c&&c.value?c.value:null}),this},r.highlightAll=function(){var e=this;return this._store.items.forEach((function(t){return e.highlightItem(t)})),this},r.unhighlightAll=function(){var e=this;return this._store.items.forEach((function(t){return e.unhighlightItem(t)})),this},r.removeActiveItemsByValue=function(e){var t=this;return this._store.activeItems.filter((function(t){return t.value===e})).forEach((function(e){return t._removeItem(e)})),this},r.removeActiveItems=function(e){var t=this;return this._store.activeItems.filter((function(t){return t.id!==e})).forEach((function(e){return t._removeItem(e)})),this},r.removeHighlightedItems=function(e){var t=this;return void 0===e&&(e=!1),this._store.highlightedActiveItems.forEach((function(i){t._removeItem(i),e&&t._triggerChange(i.value)})),this},r.showDropdown=function(e){var t=this;return this.dropdown.isActive||requestAnimationFrame((function(){t.dropdown.show(),t.containerOuter.open(t.dropdown.distanceFromTopWindow),!e&&t._canSearch&&t.input.focus(),t.passedElement.triggerEvent(D,{})})),this},r.hideDropdown=function(e){var t=this;return this.dropdown.isActive?(requestAnimationFrame((function(){t.dropdown.hide(),t.containerOuter.close(),!e&&t._canSearch&&(t.input.removeActiveDescendant(),t.input.blur()),t.passedElement.triggerEvent(M,{})})),this):this},r.getValue=function(e){void 0===e&&(e=!1);var t=this._store.activeItems.reduce((function(t,i){var n=e?i.value:i;return t.push(n),t}),[]);return this._isSelectOneElement?t[0]:t},r.setValue=function(e){var t=this;return this.initialised?(e.forEach((function(e){return t._setChoiceOrItem(e)})),this):this},r.setChoiceByValue=function(e){var t=this;return!this.initialised||this._isTextElement||(Array.isArray(e)?e:[e]).forEach((function(e){return t._findAndSelectChoiceByValue(e)})),this},r.setChoices=function(e,t,i,n){var s=this;if(void 0===e&&(e=[]),void 0===t&&(t=\"value\"),void 0===i&&(i=\"label\"),void 0===n&&(n=!1),!this.initialised)throw new ReferenceError(\"setChoices was called on a non-initialized instance of Choices\");if(!this._isSelectElement)throw new TypeError(\"setChoices can't be used with INPUT based Choices\");if(\"string\"!=typeof t||!t)throw new TypeError(\"value parameter must be a name of 'value' field in passed objects\");if(n&&this.clearChoices(),\"function\"==typeof e){var r=e(this);if(\"function\"==typeof Promise&&r instanceof Promise)return new Promise((function(e){return requestAnimationFrame(e)})).then((function(){return s._handleLoadingState(!0)})).then((function(){return r})).then((function(e){return s.setChoices(e,t,i,n)})).catch((function(e){s.config.silent||console.error(e)})).then((function(){return s._handleLoadingState(!1)})).then((function(){return s}));if(!Array.isArray(r))throw new TypeError(\".setChoices first argument function must return either array of choices or Promise, got: \"+typeof r);return this.setChoices(r,t,i,!1)}if(!Array.isArray(e))throw new TypeError(\".setChoices must be called either with array of choices with a function resulting into Promise of array of choices\");return this.containerOuter.removeLoadingState(),this._startLoading(),e.forEach((function(e){e.choices?s._addGroup({id:parseInt(e.id,10)||null,group:e,valueKey:t,labelKey:i}):s._addChoice({value:e[t],label:e[i],isSelected:e.selected,isDisabled:e.disabled,customProperties:e.customProperties,placeholder:e.placeholder})})),this._stopLoading(),this},r.clearChoices=function(){return this._store.dispatch({type:U}),this},r.clearStore=function(){return this._store.dispatch({type:\"CLEAR_ALL\"}),this},r.clearInput=function(){var e=!this._isSelectOneElement;return this.input.clear(e),!this._isTextElement&&this._canSearch&&(this._isSearching=!1,this._store.dispatch(be(!0))),this},r._render=function(){if(!this._store.isLoading()){this._currentState=this._store.state;var e=this._currentState.choices!==this._prevState.choices||this._currentState.groups!==this._prevState.groups||this._currentState.items!==this._prevState.items,t=this._isSelectElement,i=this._currentState.items!==this._prevState.items;e&&(t&&this._renderChoices(),i&&this._renderItems(),this._prevState=this._currentState)}},r._renderChoices=function(){var e=this,t=this._store,i=t.activeGroups,n=t.activeChoices,s=document.createDocumentFragment();if(this.choiceList.clear(),this.config.resetScrollPosition&&requestAnimationFrame((function(){return e.choiceList.scrollToTop()})),i.length>=1&&!this._isSearching){var r=n.filter((function(e){return!0===e.placeholder&&-1===e.groupId}));r.length>=1&&(s=this._createChoicesFragment(r,s)),s=this._createGroupsFragment(i,n,s)}else n.length>=1&&(s=this._createChoicesFragment(n,s));if(s.childNodes&&s.childNodes.length>0){var o=this._store.activeItems,a=this._canAddItem(o,this.input.value);a.response?(this.choiceList.append(s),this._highlightChoice()):this.choiceList.append(this._getTemplate(\"notice\",a.notice))}else{var c,l;this._isSearching?(l=\"function\"==typeof this.config.noResultsText?this.config.noResultsText():this.config.noResultsText,c=this._getTemplate(\"notice\",l,\"no-results\")):(l=\"function\"==typeof this.config.noChoicesText?this.config.noChoicesText():this.config.noChoicesText,c=this._getTemplate(\"notice\",l,\"no-choices\")),this.choiceList.append(c)}},r._renderItems=function(){var e=this._store.activeItems||[];this.itemList.clear();var t=this._createItemsFragment(e);t.childNodes&&this.itemList.append(t)},r._createGroupsFragment=function(e,t,i){var n=this;return void 0===i&&(i=document.createDocumentFragment()),this.config.shouldSort&&e.sort(this.config.sorter),e.forEach((function(e){var s=function(e){return t.filter((function(t){return n._isSelectOneElement?t.groupId===e.id:t.groupId===e.id&&(\"always\"===n.config.renderSelectedChoices||!t.selected)}))}(e);if(s.length>=1){var r=n._getTemplate(\"choiceGroup\",e);i.appendChild(r),n._createChoicesFragment(s,i,!0)}})),i},r._createChoicesFragment=function(e,t,i){var n=this;void 0===t&&(t=document.createDocumentFragment()),void 0===i&&(i=!1);var s=this.config,r=s.renderSelectedChoices,o=s.searchResultLimit,a=s.renderChoiceLimit,c=this._isSearching?w:this.config.sorter,l=function(e){if(\"auto\"!==r||n._isSelectOneElement||!e.selected){var i=n._getTemplate(\"choice\",e,n.config.itemSelectText);t.appendChild(i)}},h=e;\"auto\"!==r||this._isSelectOneElement||(h=e.filter((function(e){return!e.selected})));var u=h.reduce((function(e,t){return t.placeholder?e.placeholderChoices.push(t):e.normalChoices.push(t),e}),{placeholderChoices:[],normalChoices:[]}),d=u.placeholderChoices,p=u.normalChoices;(this.config.shouldSort||this._isSearching)&&p.sort(c);var m=h.length,f=this._isSelectOneElement?[].concat(d,p):p;this._isSearching?m=o:a&&a>0&&!i&&(m=a);for(var v=0;v=n){var o=s?this._searchChoices(e):0;this.passedElement.triggerEvent(j,{value:e,resultCount:o})}else r&&(this._isSearching=!1,this._store.dispatch(be(!0)))}},r._canAddItem=function(e,t){var i=!0,n=\"function\"==typeof this.config.addItemText?this.config.addItemText(t):this.config.addItemText;if(!this._isSelectOneElement){var s=function(e,t,i){return void 0===i&&(i=\"value\"),e.some((function(e){return\"string\"==typeof t?e[i]===t.trim():e[i]===t}))}(e,t);this.config.maxItemCount>0&&this.config.maxItemCount<=e.length&&(i=!1,n=\"function\"==typeof this.config.maxItemText?this.config.maxItemText(this.config.maxItemCount):this.config.maxItemText),!this.config.duplicateItemsAllowed&&s&&i&&(i=!1,n=\"function\"==typeof this.config.uniqueItemText?this.config.uniqueItemText(t):this.config.uniqueItemText),this._isTextElement&&this.config.addItems&&i&&\"function\"==typeof this.config.addItemFilter&&!this.config.addItemFilter(t)&&(i=!1,n=\"function\"==typeof this.config.customAddItemText?this.config.customAddItemText(t):this.config.customAddItemText)}return{response:i,notice:n}},r._searchChoices=function(e){var t=\"string\"==typeof e?e.trim():e,i=\"string\"==typeof this._currentValue?this._currentValue.trim():this._currentValue;if(t.length<1&&t===i+\" \")return 0;var n=this._store.searchableChoices,r=t,o=[].concat(this.config.searchFields),a=Object.assign(this.config.fuseOptions,{keys:o}),c=new s.a(n,a).search(r);return this._currentValue=t,this._highlightPosition=0,this._isSearching=!0,this._store.dispatch(function(e){return{type:G,results:e}}(c)),c.length},r._addEventListeners=function(){var e=document.documentElement;e.addEventListener(\"touchend\",this._onTouchEnd,!0),this.containerOuter.element.addEventListener(\"keydown\",this._onKeyDown,!0),this.containerOuter.element.addEventListener(\"mousedown\",this._onMouseDown,!0),e.addEventListener(\"click\",this._onClick,{passive:!0}),e.addEventListener(\"touchmove\",this._onTouchMove,{passive:!0}),this.dropdown.element.addEventListener(\"mouseover\",this._onMouseOver,{passive:!0}),this._isSelectOneElement&&(this.containerOuter.element.addEventListener(\"focus\",this._onFocus,{passive:!0}),this.containerOuter.element.addEventListener(\"blur\",this._onBlur,{passive:!0})),this.input.element.addEventListener(\"keyup\",this._onKeyUp,{passive:!0}),this.input.element.addEventListener(\"focus\",this._onFocus,{passive:!0}),this.input.element.addEventListener(\"blur\",this._onBlur,{passive:!0}),this.input.element.form&&this.input.element.form.addEventListener(\"reset\",this._onFormReset,{passive:!0}),this.input.addEventListeners()},r._removeEventListeners=function(){var e=document.documentElement;e.removeEventListener(\"touchend\",this._onTouchEnd,!0),this.containerOuter.element.removeEventListener(\"keydown\",this._onKeyDown,!0),this.containerOuter.element.removeEventListener(\"mousedown\",this._onMouseDown,!0),e.removeEventListener(\"click\",this._onClick),e.removeEventListener(\"touchmove\",this._onTouchMove),this.dropdown.element.removeEventListener(\"mouseover\",this._onMouseOver),this._isSelectOneElement&&(this.containerOuter.element.removeEventListener(\"focus\",this._onFocus),this.containerOuter.element.removeEventListener(\"blur\",this._onBlur)),this.input.element.removeEventListener(\"keyup\",this._onKeyUp),this.input.element.removeEventListener(\"focus\",this._onFocus),this.input.element.removeEventListener(\"blur\",this._onBlur),this.input.element.form&&this.input.element.form.removeEventListener(\"reset\",this._onFormReset),this.input.removeEventListeners()},r._onKeyDown=function(e){var t,i=e.target,n=e.keyCode,s=e.ctrlKey,r=e.metaKey,o=this._store.activeItems,a=this.input.isFocussed,c=this.dropdown.isActive,l=this.itemList.hasChildren(),h=String.fromCharCode(n),u=J,d=Y,p=Z,m=Q,f=ee,v=te,g=ie,_=ne,b=se,y=s||r;!this._isTextElement&&/[a-zA-Z0-9-_ ]/.test(h)&&this.showDropdown();var E=((t={})[m]=this._onAKey,t[p]=this._onEnterKey,t[f]=this._onEscapeKey,t[v]=this._onDirectionKey,t[_]=this._onDirectionKey,t[g]=this._onDirectionKey,t[b]=this._onDirectionKey,t[d]=this._onDeleteKey,t[u]=this._onDeleteKey,t);E[n]&&E[n]({event:e,target:i,keyCode:n,metaKey:r,activeItems:o,hasFocusedInput:a,hasActiveDropdown:c,hasItems:l,hasCtrlDownKeyPressed:y})},r._onKeyUp=function(e){var t=e.target,i=e.keyCode,n=this.input.value,s=this._store.activeItems,r=this._canAddItem(s,n),o=J,a=Y;if(this._isTextElement)if(r.notice&&n){var c=this._getTemplate(\"notice\",r.notice);this.dropdown.element.innerHTML=c.outerHTML,this.showDropdown(!0)}else this.hideDropdown(!0);else{var l=(i===o||i===a)&&!t.value,h=!this._isTextElement&&this._isSearching,u=this._canSearch&&r.response;l&&h?(this._isSearching=!1,this._store.dispatch(be(!0))):u&&this._handleSearch(this.input.value)}this._canSearch=this.config.searchEnabled},r._onAKey=function(e){var t=e.hasItems;e.hasCtrlDownKeyPressed&&t&&(this._canSearch=!1,this.config.removeItems&&!this.input.value&&this.input.element===document.activeElement&&this.highlightAll())},r._onEnterKey=function(e){var t=e.event,i=e.target,n=e.activeItems,s=e.hasActiveDropdown,r=Z,o=i.hasAttribute(\"data-button\");if(this._isTextElement&&i.value){var a=this.input.value;this._canAddItem(n,a).response&&(this.hideDropdown(!0),this._addItem({value:a}),this._triggerChange(a),this.clearInput())}if(o&&(this._handleButtonAction(n,i),t.preventDefault()),s){var c=this.dropdown.getChild(\".\"+this.config.classNames.highlightedState);c&&(n[0]&&(n[0].keyCode=r),this._handleChoiceAction(n,c)),t.preventDefault()}else this._isSelectOneElement&&(this.showDropdown(),t.preventDefault())},r._onEscapeKey=function(e){e.hasActiveDropdown&&(this.hideDropdown(!0),this.containerOuter.focus())},r._onDirectionKey=function(e){var t,i,n,s=e.event,r=e.hasActiveDropdown,o=e.keyCode,a=e.metaKey,c=ie,l=ne,h=se;if(r||this._isSelectOneElement){this.showDropdown(),this._canSearch=!1;var u,d=o===c||o===h?1:-1,p=\"[data-choice-selectable]\";if(a||o===h||o===l)u=d>0?this.dropdown.element.querySelector(\"[data-choice-selectable]:last-of-type\"):this.dropdown.element.querySelector(p);else{var m=this.dropdown.element.querySelector(\".\"+this.config.classNames.highlightedState);u=m?function(e,t,i){if(void 0===i&&(i=1),e instanceof Element&&\"string\"==typeof t){for(var n=(i>0?\"next\":\"previous\")+\"ElementSibling\",s=e[n];s;){if(s.matches(t))return s;s=s[n]}return s}}(m,p,d):this.dropdown.element.querySelector(p)}u&&(t=u,i=this.choiceList.element,void 0===(n=d)&&(n=1),t&&(n>0?i.scrollTop+i.offsetHeight>=t.offsetTop+t.offsetHeight:t.offsetTop>=i.scrollTop)||this.choiceList.scrollToChildElement(u,d),this._highlightChoice(u)),s.preventDefault()}},r._onDeleteKey=function(e){var t=e.event,i=e.target,n=e.hasFocusedInput,s=e.activeItems;!n||i.value||this._isSelectOneElement||(this._handleBackspace(s),t.preventDefault())},r._onTouchMove=function(){this._wasTap&&(this._wasTap=!1)},r._onTouchEnd=function(e){var t=(e||e.touches[0]).target;this._wasTap&&this.containerOuter.element.contains(t)&&((t===this.containerOuter.element||t===this.containerInner.element)&&(this._isTextElement?this.input.focus():this._isSelectMultipleElement&&this.showDropdown()),e.stopPropagation()),this._wasTap=!0},r._onMouseDown=function(e){var t=e.target;if(t instanceof HTMLElement){if(we&&this.choiceList.element.contains(t)){var i=this.choiceList.element.firstElementChild,n=\"ltr\"===this._direction?e.offsetX>=i.offsetWidth:e.offsetX0&&this.unhighlightAll(),this.containerOuter.removeFocusState(),this.hideDropdown(!0))},r._onFocus=function(e){var t,i=this,n=e.target;this.containerOuter.element.contains(n)&&((t={}).text=function(){n===i.input.element&&i.containerOuter.addFocusState()},t[\"select-one\"]=function(){i.containerOuter.addFocusState(),n===i.input.element&&i.showDropdown(!0)},t[\"select-multiple\"]=function(){n===i.input.element&&(i.showDropdown(!0),i.containerOuter.addFocusState())},t)[this.passedElement.element.type]()},r._onBlur=function(e){var t=this,i=e.target;if(this.containerOuter.element.contains(i)&&!this._isScrollingOnIe){var n,s=this._store.activeItems.some((function(e){return e.highlighted}));((n={}).text=function(){i===t.input.element&&(t.containerOuter.removeFocusState(),s&&t.unhighlightAll(),t.hideDropdown(!0))},n[\"select-one\"]=function(){t.containerOuter.removeFocusState(),(i===t.input.element||i===t.containerOuter.element&&!t._canSearch)&&t.hideDropdown(!0)},n[\"select-multiple\"]=function(){i===t.input.element&&(t.containerOuter.removeFocusState(),t.hideDropdown(!0),s&&t.unhighlightAll())},n)[this.passedElement.element.type]()}else this._isScrollingOnIe=!1,this.input.element.focus()},r._onFormReset=function(){this._store.dispatch({type:\"RESET_TO\",state:this._initialState})},r._highlightChoice=function(e){var t=this;void 0===e&&(e=null);var i=Array.from(this.dropdown.element.querySelectorAll(\"[data-choice-selectable]\"));if(i.length){var n=e;Array.from(this.dropdown.element.querySelectorAll(\".\"+this.config.classNames.highlightedState)).forEach((function(e){e.classList.remove(t.config.classNames.highlightedState),e.setAttribute(\"aria-selected\",\"false\")})),n?this._highlightPosition=i.indexOf(n):(n=i.length>this._highlightPosition?i[this._highlightPosition]:i[i.length-1])||(n=i[0]),n.classList.add(this.config.classNames.highlightedState),n.setAttribute(\"aria-selected\",\"true\"),this.passedElement.triggerEvent(B,{el:n}),this.dropdown.isActive&&(this.input.setActiveDescendant(n.id),this.containerOuter.setActiveDescendant(n.id))}},r._addItem=function(e){var t=e.value,i=e.label,n=void 0===i?null:i,s=e.choiceId,r=void 0===s?-1:s,o=e.groupId,a=void 0===o?-1:o,c=e.customProperties,l=void 0===c?null:c,h=e.placeholder,u=void 0!==h&&h,d=e.keyCode,p=void 0===d?null:d,m=\"string\"==typeof t?t.trim():t,f=p,v=l,g=this._store.items,_=n||m,b=r||-1,y=a>=0?this._store.getGroupById(a):null,E=g?g.length+1:1;return this.config.prependValue&&(m=this.config.prependValue+m.toString()),this.config.appendValue&&(m+=this.config.appendValue.toString()),this._store.dispatch(function(e){var t=e.value,i=e.label,n=e.id,s=e.choiceId,r=e.groupId,o=e.customProperties,a=e.placeholder,c=e.keyCode;return{type:W,value:t,label:i,id:n,choiceId:s,groupId:r,customProperties:o,placeholder:a,keyCode:c}}({value:m,label:_,id:E,choiceId:b,groupId:a,customProperties:l,placeholder:u,keyCode:f})),this._isSelectOneElement&&this.removeActiveItems(E),this.passedElement.triggerEvent(K,{id:E,value:m,label:_,customProperties:v,groupValue:y&&y.value?y.value:void 0,keyCode:f}),this},r._removeItem=function(e){if(!e||!E(\"Object\",e))return this;var t=e.id,i=e.value,n=e.label,s=e.choiceId,r=e.groupId,o=r>=0?this._store.getGroupById(r):null;return this._store.dispatch(function(e,t){return{type:X,id:e,choiceId:t}}(t,s)),o&&o.value?this.passedElement.triggerEvent(R,{id:t,value:i,label:n,groupValue:o.value}):this.passedElement.triggerEvent(R,{id:t,value:i,label:n}),this},r._addChoice=function(e){var t=e.value,i=e.label,n=void 0===i?null:i,s=e.isSelected,r=void 0!==s&&s,o=e.isDisabled,a=void 0!==o&&o,c=e.groupId,l=void 0===c?-1:c,h=e.customProperties,u=void 0===h?null:h,d=e.placeholder,p=void 0!==d&&d,m=e.keyCode,f=void 0===m?null:m;if(null!=t){var v=this._store.choices,g=n||t,_=v?v.length+1:1,b=this._baseId+\"-\"+this._idNames.itemChoice+\"-\"+_;this._store.dispatch(function(e){var t=e.value,i=e.label,n=e.id,s=e.groupId,r=e.disabled,o=e.elementId,a=e.customProperties,c=e.placeholder,l=e.keyCode;return{type:V,value:t,label:i,id:n,groupId:s,disabled:r,elementId:o,customProperties:a,placeholder:c,keyCode:l}}({id:_,groupId:l,elementId:b,value:t,label:g,disabled:a,customProperties:u,placeholder:p,keyCode:f})),r&&this._addItem({value:t,label:g,choiceId:_,customProperties:u,placeholder:p,keyCode:f})}},r._addGroup=function(e){var t=this,i=e.group,n=e.id,s=e.valueKey,r=void 0===s?\"value\":s,o=e.labelKey,a=void 0===o?\"label\":o,c=E(\"Object\",i)?i.choices:Array.from(i.getElementsByTagName(\"OPTION\")),l=n||Math.floor((new Date).valueOf()*Math.random()),h=!!i.disabled&&i.disabled;c?(this._store.dispatch(Ee({value:i.label,id:l,active:!0,disabled:h})),c.forEach((function(e){var i=e.disabled||e.parentNode&&e.parentNode.disabled;t._addChoice({value:e[r],label:E(\"Object\",e)?e[a]:e.innerHTML,isSelected:e.selected,isDisabled:i,groupId:l,customProperties:e.customProperties,placeholder:e.placeholder})}))):this._store.dispatch(Ee({value:i.label,id:i.id,active:!1,disabled:i.disabled}))},r._getTemplate=function(e){var t;if(!e)return null;for(var i=this.config.classNames,n=arguments.length,s=new Array(n>1?n-1:0),r=1;r{var e;return this.input_el.name=null!==(e=this.model.name)&&void 0!==e?e:\"\"})),this.connect(this.model.properties.value.change,(()=>{this.input_el.value=this.format_value,this.old_value=this.input_el.value})),this.connect(this.model.properties.low.change,(()=>{const{value:e,low:t,high:l}=this.model;null!=t&&null!=l&&(0,p.assert)(t<=l,\"Invalid bounds, low must be inferior to high\"),null!=e&&null!=t&&e{const{value:e,low:t,high:l}=this.model;null!=t&&null!=l&&(0,p.assert)(l>=t,\"Invalid bounds, high must be superior to low\"),null!=e&&null!=l&&e>l&&(this.model.value=l)})),this.connect(this.model.properties.high.change,(()=>this.input_el.placeholder=this.model.placeholder)),this.connect(this.model.properties.disabled.change,(()=>this.input_el.disabled=this.model.disabled)),this.connect(this.model.properties.placeholder.change,(()=>this.input_el.placeholder=this.model.placeholder))}get format_value(){return null!=this.model.value?this.model.pretty(this.model.value):\"\"}_set_input_filter(e){this.input_el.addEventListener(\"input\",(()=>{const{selectionStart:t,selectionEnd:l}=this.input_el;if(e(this.input_el.value))this.old_value=this.input_el.value;else{const e=this.old_value.length-this.input_el.value.length;this.input_el.value=this.old_value,t&&l&&this.input_el.setSelectionRange(t-1,l+e)}}))}render(){super.render(),this.input_el=(0,r.input)({type:\"text\",class:_.input,name:this.model.name,value:this.format_value,disabled:this.model.disabled,placeholder:this.model.placeholder}),this.old_value=this.format_value,this.set_input_filter(),this.input_el.addEventListener(\"change\",(()=>this.change_input())),this.input_el.addEventListener(\"focusout\",(()=>this.input_el.value=this.format_value)),this.group_el.appendChild(this.input_el)}set_input_filter(){\"int\"==this.model.mode?this._set_input_filter((e=>m.test(e))):\"float\"==this.model.mode&&this._set_input_filter((e=>c.test(e)))}bound_value(e){let t=e;const{low:l,high:i}=this.model;return t=null!=l?Math.max(l,t):t,t=null!=i?Math.min(i,t):t,t}get value(){let e=\"\"!=this.input_el.value?Number(this.input_el.value):null;return null!=e&&(e=this.bound_value(e)),e}change_input(){null==this.value?this.model.value=null:Number.isNaN(this.value)||(this.model.value=this.value)}}l.NumericInputView=v,v.__name__=\"NumericInputView\";class g extends o.InputWidget{constructor(e){super(e)}_formatter(e,t){return(0,d.isString)(t)?h.format(e,t):t.doFormat([e],{loc:0})[0]}pretty(e){return null!=this.format?this._formatter(e,this.format):`${e}`}}l.NumericInput=g,u=g,g.__name__=\"NumericInput\",u.prototype.default_view=v,u.define((({Number:e,String:t,Enum:l,Ref:i,Or:n,Nullable:s})=>({value:[s(e),null],placeholder:[t,\"\"],mode:[l(\"int\",\"float\"),\"int\"],format:[s(n(t,i(a.TickFormatter))),null],low:[s(e),null],high:[s(e),null]})))},\n", - " 479: function _(e,t,r,s,n){var a;s();const o=e(468),_=e(43);class p extends o.MarkupView{render(){super.render();const e=(0,_.pre)({style:{overflow:\"auto\"}},this.model.text);this.markup_el.appendChild(e)}}r.PreTextView=p,p.__name__=\"PreTextView\";class u extends o.Markup{constructor(e){super(e)}}r.PreText=u,a=u,u.__name__=\"PreText\",a.prototype.default_view=p},\n", - " 480: function _(t,o,e,a,i){a();const n=t(1);var u;const s=t(452),c=t(43),_=(0,n.__importStar)(t(318));class r extends s.ButtonGroupView{change_active(t){this.model.active!==t&&(this.model.active=t)}_update_active(){const{active:t}=this.model;this._buttons.forEach(((o,e)=>{(0,c.classes)(o).toggle(_.active,t===e)}))}}e.RadioButtonGroupView=r,r.__name__=\"RadioButtonGroupView\";class l extends s.ButtonGroup{constructor(t){super(t)}}e.RadioButtonGroup=l,u=l,l.__name__=\"RadioButtonGroup\",u.prototype.default_view=r,u.define((({Int:t,Nullable:o})=>({active:[o(t),null]})))},\n", - " 481: function _(e,n,i,t,a){t();const s=e(1);var l;const o=e(43),d=e(34),p=e(455),r=(0,s.__importStar)(e(449));class u extends p.InputGroupView{render(){super.render();const e=(0,o.div)({class:[r.input_group,this.model.inline?r.inline:null]});this.el.appendChild(e);const n=(0,d.uniqueId)(),{active:i,labels:t}=this.model;this._inputs=[];for(let a=0;athis.change_active(a))),this._inputs.push(s),this.model.disabled&&(s.disabled=!0),a==i&&(s.checked=!0);const l=(0,o.label)(s,(0,o.span)(t[a]));e.appendChild(l)}}change_active(e){this.model.active=e}}i.RadioGroupView=u,u.__name__=\"RadioGroupView\";class c extends p.InputGroup{constructor(e){super(e)}}i.RadioGroup=c,l=c,c.__name__=\"RadioGroup\",l.prototype.default_view=u,l.define((({Boolean:e,Int:n,String:i,Array:t,Nullable:a})=>({active:[a(n),null],labels:[t(i),[]],inline:[e,!1]})))},\n", - " 482: function _(e,r,t,a,i){a();var n;const o=(0,e(1).__importStar)(e(153)),s=e(461),_=e(8);class d extends s.AbstractRangeSliderView{}t.RangeSliderView=d,d.__name__=\"RangeSliderView\";class c extends s.AbstractSlider{constructor(e){super(e),this.behaviour=\"drag\",this.connected=[!1,!0,!1]}_formatter(e,r){return(0,_.isString)(r)?o.format(e,r):r.compute(e)}}t.RangeSlider=c,n=c,c.__name__=\"RangeSlider\",n.prototype.default_view=d,n.override({format:\"0[.]00\"})},\n", - " 483: function _(e,t,n,s,i){s();const l=e(1);var u;const a=e(43),o=e(8),p=e(13),_=e(448),r=(0,l.__importStar)(e(449));class c extends _.InputWidgetView{constructor(){super(...arguments),this._known_values=new Set}connect_signals(){super.connect_signals();const{value:e,options:t}=this.model.properties;this.on_change(e,(()=>{this._update_value()})),this.on_change(t,(()=>{(0,a.empty)(this.input_el),(0,a.append)(this.input_el,...this.options_el()),this._update_value()}))}options_el(){const{_known_values:e}=this;function t(t){return t.map((t=>{let n,s;return(0,o.isString)(t)?n=s=t:[n,s]=t,e.add(n),(0,a.option)({value:n},s)}))}e.clear();const{options:n}=this.model;return(0,o.isArray)(n)?t(n):(0,p.entries)(n).map((([e,n])=>(0,a.optgroup)({label:e},t(n))))}render(){super.render(),this.input_el=(0,a.select)({class:r.input,name:this.model.name,disabled:this.model.disabled},this.options_el()),this._update_value(),this.input_el.addEventListener(\"change\",(()=>this.change_input())),this.group_el.appendChild(this.input_el)}change_input(){const e=this.input_el.value;this.model.value=e,super.change_input()}_update_value(){const{value:e}=this.model;this._known_values.has(e)?this.input_el.value=e:this.input_el.removeAttribute(\"value\")}}n.SelectView=c,c.__name__=\"SelectView\";class h extends _.InputWidget{constructor(e){super(e)}}n.Select=h,u=h,h.__name__=\"Select\",u.prototype.default_view=c,u.define((({String:e,Array:t,Tuple:n,Dict:s,Or:i})=>{const l=t(i(e,n(e,e)));return{value:[e,\"\"],options:[i(l,s(l)),[]]}}))},\n", - " 484: function _(e,t,r,i,a){i();var o;const s=(0,e(1).__importStar)(e(153)),_=e(461),n=e(8);class c extends _.AbstractSliderView{}r.SliderView=c,c.__name__=\"SliderView\";class d extends _.AbstractSlider{constructor(e){super(e),this.behaviour=\"tap\",this.connected=[!0,!1]}_formatter(e,t){return(0,n.isString)(t)?s.format(e,t):t.compute(e)}}r.Slider=d,o=d,d.__name__=\"Slider\",o.prototype.default_view=c,o.override({format:\"0[.]00\"})},\n", - " 485: function _(e,t,i,n,s){var l;n();const o=e(478),r=e(43),{min:a,max:h,floor:_,abs:u}=Math;function d(e){return _(e)!==e?e.toFixed(16).replace(/0+$/,\"\").split(\".\")[1].length:0}class p extends o.NumericInputView{*buttons(){yield this.btn_up_el,yield this.btn_down_el}initialize(){super.initialize(),this._handles={interval:void 0,timeout:void 0},this._interval=200}connect_signals(){super.connect_signals();const e=this.model.properties;this.on_change(e.disabled,(()=>{for(const e of this.buttons())(0,r.toggle_attribute)(e,\"disabled\",this.model.disabled)}))}render(){super.render(),this.wrapper_el=(0,r.div)({class:\"bk-spin-wrapper\"}),this.group_el.replaceChild(this.wrapper_el,this.input_el),this.btn_up_el=(0,r.button)({class:\"bk-spin-btn bk-spin-btn-up\"}),this.btn_down_el=(0,r.button)({class:\"bk-spin-btn bk-spin-btn-down\"}),this.wrapper_el.appendChild(this.input_el),this.wrapper_el.appendChild(this.btn_up_el),this.wrapper_el.appendChild(this.btn_down_el);for(const e of this.buttons())(0,r.toggle_attribute)(e,\"disabled\",this.model.disabled),e.addEventListener(\"mousedown\",(e=>this._btn_mouse_down(e))),e.addEventListener(\"mouseup\",(()=>this._btn_mouse_up())),e.addEventListener(\"mouseleave\",(()=>this._btn_mouse_leave()));this.input_el.addEventListener(\"keydown\",(e=>this._input_key_down(e))),this.input_el.addEventListener(\"keyup\",(()=>this.model.value_throttled=this.model.value)),this.input_el.addEventListener(\"wheel\",(e=>this._input_mouse_wheel(e))),this.input_el.addEventListener(\"wheel\",function(e,t,i=!1){let n;return function(...s){const l=this,o=i&&void 0===n;void 0!==n&&clearTimeout(n),n=setTimeout((function(){n=void 0,i||e.apply(l,s)}),t),o&&e.apply(l,s)}}((()=>{this.model.value_throttled=this.model.value}),this.model.wheel_wait,!1))}get precision(){const{low:e,high:t,step:i}=this.model,n=d;return h(n(u(null!=e?e:0)),n(u(null!=t?t:0)),n(u(i)))}remove(){this._stop_incrementation(),super.remove()}_start_incrementation(e){clearInterval(this._handles.interval),this._counter=0;const{step:t}=this.model,i=e=>{if(this._counter+=1,this._counter%5==0){const t=Math.floor(this._counter/5);t<10?(clearInterval(this._handles.interval),this._handles.interval=setInterval((()=>i(e)),this._interval/(t+1))):t>=10&&t<=13&&(clearInterval(this._handles.interval),this._handles.interval=setInterval((()=>i(2*e)),this._interval/10))}this.increment(e)};this._handles.interval=setInterval((()=>i(e*t)),this._interval)}_stop_incrementation(){clearTimeout(this._handles.timeout),this._handles.timeout=void 0,clearInterval(this._handles.interval),this._handles.interval=void 0,this.model.value_throttled=this.model.value}_btn_mouse_down(e){e.preventDefault();const t=e.currentTarget===this.btn_up_el?1:-1;this.increment(t*this.model.step),this.input_el.focus(),this._handles.timeout=setTimeout((()=>this._start_incrementation(t)),this._interval)}_btn_mouse_up(){this._stop_incrementation()}_btn_mouse_leave(){this._stop_incrementation()}_input_mouse_wheel(e){if(document.activeElement===this.input_el){e.preventDefault();const t=e.deltaY>0?-1:1;this.increment(t*this.model.step)}}_input_key_down(e){switch(e.keyCode){case r.Keys.Up:return e.preventDefault(),this.increment(this.model.step);case r.Keys.Down:return e.preventDefault(),this.increment(-this.model.step);case r.Keys.PageUp:return e.preventDefault(),this.increment(this.model.page_step_multiplier*this.model.step);case r.Keys.PageDown:return e.preventDefault(),this.increment(-this.model.page_step_multiplier*this.model.step)}}adjust_to_precision(e){return this.bound_value(Number(e.toFixed(this.precision)))}increment(e){const{low:t,high:i}=this.model;null==this.model.value?e>0?this.model.value=null!=t?t:null!=i?a(0,i):0:e<0&&(this.model.value=null!=i?i:null!=t?h(t,0):0):this.model.value=this.adjust_to_precision(this.model.value+e)}change_input(){super.change_input(),this.model.value_throttled=this.model.value}}i.SpinnerView=p,p.__name__=\"SpinnerView\";class m extends o.NumericInput{constructor(e){super(e)}}i.Spinner=m,l=m,m.__name__=\"Spinner\",l.prototype.default_view=p,l.define((({Number:e,Nullable:t})=>({value_throttled:[t(e),null],step:[e,1],page_step_multiplier:[e,10],wheel_wait:[e,100]}))),l.override({mode:\"float\"})},\n", - " 486: function _(e,t,s,n,i){n();const o=e(1);var r;const c=e(447),l=e(43),p=(0,o.__importStar)(e(449));class _ extends c.TextLikeInputView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.rows.change,(()=>this.input_el.rows=this.model.rows)),this.connect(this.model.properties.cols.change,(()=>this.input_el.cols=this.model.cols))}_render_input(){this.input_el=(0,l.textarea)({class:p.input})}render(){super.render(),this.input_el.cols=this.model.cols,this.input_el.rows=this.model.rows}}s.TextAreaInputView=_,_.__name__=\"TextAreaInputView\";class a extends c.TextLikeInput{constructor(e){super(e)}}s.TextAreaInput=a,r=a,a.__name__=\"TextAreaInput\",r.prototype.default_view=_,r.define((({Int:e})=>({cols:[e,20],rows:[e,2]}))),r.override({max_length:500})},\n", - " 487: function _(e,t,s,c,i){c();const o=e(1);var a;const n=e(441),l=e(43),_=(0,o.__importStar)(e(318));class r extends n.AbstractButtonView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.active.change,(()=>this._update_active()))}render(){super.render(),this._update_active()}click(){this.model.active=!this.model.active,super.click()}_update_active(){(0,l.classes)(this.button_el).toggle(_.active,this.model.active)}}s.ToggleView=r,r.__name__=\"ToggleView\";class g extends n.AbstractButton{constructor(e){super(e)}}s.Toggle=g,a=g,g.__name__=\"Toggle\",a.prototype.default_view=r,a.define((({Boolean:e})=>({active:[e,!1]}))),a.override({label:\"Toggle\"})},\n", - " }, 439, {\"models/widgets/main\":439,\"models/widgets/index\":440,\"models/widgets/abstract_button\":441,\"models/widgets/control\":442,\"models/widgets/widget\":512,\"models/widgets/abstract_icon\":444,\"models/widgets/autocomplete_input\":445,\"models/widgets/text_input\":446,\"models/widgets/text_like_input\":447,\"models/widgets/input_widget\":448,\"styles/widgets/inputs.css\":449,\"models/widgets/button\":450,\"models/widgets/checkbox_button_group\":451,\"models/widgets/button_group\":452,\"models/widgets/oriented_control\":453,\"models/widgets/checkbox_group\":454,\"models/widgets/input_group\":455,\"models/widgets/color_picker\":456,\"models/widgets/date_picker\":457,\"styles/widgets/flatpickr.css\":459,\"models/widgets/date_range_slider\":460,\"models/widgets/abstract_slider\":461,\"styles/widgets/sliders.css\":463,\"styles/widgets/nouislider.css\":464,\"models/widgets/date_slider\":465,\"models/widgets/datetime_range_slider\":466,\"models/widgets/div\":467,\"models/widgets/markup\":468,\"styles/clearfix.css\":469,\"models/widgets/dropdown\":470,\"models/widgets/file_input\":471,\"models/widgets/multiselect\":472,\"models/widgets/paragraph\":473,\"models/widgets/password_input\":474,\"models/widgets/multichoice\":475,\"styles/widgets/choices.css\":477,\"models/widgets/numeric_input\":478,\"models/widgets/pretext\":479,\"models/widgets/radio_button_group\":480,\"models/widgets/radio_group\":481,\"models/widgets/range_slider\":482,\"models/widgets/selectbox\":483,\"models/widgets/slider\":484,\"models/widgets/spinner\":485,\"models/widgets/textarea_input\":486,\"models/widgets/toggle\":487}, {});});\n", - "\n", - " /* END bokeh-widgets.min.js */\n", - " },\n", - " function(Bokeh) {\n", - " /* BEGIN bokeh-tables.min.js */\n", - " /*!\n", - " * Copyright (c) 2012 - 2022, Anaconda, Inc., and Bokeh Contributors\n", - " * All rights reserved.\n", - " * \n", - " * Redistribution and use in source and binary forms, with or without modification,\n", - " * are permitted provided that the following conditions are met:\n", - " * \n", - " * Redistributions of source code must retain the above copyright notice,\n", - " * this list of conditions and the following disclaimer.\n", - " * \n", - " * Redistributions in binary form must reproduce the above copyright notice,\n", - " * this list of conditions and the following disclaimer in the documentation\n", - " * and/or other materials provided with the distribution.\n", - " * \n", - " * Neither the name of Anaconda nor the names of any contributors\n", - " * may be used to endorse or promote products derived from this software\n", - " * without specific prior written permission.\n", - " * \n", - " * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n", - " * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n", - " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n", - " * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n", - " * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n", - " * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n", - " * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n", - " * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n", - " * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n", - " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n", - " * THE POSSIBILITY OF SUCH DAMAGE.\n", - " */\n", - " (function(root, factory) {\n", - " factory(root[\"Bokeh\"], \"2.4.3\");\n", - " })(this, function(Bokeh, version) {\n", - " let define;\n", - " return (function(modules, entry, aliases, externals) {\n", - " const bokeh = typeof Bokeh !== \"undefined\" && (version != null ? Bokeh[version] : Bokeh);\n", - " if (bokeh != null) {\n", - " return bokeh.register_plugin(modules, entry, aliases);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh \" + version + \". You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " 488: function _(t,e,o,r,s){r();const _=(0,t(1).__importStar)(t(489));o.Tables=_;(0,t(7).register_models)(_)},\n", - " 489: function _(g,a,r,e,t){e();const o=g(1);(0,o.__exportStar)(g(490),r),(0,o.__exportStar)(g(493),r),t(\"DataTable\",g(496).DataTable),t(\"TableColumn\",g(514).TableColumn),t(\"TableWidget\",g(513).TableWidget);var n=g(516);t(\"AvgAggregator\",n.AvgAggregator),t(\"MinAggregator\",n.MinAggregator),t(\"MaxAggregator\",n.MaxAggregator),t(\"SumAggregator\",n.SumAggregator);var A=g(517);t(\"GroupingInfo\",A.GroupingInfo),t(\"DataCube\",A.DataCube)},\n", - " 490: function _(e,t,i,s,a){s();const r=e(1);var l,n,u,d,o,p,_,c,h;const E=e(43),V=e(226),m=e(53),f=e(491),v=(0,r.__importStar)(e(492));class w extends V.DOMView{constructor(e){const{model:t,parent:i}=e.column;super(Object.assign({model:t,parent:i},e)),this.args=e,this.initialize(),this.render()}get emptyValue(){return null}initialize(){super.initialize(),this.inputEl=this._createInput(),this.defaultValue=null}async lazy_initialize(){throw new Error(\"unsupported\")}css_classes(){return super.css_classes().concat(v.cell_editor)}render(){super.render(),this.args.container.append(this.el),this.el.appendChild(this.inputEl),this.renderEditor(),this.disableNavigation()}renderEditor(){}disableNavigation(){this.inputEl.addEventListener(\"keydown\",(e=>{switch(e.keyCode){case E.Keys.Left:case E.Keys.Right:case E.Keys.Up:case E.Keys.Down:case E.Keys.PageUp:case E.Keys.PageDown:e.stopImmediatePropagation()}}))}destroy(){this.remove()}focus(){this.inputEl.focus()}show(){}hide(){}position(){}getValue(){return this.inputEl.value}setValue(e){this.inputEl.value=e}serializeValue(){return this.getValue()}isValueChanged(){return!(\"\"==this.getValue()&&null==this.defaultValue)&&this.getValue()!==this.defaultValue}applyValue(e,t){const i=this.args.grid.getData(),s=i.index.indexOf(e[f.DTINDEX_NAME]);i.setField(s,this.args.column.field,t)}loadValue(e){const t=e[this.args.column.field];this.defaultValue=null!=t?t:this.emptyValue,this.setValue(this.defaultValue)}validateValue(e){if(this.args.column.validator){const t=this.args.column.validator(e);if(!t.valid)return t}return{valid:!0,msg:null}}validate(){return this.validateValue(this.getValue())}}i.CellEditorView=w,w.__name__=\"CellEditorView\";class g extends m.Model{}i.CellEditor=g,g.__name__=\"CellEditor\";class x extends w{get emptyValue(){return\"\"}_createInput(){return(0,E.input)({type:\"text\"})}renderEditor(){this.inputEl.focus(),this.inputEl.select()}loadValue(e){super.loadValue(e),this.inputEl.defaultValue=this.defaultValue,this.inputEl.select()}}i.StringEditorView=x,x.__name__=\"StringEditorView\";class y extends g{}i.StringEditor=y,l=y,y.__name__=\"StringEditor\",l.prototype.default_view=x,l.define((({String:e,Array:t})=>({completions:[t(e),[]]})));class I extends w{_createInput(){return(0,E.textarea)()}renderEditor(){this.inputEl.focus(),this.inputEl.select()}}i.TextEditorView=I,I.__name__=\"TextEditorView\";class b extends g{}i.TextEditor=b,n=b,b.__name__=\"TextEditor\",n.prototype.default_view=I;class N extends w{_createInput(){return(0,E.select)()}renderEditor(){for(const e of this.model.options)this.inputEl.appendChild((0,E.option)({value:e},e));this.focus()}}i.SelectEditorView=N,N.__name__=\"SelectEditorView\";class C extends g{}i.SelectEditor=C,u=C,C.__name__=\"SelectEditor\",u.prototype.default_view=N,u.define((({String:e,Array:t})=>({options:[t(e),[]]})));class D extends w{_createInput(){return(0,E.input)({type:\"text\"})}}i.PercentEditorView=D,D.__name__=\"PercentEditorView\";class S extends g{}i.PercentEditor=S,d=S,S.__name__=\"PercentEditor\",d.prototype.default_view=D;class k extends w{_createInput(){return(0,E.input)({type:\"checkbox\"})}renderEditor(){this.focus()}loadValue(e){this.defaultValue=!!e[this.args.column.field],this.inputEl.checked=this.defaultValue}serializeValue(){return this.inputEl.checked}}i.CheckboxEditorView=k,k.__name__=\"CheckboxEditorView\";class z extends g{}i.CheckboxEditor=z,o=z,z.__name__=\"CheckboxEditor\",o.prototype.default_view=k;class P extends w{_createInput(){return(0,E.input)({type:\"text\"})}renderEditor(){this.inputEl.focus(),this.inputEl.select()}remove(){super.remove()}serializeValue(){var e;return null!==(e=parseInt(this.getValue(),10))&&void 0!==e?e:0}loadValue(e){super.loadValue(e),this.inputEl.defaultValue=this.defaultValue,this.inputEl.select()}validateValue(e){return isNaN(e)?{valid:!1,msg:\"Please enter a valid integer\"}:super.validateValue(e)}}i.IntEditorView=P,P.__name__=\"IntEditorView\";class T extends g{}i.IntEditor=T,p=T,T.__name__=\"IntEditor\",p.prototype.default_view=P,p.define((({Int:e})=>({step:[e,1]})));class K extends w{_createInput(){return(0,E.input)({type:\"text\"})}renderEditor(){this.inputEl.focus(),this.inputEl.select()}remove(){super.remove()}serializeValue(){var e;return null!==(e=parseFloat(this.getValue()))&&void 0!==e?e:0}loadValue(e){super.loadValue(e),this.inputEl.defaultValue=this.defaultValue,this.inputEl.select()}validateValue(e){return isNaN(e)?{valid:!1,msg:\"Please enter a valid number\"}:super.validateValue(e)}}i.NumberEditorView=K,K.__name__=\"NumberEditorView\";class A extends g{}i.NumberEditor=A,_=A,A.__name__=\"NumberEditor\",_.prototype.default_view=K,_.define((({Number:e})=>({step:[e,.01]})));class M extends w{_createInput(){return(0,E.input)({type:\"text\"})}}i.TimeEditorView=M,M.__name__=\"TimeEditorView\";class O extends g{}i.TimeEditor=O,c=O,O.__name__=\"TimeEditor\",c.prototype.default_view=M;class F extends w{_createInput(){return(0,E.input)({type:\"text\"})}get emptyValue(){return new Date}renderEditor(){this.inputEl.focus(),this.inputEl.select()}destroy(){super.destroy()}show(){super.show()}hide(){super.hide()}position(){return super.position()}getValue(){}setValue(e){}}i.DateEditorView=F,F.__name__=\"DateEditorView\";class L extends g{}i.DateEditor=L,h=L,L.__name__=\"DateEditor\",h.prototype.default_view=F},\n", - " 491: function _(_,n,i,t,d){t(),i.DTINDEX_NAME=\"__bkdt_internal_index__\"},\n", - " 492: function _(e,l,o,t,r){t(),o.root=\"bk-root\",o.data_table=\"bk-data-table\",o.cell_special_defaults=\"bk-cell-special-defaults\",o.cell_select=\"bk-cell-select\",o.cell_index=\"bk-cell-index\",o.header_index=\"bk-header-index\",o.cell_editor=\"bk-cell-editor\",o.cell_editor_completion=\"bk-cell-editor-completion\",o.default='.bk-root .bk-data-table{box-sizing:content-box;font-size:11px;}.bk-root .bk-data-table input[type=\"checkbox\"]{margin-left:4px;margin-right:4px;}.bk-root .bk-cell-special-defaults{border-right-color:silver;border-right-style:solid;background:#f5f5f5;}.bk-root .bk-cell-select{border-right-color:silver;border-right-style:solid;background:#f5f5f5;}.bk-root .slick-cell.bk-cell-index{border-right-color:silver;border-right-style:solid;background:#f5f5f5;text-align:right;background:#f0f0f0;color:#909090;}.bk-root .bk-header-index .slick-column-name{float:right;}.bk-root .slick-row.selected .bk-cell-index{background-color:transparent;}.bk-root .slick-row.odd{background:#f0f0f0;}.bk-root .slick-cell{padding-left:4px;padding-right:4px;border-right-color:transparent;border:0.25px solid transparent;}.bk-root .slick-cell .bk{line-height:inherit;}.bk-root .slick-cell.active{border-style:dashed;}.bk-root .slick-cell.selected{background-color:#F0F8FF;}.bk-root .slick-cell.editable{padding-left:0;padding-right:0;}.bk-root .bk-cell-editor{display:contents;}.bk-root .bk-cell-editor input,.bk-root .bk-cell-editor select{width:100%;height:100%;border:0;margin:0;padding:0;outline:0;background:transparent;vertical-align:baseline;}.bk-root .bk-cell-editor input{padding-left:4px;padding-right:4px;}.bk-root .bk-cell-editor-completion{font-size:11px;}'},\n", - " 493: function _(t,e,r,n,o){n();const a=t(1);var s,i,l,c,u,m;const _=(0,a.__importDefault)(t(151)),d=(0,a.__importStar)(t(153)),f=t(494),g=t(43),F=t(20),h=t(8),p=t(34),S=t(22),x=t(53);class b extends x.Model{constructor(t){super(t)}doFormat(t,e,r,n,o){return null==r?\"\":`${r}`.replace(/&/g,\"&\").replace(//g,\">\")}}r.CellFormatter=b,b.__name__=\"CellFormatter\";class M extends b{constructor(t){super(t)}doFormat(t,e,r,n,o){const{font_style:a,text_align:s,text_color:i}=this,l=(0,g.div)(null==r?\"\":`${r}`);switch(a){case\"bold\":l.style.fontWeight=\"bold\";break;case\"italic\":l.style.fontStyle=\"italic\"}return null!=s&&(l.style.textAlign=s),null!=i&&(l.style.color=(0,S.color2css)(i)),l.outerHTML}}r.StringFormatter=M,s=M,M.__name__=\"StringFormatter\",s.define((({Color:t,Nullable:e,String:r})=>({font_style:[F.FontStyle,\"normal\"],text_align:[F.TextAlign,\"left\"],text_color:[e(t),null],nan_format:[r,\"-\"]})));class w extends M{constructor(t){super(t)}get scientific_limit_low(){return 10**this.power_limit_low}get scientific_limit_high(){return 10**this.power_limit_high}doFormat(t,e,r,n,o){const a=Math.abs(r)<=this.scientific_limit_low||Math.abs(r)>=this.scientific_limit_high;let s=this.precision;return s<1&&(s=1),r=null==r||isNaN(r)?this.nan_format:0==r?(0,p.to_fixed)(r,1):a?r.toExponential(s):(0,p.to_fixed)(r,s),super.doFormat(t,e,r,n,o)}}r.ScientificFormatter=w,i=w,w.__name__=\"ScientificFormatter\",i.define((({Number:t})=>({precision:[t,10],power_limit_high:[t,5],power_limit_low:[t,-3]})));class C extends M{constructor(t){super(t)}doFormat(t,e,r,n,o){const{format:a,language:s,nan_format:i}=this,l=(()=>{switch(this.rounding){case\"round\":case\"nearest\":return Math.round;case\"floor\":case\"rounddown\":return Math.floor;case\"ceil\":case\"roundup\":return Math.ceil}})();return r=null==r||isNaN(r)?i:d.format(r,a,s,l),super.doFormat(t,e,r,n,o)}}r.NumberFormatter=C,l=C,C.__name__=\"NumberFormatter\",l.define((({String:t})=>({format:[t,\"0,0\"],language:[t,\"en\"],rounding:[F.RoundingFunction,\"round\"]})));class y extends b{constructor(t){super(t)}doFormat(t,e,r,n,o){return r?(0,g.i)({class:this.icon}).outerHTML:\"\"}}r.BooleanFormatter=y,c=y,y.__name__=\"BooleanFormatter\",c.define((({String:t})=>({icon:[t,\"check\"]})));class N extends M{constructor(t){super(t)}getFormat(){switch(this.format){case\"ATOM\":case\"W3C\":case\"RFC-3339\":case\"ISO-8601\":return\"%Y-%m-%d\";case\"COOKIE\":return\"%a, %d %b %Y\";case\"RFC-850\":return\"%A, %d-%b-%y\";case\"RFC-1123\":case\"RFC-2822\":return\"%a, %e %b %Y\";case\"RSS\":case\"RFC-822\":case\"RFC-1036\":return\"%a, %e %b %y\";case\"TIMESTAMP\":return;default:return this.format}}doFormat(t,e,r,n,o){const{nan_format:a}=this;let s;return s=null==(r=(0,h.isString)(r)?parseInt(r,10):r)||isNaN(r)||-9223372036854776===r?a:(0,_.default)(r,this.getFormat()),super.doFormat(t,e,s,n,o)}}r.DateFormatter=N,u=N,N.__name__=\"DateFormatter\",u.define((({String:t})=>({format:[t,\"ISO-8601\"]})));class T extends b{constructor(t){super(t)}doFormat(t,e,r,n,o){const{template:a}=this;if(null==r)return\"\";return f._.template(a)(Object.assign(Object.assign({},o),{value:r}))}}r.HTMLTemplateFormatter=T,m=T,T.__name__=\"HTMLTemplateFormatter\",m.define((({String:t})=>({template:[t,\"<%= value %>\"]})))},\n", - " 494: function _(e,n,t,f,i){var o=e(495),d=o.template;function r(e,n,t){return d(e,n,t)}r._=o,n.exports=r,\"function\"==typeof define&&define.amd?define((function(){return r})):\"undefined\"==typeof window&&\"undefined\"==typeof navigator||(window.UnderscoreTemplate=r)},\n", - " 495: function _(r,e,n,t,a){\n", - " // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n", - " // Underscore may be freely distributed under the MIT license.\n", - " var u={},c=Array.prototype,o=Object.prototype,l=c.slice,i=o.toString,f=o.hasOwnProperty,s=c.forEach,p=Object.keys,_=Array.isArray,h=function(){},v=h.each=h.forEach=function(r,e,n){if(null!=r)if(s&&r.forEach===s)r.forEach(e,n);else if(r.length===+r.length){for(var t=0,a=r.length;t\":\">\",'\"':\""\",\"'\":\"'\"}},y={escape:new RegExp(\"[\"+h.keys(g.escape).join(\"\")+\"]\",\"g\")};h.each([\"escape\"],(function(r){h[r]=function(e){return null==e?\"\":(\"\"+e).replace(y[r],(function(e){return g[r][e]}))}})),h.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g};var j=/(.)^/,b={\"'\":\"'\",\"\\\\\":\"\\\\\",\"\\r\":\"r\",\"\\n\":\"n\",\"\\t\":\"t\",\"\\u2028\":\"u2028\",\"\\u2029\":\"u2029\"},w=/\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;h.template=function(r,e,n){var t;n=h.defaults({},n,h.templateSettings);var a=new RegExp([(n.escape||j).source,(n.interpolate||j).source,(n.evaluate||j).source].join(\"|\")+\"|$\",\"g\"),u=0,c=\"__p+='\";r.replace(a,(function(e,n,t,a,o){return c+=r.slice(u,o).replace(w,(function(r){return\"\\\\\"+b[r]})),n&&(c+=\"'+\\n((__t=(\"+n+\"))==null?'':_.escape(__t))+\\n'\"),t&&(c+=\"'+\\n((__t=(\"+t+\"))==null?'':__t)+\\n'\"),a&&(c+=\"';\\n\"+a+\"\\n__p+='\"),u=o+e.length,e})),c+=\"';\\n\",n.variable||(c=\"with(obj||{}){\\n\"+c+\"}\\n\"),c=\"var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\\n\"+c+\"return __p;\\n\";try{t=new Function(n.variable||\"obj\",\"_\",c)}catch(r){throw r.source=c,r}if(e)return t(e,h);var o=function(r){return t.call(this,r,h)};return o.source=\"function(\"+(n.variable||\"obj\")+\"){\\n\"+c+\"}\",o},e.exports=h},\n", - " 496: function _(e,t,i,s,o){s();const n=e(1);var l;const r=e(497),d=e(501),a=e(502),h=e(503),u=e(34),c=e(8),_=e(9),m=e(13),g=e(19),p=e(512),f=e(491),b=e(513),w=e(514),x=(0,n.__importStar)(e(492)),C=x,v=(0,n.__importDefault)(e(515));i.AutosizeModes={fit_columns:\"FCV\",fit_viewport:\"FVC\",force_fit:\"LFF\",none:\"NOA\"};let z=!1;class A{constructor(e,t){this.init(e,t)}init(e,t){if(f.DTINDEX_NAME in e.data)throw new Error(`special name ${f.DTINDEX_NAME} cannot be used as a data table column`);this.source=e,this.view=t,this.index=[...this.view.indices]}getLength(){return this.index.length}getItem(e){const t={};for(const i of(0,m.keys)(this.source.data))t[i]=this.source.data[i][this.index[e]];return t[f.DTINDEX_NAME]=this.index[e],t}getField(e,t){return t==f.DTINDEX_NAME?this.index[e]:this.source.data[t][this.index[e]]}setField(e,t,i){const s=this.index[e];this.source.patch({[t]:[[s,i]]})}getRecords(){return(0,_.range)(0,this.getLength()).map((e=>this.getItem(e)))}getItems(){return this.getRecords()}slice(e,t,i){return e=null!=e?e:0,t=null!=t?t:this.getLength(),i=null!=i?i:1,(0,_.range)(e,t,i).map((e=>this.getItem(e)))}sort(e){let t=e.map((e=>[e.sortCol.field,e.sortAsc?1:-1]));0==t.length&&(t=[[f.DTINDEX_NAME,1]]);const i=this.getRecords(),s=this.index.slice();this.index.sort(((e,o)=>{for(const[n,l]of t){const t=i[s.indexOf(e)][n],r=i[s.indexOf(o)][n];if(t!==r)return(0,c.isNumber)(t)&&(0,c.isNumber)(r)?l*(t-r||+isNaN(t)-+isNaN(r)):`${t}`>`${r}`?l:-l}return 0}))}}i.TableDataProvider=A,A.__name__=\"TableDataProvider\";class M extends p.WidgetView{constructor(){super(...arguments),this._in_selection_update=!1,this._width=null}connect_signals(){super.connect_signals(),this.connect(this.model.change,(()=>this.render())),this.connect(this.model.source.streaming,(()=>this.updateGrid())),this.connect(this.model.source.patching,(()=>this.updateGrid())),this.connect(this.model.source.change,(()=>this.updateGrid())),this.connect(this.model.source.properties.data.change,(()=>this.updateGrid())),this.connect(this.model.source.selected.change,(()=>this.updateSelection())),this.connect(this.model.source.selected.properties.indices.change,(()=>this.updateSelection()));for(const e of this.model.columns)this.connect(e.change,(()=>{this.invalidate_layout(),this.render()}))}remove(){var e;null===(e=this.grid)||void 0===e||e.destroy(),super.remove()}styles(){return[...super.styles(),v.default,x.default]}update_position(){super.update_position(),this.grid.resizeCanvas()}after_layout(){super.after_layout(),this.updateLayout(!0,!1)}box_sizing(){const e=super.box_sizing();return\"fit_viewport\"===this.model.autosize_mode&&null!=this._width&&(e.width=this._width),e}updateLayout(e,t){const s=this.autosize;s===i.AutosizeModes.fit_columns||s===i.AutosizeModes.force_fit?(e||this.grid.resizeCanvas(),this.grid.autosizeColumns()):e&&t&&s===i.AutosizeModes.fit_viewport&&this.invalidate_layout()}updateGrid(){if(this.model.view.compute_indices(),this.data.init(this.model.source,this.model.view),this.model.sortable){const e=this.grid.getColumns(),t=this.grid.getSortColumns().map((t=>({sortCol:{field:e[this.grid.getColumnIndex(t.columnId)].field},sortAsc:t.sortAsc})));this.data.sort(t)}this.grid.invalidate(),this.updateLayout(!0,!0)}updateSelection(){if(this._in_selection_update)return;const{selected:e}=this.model.source,t=e.indices.map((e=>this.data.index.indexOf(e))).sort();this._in_selection_update=!0,this.grid.setSelectedRows(t),this._in_selection_update=!1;const i=this.grid.getViewport(),s=this.model.get_scroll_index(i,t);null!=s&&this.grid.scrollRowToTop(s)}newIndexColumn(){return{id:(0,u.uniqueId)(),name:this.model.index_header,field:f.DTINDEX_NAME,width:this.model.index_width,behavior:\"select\",cannotTriggerInsert:!0,resizable:!1,selectable:!1,sortable:!0,cssClass:C.cell_index,headerCssClass:C.header_index}}css_classes(){return super.css_classes().concat(C.data_table)}get autosize(){let e;return e=!0===this.model.fit_columns?i.AutosizeModes.force_fit:!1===this.model.fit_columns?i.AutosizeModes.none:i.AutosizeModes[this.model.autosize_mode],e}render(){var e;const t=this.model.columns.filter((e=>e.visible)).map((e=>Object.assign(Object.assign({},e.toColumn()),{parent:this})));let s=null;if(\"checkbox\"==this.model.selectable&&(s=new d.CheckboxSelectColumn({cssClass:C.cell_select}),t.unshift(s.getColumnDefinition())),null!=this.model.index_position){const e=this.model.index_position,i=this.newIndexColumn();-1==e?t.push(i):e<-1?t.splice(e+1,0,i):t.splice(e,0,i)}let{reorderable:o}=this.model;!o||\"undefined\"!=typeof $&&null!=$.fn&&null!=$.fn.sortable||(z||(g.logger.warn(\"jquery-ui is required to enable DataTable.reorderable\"),z=!0),o=!1);let n=-1,l=!1;const{frozen_rows:u,frozen_columns:_}=this.model,m=null==_?-1:_-1;null!=u&&(l=u<0,n=Math.abs(u));const p={enableCellNavigation:!1!==this.model.selectable,enableColumnReorder:o,autosizeColsMode:this.autosize,multiColumnSort:this.model.sortable,editable:this.model.editable,autoEdit:this.model.auto_edit,autoHeight:!1,rowHeight:this.model.row_height,frozenColumn:m,frozenRow:n,frozenBottom:l},f=null!=this.grid;if(this.data=new A(this.model.source,this.model.view),this.grid=new h.Grid(this.el,this.data,t,p),this.autosize==i.AutosizeModes.fit_viewport){this.grid.autosizeColumns();let i=0;for(const s of t)i+=null!==(e=s.width)&&void 0!==e?e:0;this._width=Math.ceil(i)}if(this.grid.onSort.subscribe(((e,t)=>{if(!this.model.sortable)return;const i=t.sortCols;null!=i&&(this.data.sort(i),this.grid.invalidate(),this.updateSelection(),this.grid.render(),this.model.header_row||this._hide_header(),this.model.update_sort_columns(i))})),!1!==this.model.selectable){this.grid.setSelectionModel(new r.RowSelectionModel({selectActiveRow:null==s})),null!=s&&this.grid.registerPlugin(s);const e={dataItemColumnValueExtractor(e,t){let i=e[t.field];return(0,c.isString)(i)&&(i=i.replace(/\\n/g,\"\\\\n\")),i},includeHeaderWhenCopying:!1};this.grid.registerPlugin(new a.CellExternalCopyManager(e)),this.grid.onSelectedRowsChanged.subscribe(((e,t)=>{this._in_selection_update||(this.model.source.selected.indices=t.rows.map((e=>this.data.index[e])))})),this.updateSelection(),this.model.header_row||this._hide_header()}f&&this.updateLayout(f,!1)}_hide_header(){for(const e of this.el.querySelectorAll(\".slick-header-columns\"))e.style.height=\"0px\";this.grid.resizeCanvas()}}i.DataTableView=M,M.__name__=\"DataTableView\";class D extends b.TableWidget{constructor(e){super(e),this._sort_columns=[]}get sort_columns(){return this._sort_columns}update_sort_columns(e){this._sort_columns=e.map((({sortCol:e,sortAsc:t})=>({field:e.field,sortAsc:t})))}get_scroll_index(e,t){return this.scroll_to_selection&&0!=t.length?(0,_.some)(t,(t=>e.top<=t&&t<=e.bottom))?null:Math.max(0,Math.min(...t)-1):null}}i.DataTable=D,l=D,D.__name__=\"DataTable\",l.prototype.default_view=M,l.define((({Array:e,Boolean:t,Int:i,Ref:s,String:o,Enum:n,Or:l,Nullable:r})=>({autosize_mode:[n(\"fit_columns\",\"fit_viewport\",\"none\",\"force_fit\"),\"force_fit\"],auto_edit:[t,!1],columns:[e(s(w.TableColumn)),[]],fit_columns:[r(t),null],frozen_columns:[r(i),null],frozen_rows:[r(i),null],sortable:[t,!0],reorderable:[t,!0],editable:[t,!1],selectable:[l(t,n(\"checkbox\")),!0],index_position:[r(i),0],index_header:[o,\"#\"],index_width:[i,40],scroll_to_selection:[t,!0],header_row:[t,!0],row_height:[i,25]}))),l.override({width:600,height:400})},\n", - " 497: function _(e,t,n,o,r){var l=e(498),i=e(500);t.exports={RowSelectionModel:function(e){var t,n,o,r=[],c=this,u=new i.EventHandler,s={selectActiveRow:!0};function a(e){return function(){n||(n=!0,e.apply(this,arguments),n=!1)}}function f(e){for(var t=[],n=0;n=0&&r0&&t-1 in e)}w.fn=w.prototype={jquery:b,constructor:w,length:0,toArray:function(){return i.call(this)},get:function(e){return null==e?i.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(i.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(w.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(w.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|[\\\\x20\\\\t\\\\r\\\\n\\\\f])[\\\\x20\\\\t\\\\r\\\\n\\\\f]*\"),U=new RegExp(M+\"|>\"),X=new RegExp(F),V=new RegExp(\"^\"+I+\"$\"),G={ID:new RegExp(\"^#(\"+I+\")\"),CLASS:new RegExp(\"^\\\\.(\"+I+\")\"),TAG:new RegExp(\"^(\"+I+\"|[*])\"),ATTR:new RegExp(\"^\"+W),PSEUDO:new RegExp(\"^\"+F),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\([\\\\x20\\\\t\\\\r\\\\n\\\\f]*(even|odd|(([+-]|)(\\\\d*)n|)[\\\\x20\\\\t\\\\r\\\\n\\\\f]*(?:([+-]|)[\\\\x20\\\\t\\\\r\\\\n\\\\f]*(\\\\d+)|))[\\\\x20\\\\t\\\\r\\\\n\\\\f]*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+R+\")$\",\"i\"),needsContext:new RegExp(\"^[\\\\x20\\\\t\\\\r\\\\n\\\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\([\\\\x20\\\\t\\\\r\\\\n\\\\f]*((?:-\\\\d)?\\\\d*)[\\\\x20\\\\t\\\\r\\\\n\\\\f]*\\\\)|)(?=[^-]|$)\",\"i\")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\\d$/i,K=/^[^{]+\\{\\s*\\[native \\w/,Z=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ee=/[+~]/,te=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}[\\\\x20\\\\t\\\\r\\\\n\\\\f]?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),ne=function(e,t){var n=\"0x\"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,ie=function(e,t){return t?\"\\0\"===e?\"\\ufffd\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},oe=function(){p()},ae=be((function(e){return!0===e.disabled&&\"fieldset\"===e.nodeName.toLowerCase()}),{dir:\"parentNode\",next:\"legend\"});try{H.apply(D=O.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(e){H={apply:D.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(e,t,r,i){var o,s,l,c,f,h,y,m=t&&t.ownerDocument,w=t?t.nodeType:9;if(r=r||[],\"string\"!=typeof e||!e||1!==w&&9!==w&&11!==w)return r;if(!i&&(p(t),t=t||d,g)){if(11!==w&&(f=Z.exec(e)))if(o=f[1]){if(9===w){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return H.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return H.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!A[e+\" \"]&&(!v||!v.test(e))&&(1!==w||\"object\"!==t.nodeName.toLowerCase())){if(y=e,m=t,1===w&&(U.test(e)||z.test(e))){for((m=ee.test(e)&&ye(t.parentNode)||t)===t&&n.scope||((c=t.getAttribute(\"id\"))?c=c.replace(re,ie):t.setAttribute(\"id\",c=b)),s=(h=a(e)).length;s--;)h[s]=(c?\"#\"+c:\":scope\")+\" \"+xe(h[s]);y=h.join(\",\")}try{return H.apply(r,m.querySelectorAll(y)),r}catch(t){A(e,!0)}finally{c===b&&t.removeAttribute(\"id\")}}}return u(e.replace($,\"$1\"),t,r,i)}function ue(){var e=[];return function t(n,i){return e.push(n+\" \")>r.cacheLength&&delete t[e.shift()],t[n+\" \"]=i}}function le(e){return e[b]=!0,e}function ce(e){var t=d.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){for(var n=e.split(\"|\"),i=n.length;i--;)r.attrHandle[n[i]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function de(e){return function(t){return\"input\"===t.nodeName.toLowerCase()&&t.type===e}}function he(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function ge(e){return function(t){return\"form\"in t?t.parentNode&&!1===t.disabled?\"label\"in t?\"label\"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:\"label\"in t&&t.disabled===e}}function ve(e){return le((function(t){return t=+t,le((function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))}))}))}function ye(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=se.support={},o=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||\"HTML\")},p=se.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!=d&&9===a.nodeType&&a.documentElement?(h=(d=a).documentElement,g=!o(d),w!=d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener(\"unload\",oe,!1):i.attachEvent&&i.attachEvent(\"onunload\",oe)),n.scope=ce((function(e){return h.appendChild(e).appendChild(d.createElement(\"div\")),void 0!==e.querySelectorAll&&!e.querySelectorAll(\":scope fieldset div\").length})),n.attributes=ce((function(e){return e.className=\"i\",!e.getAttribute(\"className\")})),n.getElementsByTagName=ce((function(e){return e.appendChild(d.createComment(\"\")),!e.getElementsByTagName(\"*\").length})),n.getElementsByClassName=K.test(d.getElementsByClassName),n.getById=ce((function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length})),n.getById?(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute(\"id\")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&g)return t.getElementsByClassName(e)},y=[],v=[],(n.qsa=K.test(d.querySelectorAll))&&(ce((function(e){var t;h.appendChild(e).innerHTML=\"\",e.querySelectorAll(\"[msallowcapture^='']\").length&&v.push(\"[*^$]=[\\\\x20\\\\t\\\\r\\\\n\\\\f]*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||v.push(\"\\\\[[\\\\x20\\\\t\\\\r\\\\n\\\\f]*(?:value|\"+R+\")\"),e.querySelectorAll(\"[id~=\"+b+\"-]\").length||v.push(\"~=\"),(t=d.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||v.push(\"\\\\[[\\\\x20\\\\t\\\\r\\\\n\\\\f]*name[\\\\x20\\\\t\\\\r\\\\n\\\\f]*=[\\\\x20\\\\t\\\\r\\\\n\\\\f]*(?:''|\\\"\\\")\"),e.querySelectorAll(\":checked\").length||v.push(\":checked\"),e.querySelectorAll(\"a#\"+b+\"+*\").length||v.push(\".#.+[+~]\"),e.querySelectorAll(\"\\\\\\f\"),v.push(\"[\\\\r\\\\n\\\\f]\")})),ce((function(e){e.innerHTML=\"\";var t=d.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&v.push(\"name[\\\\x20\\\\t\\\\r\\\\n\\\\f]*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&v.push(\":enabled\",\":disabled\"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&v.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),v.push(\",.*:\")}))),(n.matchesSelector=K.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ce((function(e){n.disconnectedMatch=m.call(e,\"*\"),m.call(e,\"[s!='']:x\"),y.push(\"!=\",F)})),v=v.length&&new RegExp(v.join(\"|\")),y=y.length&&new RegExp(y.join(\"|\")),t=K.test(h.compareDocumentPosition),x=t||K.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},N=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==d||e.ownerDocument==w&&x(w,e)?-1:t==d||t.ownerDocument==w&&x(w,t)?1:c?P(c,e)-P(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==d?-1:t==d?1:i?-1:o?1:c?P(c,e)-P(c,t):0;if(i===o)return pe(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?pe(a[r],s[r]):a[r]==w?-1:s[r]==w?1:0},d):d},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(p(e),n.matchesSelector&&g&&!A[t+\" \"]&&(!y||!y.test(t))&&(!v||!v.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){A(t,!0)}return se(t,d,null,[e]).length>0},se.contains=function(e,t){return(e.ownerDocument||e)!=d&&p(e),x(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&j.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},se.escape=function(e){return(e+\"\").replace(re,ie)},se.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},se.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(N),f){for(;t=e[o++];)t===e[o]&&(i=r.push(o));for(;i--;)e.splice(r[i],1)}return c=null,e},i=se.getText=function(e){var t,n=\"\",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=i(t);return n},r=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||\"\").replace(te,ne),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+\" \"];return t||(t=new RegExp(\"(^|[\\\\x20\\\\t\\\\r\\\\n\\\\f])\"+e+\"(\"+M+\"|$)\"))&&E(e,(function(e){return t.test(\"string\"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute(\"class\")||\"\")}))},ATTR:function(e,t,n){return function(r){var i=se.attr(r,e);return null==i?\"!=\"===t:!t||(i+=\"\",\"=\"===t?i===n:\"!=\"===t?i!==n:\"^=\"===t?n&&0===i.indexOf(n):\"*=\"===t?n&&i.indexOf(n)>-1:\"$=\"===t?n&&i.slice(-n.length)===n:\"~=\"===t?(\" \"+i.replace(B,\" \")+\" \").indexOf(n)>-1:\"|=\"===t&&(i===n||i.slice(0,n.length+1)===n+\"-\"))}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?\"nextSibling\":\"previousSibling\",v=t.parentNode,y=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(v){if(o){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g=\"only\"===e&&!h&&\"nextSibling\"}return!0}if(h=[a?v.firstChild:v.lastChild],a&&m){for(x=(d=(l=(c=(f=(p=v)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&v.childNodes[d];p=++d&&p&&p[g]||(x=d=0)||h.pop();)if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)for(;(p=++d&&p&&p[g]||(x=d=0)||h.pop())&&((s?p.nodeName.toLowerCase()!==y:1!==p.nodeType)||!++x||(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||se.error(\"unsupported pseudo: \"+e);return i[b]?i(t):i.length>1?(n=[e,e,\"\",t],r.setFilters.hasOwnProperty(e.toLowerCase())?le((function(e,n){for(var r,o=i(e,t),a=o.length;a--;)e[r=P(e,o[a])]=!(n[r]=o[a])})):function(e){return i(e,0,n)}):i}},pseudos:{not:le((function(e){var t=[],n=[],r=s(e.replace($,\"$1\"));return r[b]?le((function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))})):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}})),has:le((function(e){return function(t){return se(e,t).length>0}})),contains:le((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||i(t)).indexOf(e)>-1}})),lang:le((function(e){return V.test(e||\"\")||se.error(\"unsupported lang: \"+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return(n=n.toLowerCase())===e||0===n.indexOf(e+\"-\")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:ve((function(){return[0]})),last:ve((function(e,t){return[t-1]})),eq:ve((function(e,t,n){return[n<0?n+t:n]})),even:ve((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:ve((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s-1&&(o[l]=!(a[l]=f))}}else y=Te(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)}))}function Ee(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[\" \"],u=a?1:0,c=be((function(e){return e===t}),s,!0),f=be((function(e){return P(t,e)>-1}),s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&we(p),u>1&&xe(e.slice(0,u-1).concat({value:\" \"===e[u-2].type?\"*\":\"\"})).replace($,\"$1\"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,v,y=0,m=\"0\",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG(\"*\",c),E=T+=null==w?1:Math.random()||.1,S=C.length;for(c&&(l=a==d||a||c);m!==S&&null!=(f=C[m]);m++){if(i&&f){for(h=0,a||f.ownerDocument==d||(p(f),s=!g);v=e[h++];)if(v(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!v&&f)&&y--,o&&x.push(f))}if(y+=m,n&&m!==y){for(h=0;v=t[h++];)v(x,b,a,s);if(o){if(y>0)for(;m--;)x[m]||b[m]||(b[m]=q.call(u));b=Te(b)}H.apply(u,b),c&&!o&&b.length>0&&y+t.length>1&&se.uniqueSort(u)}return c&&(T=E,l=w),x};return n?le(o):o}(o,i)),s.selector=e}return s},u=se.select=function(e,t,n,i){var o,u,l,c,f,p=\"function\"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&\"ID\"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(te,ne),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}for(o=G.needsContext.test(e)?0:u.length;o--&&(l=u[o],!r.relative[c=l.type]);)if((f=r.find[c])&&(i=f(l.matches[0].replace(te,ne),ee.test(u[0].type)&&ye(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&xe(u)))return H.apply(n,i),n;break}}return(p||s(e,d))(i,t,!g,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},n.sortStable=b.split(\"\").sort(N).join(\"\")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ce((function(e){return 1&e.compareDocumentPosition(d.createElement(\"fieldset\"))})),ce((function(e){return e.innerHTML=\"\",\"#\"===e.firstChild.getAttribute(\"href\")}))||fe(\"type|href|height|width\",(function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)})),n.attributes&&ce((function(e){return e.innerHTML=\"\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")}))||fe(\"value\",(function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue})),ce((function(e){return null==e.getAttribute(\"disabled\")}))||fe(R,(function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null})),se}(e);w.find=C,w.expr=C.selectors,w.expr[\":\"]=w.expr.pseudos,w.uniqueSort=w.unique=C.uniqueSort,w.text=C.getText,w.isXMLDoc=C.isXML,w.contains=C.contains,w.escapeSelector=C.escape;var E=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=w.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function j(e,t,n){return h(t)?w.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?w.grep(e,(function(e){return e===t!==n})):\"string\"!=typeof t?w.grep(e,(function(e){return s.call(t,e)>-1!==n})):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,(function(e){return 1===e.nodeType})))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if(\"string\"!=typeof e)return this.pushStack(w(e).filter((function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,\"string\"==typeof e&&k.test(e)?w(e):e||[],!1).length}});var D,q=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/;(w.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,\"string\"==typeof e){if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&e.length>=3?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:v,!0)),N.test(r[1])&&w.isPlainObject(t))for(r in t)h(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=v.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):h(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,D=w(v);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?s.call(w(e),this[0]):s.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return E(e,\"parentNode\")},parentsUntil:function(e,t,n){return E(e,\"parentNode\",n)},next:function(e){return O(e,\"nextSibling\")},prev:function(e){return O(e,\"previousSibling\")},nextAll:function(e){return E(e,\"nextSibling\")},prevAll:function(e){return E(e,\"previousSibling\")},nextUntil:function(e,t,n){return E(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return E(e,\"previousSibling\",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,\"template\")&&(e=e.content||e),w.merge([],e.childNodes))}},(function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=w.filter(r,i)),this.length>1&&(H[e]||w.uniqueSort(i),L.test(e)&&i.reverse()),this.pushStack(i)}}));var P=/[^\\x20\\t\\r\\n\\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&h(i=e.promise)?i.call(e).done(t).fail(n):e&&h(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.Callbacks=function(e){e=\"string\"==typeof e?function(e){var t={};return w.each(e.match(P)||[],(function(e,n){t[n]=!0})),t}(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1)for(n=a.shift();++s-1;)o.splice(n,1),n<=s&&s--})),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n=\"\",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=\"\"),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},w.extend({Deferred:function(t){var n=[[\"notify\",\"progress\",w.Callbacks(\"memory\"),w.Callbacks(\"memory\"),2],[\"resolve\",\"done\",w.Callbacks(\"once memory\"),w.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",w.Callbacks(\"once memory\"),w.Callbacks(\"once memory\"),1,\"rejected\"]],r=\"pending\",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred((function(t){w.each(n,(function(n,r){var i=h(e[r[4]])&&e[r[4]];o[r[1]]((function(){var e=i&&i.apply(this,arguments);e&&h(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+\"With\"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==M&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred((function(e){n[0][3].add(a(0,e,h(i)?i:R,e.notifyWith)),n[1][3].add(a(0,e,h(t)?t:R)),n[2][3].add(a(0,e,h(r)?r:M))})).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,(function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add((function(){r=s}),n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+\"With\"](this===o?void 0:this,arguments),this},o[t[0]+\"With\"]=a.fireWith})),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),o=i.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?i.call(arguments):n,--t||a.resolveWith(r,o)}};if(t<=1&&(I(e,a.done(s(n)).resolve,a.reject,!t),\"pending\"===a.state()||h(o[n]&&o[n].then)))return a.then();for(;n--;)I(o[n],s(n),a.reject);return a.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&W.test(t.name)&&e.console.warn(\"jQuery.Deferred exception: \"+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout((function(){throw t}))};var F=w.Deferred();function B(){v.removeEventListener(\"DOMContentLoaded\",B),e.removeEventListener(\"load\",B),w.ready()}w.fn.ready=function(e){return F.then(e).catch((function(e){w.readyException(e)})),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(v,[w]))}}),w.ready.then=F.then,\"complete\"===v.readyState||\"loading\"!==v.readyState&&!v.documentElement.doScroll?e.setTimeout(w.ready):(v.addEventListener(\"DOMContentLoaded\",B),e.addEventListener(\"load\",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===x(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,h(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each((function(){Q.remove(this,e)}))}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t);\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,(function(){w.dequeue(e,t)}),o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Y.get(e,n)||Y.access(e,n,{empty:w.Callbacks(\"once memory\").add((function(){Y.remove(e,[t+\"queue\",n])}))})}}),w.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length\\x20\\t\\r\\n\\f]*)/i,ge=/^$|^module$|\\/(?:java|ecma)script/i;fe=v.createDocumentFragment().appendChild(v.createElement(\"div\")),(pe=v.createElement(\"input\")).setAttribute(\"type\",\"radio\"),pe.setAttribute(\"checked\",\"checked\"),pe.setAttribute(\"name\",\"t\"),fe.appendChild(pe),d.checkClone=fe.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.innerHTML=\"\",d.noCloneChecked=!!fe.cloneNode(!0).lastChild.defaultValue,fe.innerHTML=\"\",d.option=!!fe.lastChild;var ve={thead:[1,\"\",\"
\"],col:[2,\"\",\"
\"],tr:[2,\"\",\"
\"],td:[3,\"\",\"
\"],_default:[0,\"\",\"\"]};function ye(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):void 0!==e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&A(e,t)?w.merge([e],n):n}function me(e,t){for(var n=0,r=e.length;n\",\"\"]);var xe=/<|&#?\\w+;/;function be(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d-1)i&&i.push(o);else if(l=ie(o),a=ye(f.appendChild(o),\"script\"),l&&me(a),n)for(c=0;o=a[c++];)ge.test(o.type||\"\")&&n.push(o);return f}var we=/^([^.]*)(?:\\.(.+)|)/;function Te(){return!0}function Ce(){return!1}function Ee(e,t){return e===function(){try{return v.activeElement}catch(e){}}()==(\"focus\"===t)}function Se(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){for(s in\"string\"!=typeof n&&(r=r||n,n=void 0),t)Se(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ce;else if(!i)return e;return 1===o&&(a=i,i=function(e){return w().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=w.guid++)),e.each((function(){w.event.add(this,t,i,r,n)}))}function ke(e,t,n){n?(Y.set(e,t,!1),w.event.add(e,t,{namespace:!1,handler:function(e){var r,o,a=Y.get(this,t);if(1&e.isTrigger&&this[t]){if(a.length)(w.event.special[t]||{}).delegateType&&e.stopPropagation();else if(a=i.call(arguments),Y.set(this,t,a),r=n(this,t),this[t](),a!==(o=Y.get(this,t))||r?Y.set(this,t,!1):o={},a!==o)return e.stopImmediatePropagation(),e.preventDefault(),o&&o.value}else a.length&&(Y.set(this,t,{value:w.event.trigger(w.extend(a[0],w.Event.prototype),a.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,t)&&w.event.add(e,t,Te)}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(e);if(V(e))for(n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(re,i),n.guid||(n.guid=w.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(t){return void 0!==w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||\"\").match(P)||[\"\"]).length;l--;)d=g=(s=we.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(\".\")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){for(l=(t=(t||\"\").match(P)||[\"\"]).length;l--;)if(d=g=(s=we.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d){for(f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||w.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&Y.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=w.event.fix(e),l=(Y.get(this,\"events\")||Object.create(null))[u.type]||[],c=w.event.special[u.type]||{};for(s[0]=u,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\\s*$/g;function De(e,t){return A(e,\"table\")&&A(11!==t.nodeType?t:t.firstChild,\"tr\")&&w(e).children(\"tbody\")[0]||e}function qe(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function Le(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function He(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,\"handle events\"),s)for(n=0,r=s[i].length;n1&&\"string\"==typeof v&&!d.checkClone&&Ne.test(v))return e.each((function(i){var o=e.eq(i);y&&(t[0]=v.call(this,i,o.html())),Pe(o,t,n,r)}));if(p&&(a=(i=be(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=a),a||r)){for(u=(s=w.map(ye(i,\"script\"),qe)).length;f0&&me(a,!u&&ye(e,\"script\")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,(function(e){return void 0===e?w.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Pe(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||De(this,e).appendChild(e)}))},prepend:function(){return Pe(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=De(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Pe(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Pe(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return w.clone(this,e,t)}))},html:function(e){return $(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!Ae.test(e)&&!ve[(he.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!d.boxSizingReliable()||n)&&\"border-box\"===w.css(e,\"boxSizing\",!1,r),o=i,a=Be(e,t,r),s=\"offset\"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a=\"auto\"}return(!d.boxSizingReliable()&&i||!d.reliableTrDimensions()&&A(e,\"tr\")||\"auto\"===a||!parseFloat(a)&&\"inline\"===w.css(e,\"display\",!1,r))&&e.getClientRects().length&&(i=\"border-box\"===w.css(e,\"boxSizing\",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?\"border\":\"content\"),o,r,a)+\"px\"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];\"string\"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o=\"number\"),null!=n&&n==n&&(\"number\"!==o||u||(n+=i&&i[3]||(w.cssNumber[s]?\"\":\"px\")),d.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(l[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&\"get\"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),\"normal\"===i&&t in Qe&&(i=Qe[t]),\"\"===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each([\"height\",\"width\"],(function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!Ve.test(w.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,t,r):We(e,Ye,(function(){return Ze(e,t,r)}))},set:function(e,n,r){var i,o=Ie(e),a=!d.scrollboxSize()&&\"absolute\"===o.position,s=(a||r)&&\"border-box\"===w.css(e,\"boxSizing\",!1,o),u=r?Ke(e,t,r,s,o):0;return s&&a&&(u-=Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ke(e,t,\"border\",!1,o)-.5)),u&&(i=te.exec(n))&&\"px\"!==(i[3]||\"px\")&&(e.style[t]=n,n=w.css(e,t)),Je(0,n,u)}}})),w.cssHooks.marginLeft=$e(d.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Be(e,\"marginLeft\"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+\"px\"})),w.each({margin:\"\",padding:\"\",border:\"Width\"},(function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)i[e+ne[r]+t]=o[r]||o[r-2]||o[0];return i}},\"margin\"!==e&&(w.cssHooks[e+t].set=Je)})),w.fn.extend({css:function(e,t){return $(this,(function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a1)}}),w.Tween=et,et.prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?\"\":\"px\")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}},et.prototype.init.prototype=et.prototype,et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,\"\"))&&\"auto\"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||!w.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},et.propHooks.scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},w.fx=et.prototype.init,w.fx.step={};var tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){nt&&(!1===v.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(ot):e.setTimeout(ot,w.fx.interval),w.fx.tick())}function at(){return e.setTimeout((function(){tt=void 0})),tt=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i[\"margin\"+(n=ne[r])]=i[\"padding\"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners[\"*\"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){w.removeAttr(this,e)}))}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!d.radioValue&&\"radio\"===t&&A(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\\w+/g),(function(e,t){var n=ft[t]||w.find.attr;ft[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ft[a],ft[a]=i,i=null!=n(e,t,r)?a:null,ft[a]=o),i}}));var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(\" \")}function gt(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function vt(e){return Array.isArray(e)?e:\"string\"==typeof e&&e.match(P)||[]}w.fn.extend({prop:function(e,t){return $(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[w.propFix[e]||e]}))}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,\"tabindex\");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:\"htmlFor\",class:\"className\"}}),d.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],(function(){w.propFix[this.toLowerCase()]=this})),w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(h(e))return this.each((function(t){w(this).addClass(e.call(this,t,gt(this)))}));if((t=vt(e)).length)for(;n=this[u++];)if(i=gt(n),r=1===n.nodeType&&\" \"+ht(i)+\" \"){for(a=0;o=t[a++];)r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");i!==(s=ht(r))&&n.setAttribute(\"class\",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(h(e))return this.each((function(t){w(this).removeClass(e.call(this,t,gt(this)))}));if(!arguments.length)return this.attr(\"class\",\"\");if((t=vt(e)).length)for(;n=this[u++];)if(i=gt(n),r=1===n.nodeType&&\" \"+ht(i)+\" \"){for(a=0;o=t[a++];)for(;r.indexOf(\" \"+o+\" \")>-1;)r=r.replace(\" \"+o+\" \",\" \");i!==(s=ht(r))&&n.setAttribute(\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e,r=\"string\"===n||Array.isArray(e);return\"boolean\"==typeof t&&r?t?this.addClass(e):this.removeClass(e):h(e)?this.each((function(n){w(this).toggleClass(e.call(this,n,gt(this),t),t)})):this.each((function(){var t,i,o,a;if(r)for(i=0,o=w(this),a=vt(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&\"boolean\"!==n||((t=gt(this))&&Y.set(this,\"__className__\",t),this.setAttribute&&this.setAttribute(\"class\",t||!1===e?\"\":Y.get(this,\"__className__\")||\"\"))}))},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+ht(gt(n))+\" \").indexOf(t)>-1)return!0;return!1}});var yt=/\\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=h(e),this.each((function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i=\"\":\"number\"==typeof i?i+=\"\":Array.isArray(i)&&(i=w.map(i,(function(e){return null==e?\"\":e+\"\"}))),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&\"set\"in t&&void 0!==t.set(this,i,\"value\")||(this.value=i))}))):i?(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&\"get\"in t&&void 0!==(n=t.get(i,\"value\"))?n:\"string\"==typeof(n=i.value)?n.replace(yt,\"\"):null==n?\"\":n:void 0}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,\"value\");return null!=t?t:ht(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each([\"radio\",\"checkbox\"],(function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},d.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})})),d.focusin=\"onfocusin\"in e;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,r,i){var o,a,s,u,l,f,p,d,y=[r||v],m=c.call(t,\"type\")?t.type:t,x=c.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(a=d=s=r=r||v,3!==r.nodeType&&8!==r.nodeType&&!mt.test(m+w.event.triggered)&&(m.indexOf(\".\")>-1&&(x=m.split(\".\"),m=x.shift(),x.sort()),l=m.indexOf(\":\")<0&&\"on\"+m,(t=t[w.expando]?t:new w.Event(m,\"object\"==typeof t&&t)).isTrigger=i?2:3,t.namespace=x.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+x.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:w.makeArray(n,[t]),p=w.event.special[m]||{},i||!p.trigger||!1!==p.trigger.apply(r,n))){if(!i&&!p.noBubble&&!g(r)){for(u=p.delegateType||m,mt.test(u+m)||(a=a.parentNode);a;a=a.parentNode)y.push(a),s=a;s===(r.ownerDocument||v)&&y.push(s.defaultView||s.parentWindow||e)}for(o=0;(a=y[o++])&&!t.isPropagationStopped();)d=a,t.type=o>1?u:p.bindType||m,(f=(Y.get(a,\"events\")||Object.create(null))[t.type]&&Y.get(a,\"handle\"))&&f.apply(a,n),(f=l&&a[l])&&f.apply&&V(a)&&(t.result=f.apply(a,n),!1===t.result&&t.preventDefault());return t.type=m,i||t.isDefaultPrevented()||p._default&&!1!==p._default.apply(y.pop(),n)||!V(r)||l&&h(r[m])&&!g(r)&&((s=r[l])&&(r[l]=null),w.event.triggered=m,t.isPropagationStopped()&&d.addEventListener(m,xt),r[m](),t.isPropagationStopped()&&d.removeEventListener(m,xt),w.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each((function(){w.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),d.focusin||w.each({focus:\"focusin\",blur:\"focusout\"},(function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=Y.access(r,t);i||r.addEventListener(e,n,!0),Y.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=Y.access(r,t)-1;i?Y.access(r,t,i):(r.removeEventListener(e,n,!0),Y.remove(r,t))}}}));var bt=e.location,wt={guid:Date.now()},Tt=/\\?/;w.parseXML=function(t){var n,r;if(!t||\"string\"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,\"text/xml\")}catch(e){}return r=n&&n.getElementsByTagName(\"parsererror\")[0],n&&!r||w.error(\"Invalid XML: \"+(r?w.map(r.childNodes,(function(e){return e.textContent})).join(\"\\n\"):t)),n};var Ct=/\\[\\]$/,Et=/\\r?\\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(e,t,n,r){var i;if(Array.isArray(t))w.each(t,(function(t,i){n||Ct.test(e)?r(e,i):At(e+\"[\"+(\"object\"==typeof i&&null!=i?t:\"\")+\"]\",i,n,r)}));else if(n||\"object\"!==x(t))r(e,t);else for(i in t)At(e+\"[\"+i+\"]\",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=h(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(null==e)return\"\";if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,(function(){i(this.name,this.value)}));else for(n in e)At(n,e[n],t,i);return r.join(\"&\")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=w.prop(this,\"elements\");return e?w.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!w(this).is(\":disabled\")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!de.test(e))})).map((function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,(function(e){return{name:t.name,value:e.replace(Et,\"\\r\\n\")}})):{name:t.name,value:n.replace(Et,\"\\r\\n\")}})).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\\/\\//,Ot={},Pt={},Rt=\"*/\".concat(\"*\"),Mt=v.createElement(\"a\");function It(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,i=0,o=t.toLowerCase().match(P)||[];if(h(n))for(;r=o[i++];)\"+\"===r[0]?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Wt(e,t,n,r){var i={},o=e===Pt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],(function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)})),u}return a(t.dataTypes[0])||!i[\"*\"]&&a(\"*\")}function Ft(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}Mt.href=bt.href,w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:\"GET\",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Rt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,w.ajaxSettings),t):Ft(w.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(t,n){\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var r,i,o,a,s,u,l,c,f,p,d=w.ajaxSetup({},n),h=d.context||d,g=d.context&&(h.nodeType||h.jquery)?w(h):w.event,y=w.Deferred(),m=w.Callbacks(\"once memory\"),x=d.statusCode||{},b={},T={},C=\"canceled\",E={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=qt.exec(o);)a[t[1].toLowerCase()+\" \"]=(a[t[1].toLowerCase()+\" \"]||[]).concat(t[2]);t=a[e.toLowerCase()+\" \"]}return null==t?null:t.join(\", \")},getAllResponseHeaders:function(){return l?o:null},setRequestHeader:function(e,t){return null==l&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return r&&r.abort(t),S(0,t),this}};if(y.promise(E),d.url=((t||d.url||bt.href)+\"\").replace(Ht,bt.protocol+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||\"*\").toLowerCase().match(P)||[\"\"],null==d.crossDomain){u=v.createElement(\"a\");try{u.href=d.url,u.href=u.href,d.crossDomain=Mt.protocol+\"//\"+Mt.host!=u.protocol+\"//\"+u.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=w.param(d.data,d.traditional)),Wt(Ot,d,n,E),l)return E;for(f in(c=w.event&&d.global)&&0==w.active++&&w.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Lt.test(d.type),i=d.url.replace(jt,\"\"),d.hasContent?d.data&&d.processData&&0===(d.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(d.data=d.data.replace(Nt,\"+\")):(p=d.url.slice(i.length),d.data&&(d.processData||\"string\"==typeof d.data)&&(i+=(Tt.test(i)?\"&\":\"?\")+d.data,delete d.data),!1===d.cache&&(i=i.replace(Dt,\"$1\"),p=(Tt.test(i)?\"&\":\"?\")+\"_=\"+wt.guid+++p),d.url=i+p),d.ifModified&&(w.lastModified[i]&&E.setRequestHeader(\"If-Modified-Since\",w.lastModified[i]),w.etag[i]&&E.setRequestHeader(\"If-None-Match\",w.etag[i])),(d.data&&d.hasContent&&!1!==d.contentType||n.contentType)&&E.setRequestHeader(\"Content-Type\",d.contentType),E.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Rt+\"; q=0.01\":\"\"):d.accepts[\"*\"]),d.headers)E.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(!1===d.beforeSend.call(h,E,d)||l))return E.abort();if(C=\"abort\",m.add(d.complete),E.done(d.success),E.fail(d.error),r=Wt(Pt,d,n,E)){if(E.readyState=1,c&&g.trigger(\"ajaxSend\",[E,d]),l)return E;d.async&&d.timeout>0&&(s=e.setTimeout((function(){E.abort(\"timeout\")}),d.timeout));try{l=!1,r.send(b,S)}catch(e){if(l)throw e;S(-1,e)}}else S(-1,\"No Transport\");function S(t,n,a,u){var f,p,v,b,T,C=n;l||(l=!0,s&&e.clearTimeout(s),r=void 0,o=u||\"\",E.readyState=t>0?4:0,f=t>=200&&t<300||304===t,a&&(b=function(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+\" \"+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(d,E,a)),!f&&w.inArray(\"script\",d.dataTypes)>-1&&w.inArray(\"json\",d.dataTypes)<0&&(d.converters[\"text script\"]=function(){}),b=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(!(a=l[u+\" \"+o]||l[\"* \"+o]))for(i in l)if((s=i.split(\" \"))[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}(d,b,E,f),f?(d.ifModified&&((T=E.getResponseHeader(\"Last-Modified\"))&&(w.lastModified[i]=T),(T=E.getResponseHeader(\"etag\"))&&(w.etag[i]=T)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=b.state,p=b.data,f=!(v=b.error))):(v=C,!t&&C||(C=\"error\",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+\"\",f?y.resolveWith(h,[p,C,E]):y.rejectWith(h,[E,C,v]),E.statusCode(x),x=void 0,c&&g.trigger(f?\"ajaxSuccess\":\"ajaxError\",[E,d,f?p:v]),m.fireWith(h,[E,C]),c&&(g.trigger(\"ajaxComplete\",[E,d]),--w.active||w.event.trigger(\"ajaxStop\")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,\"json\")},getScript:function(e,t){return w.get(e,void 0,t,\"script\")}}),w.each([\"get\",\"post\"],(function(e,t){w[t]=function(e,n,r,i){return h(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}})),w.ajaxPrefilter((function(e){var t;for(t in e.headers)\"content-type\"===t.toLowerCase()&&(e.contentType=e.headers[t]||\"\")})),w._evalUrl=function(e,t,n){return w.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,converters:{\"text script\":function(){}},dataFilter:function(e){w.globalEval(e,t,n)}})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(h(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return h(e)?this.each((function(t){w(this).wrapInner(e.call(this,t))})):this.each((function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=h(e);return this.each((function(n){w(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not(\"body\").each((function(){w(this).replaceWith(this.childNodes)})),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=w.ajaxSettings.xhr();d.cors=!!$t&&\"withCredentials\"in $t,d.ajax=$t=!!$t,w.ajaxTransport((function(t){var n,r;if(d.cors||$t&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];for(a in t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i[\"X-Requested-With\"]||(i[\"X-Requested-With\"]=\"XMLHttpRequest\"),i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,\"abort\"===e?s.abort():\"error\"===e?\"number\"!=typeof s.status?o(0,\"error\"):o(s.status,s.statusText):o(Bt[s.status]||s.status,s.statusText,\"text\"!==(s.responseType||\"text\")||\"string\"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n(\"error\"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout((function(){n&&r()}))},n=n(\"abort\");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}})),w.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),w.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter(\"script\",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")})),w.ajaxTransport(\"script\",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,i){t=w(\"" - ], - "text/plain": [ - ":Curve [time] (ACCET)" - ] - }, - "execution_count": 34, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "1002" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "ds2.ACCET[:,2000,2000].hvplot(x='time')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.10.9" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/05_explore_rechunked.ipynb b/201/05_explore_rechunked.ipynb deleted file mode 100644 index 6ee3596..0000000 --- a/201/05_explore_rechunked.ipynb +++ /dev/null @@ -1,1153 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "abac6797-4386-4f15-8b34-5e433dce5e64", - "metadata": {}, - "source": [ - "# Explore rechunked data" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "6286295f-dbc0-4757-a433-a03f8fa2bfd9", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "import xarray as xr\n", - "import hvplot.xarray" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "301d41a2-7e11-444c-93fd-59b524da4ae5", - "metadata": {}, - "outputs": [], - "source": [ - "fs_read = fsspec.filesystem('s3', requester_pays=True, skip_instance_cache=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "0a8eda8f-fc70-457a-8892-560ce1acc312", - "metadata": {}, - "outputs": [], - "source": [ - "rechunked_zarr = 's3://esip-qhub/testing/usgs/nwm1km.zarr'" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "dd53fdba-ace6-474a-8ff2-5daa1cf9c108", - "metadata": {}, - "outputs": [], - "source": [ - "ds = xr.open_dataset(fs_read.get_mapper(rechunked_zarr), engine='zarr', chunks={})" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "d4b41d42-ead0-42f7-8494-37ab43fa1ada", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (time: 144, y: 3840, x: 4608)\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Data variables:\n",
-       "    ACCET    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    FSNO     (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "    SNEQV    (time, y, x) float64 dask.array<chunksize=(72, 192, 264), meta=np.ndarray>\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 144, y: 3840, x: 4608)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 1979-02-19\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Data variables:\n", - " ACCET (time, y, x) float64 dask.array\n", - " FSNO (time, y, x) float64 dask.array\n", - " SNEQV (time, y, x) float64 dask.array\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "983ecff0-d0d9-4a2e-93d8-9d514bea8dd0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3 µs, sys: 1e+03 ns, total: 4 µs\n", - "Wall time: 5.48 µs\n" - ] - } - ], - "source": [ - "%time\n", - "da = ds.ACCET[:144,1500,2000]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "17123ac3-53ee-4b49-ac51-69ab2b53bf46", - "metadata": {}, - "outputs": [ - { - "data": {}, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ], - "text/plain": [ - ":Curve [time] (ACCET)" - ] - }, - "execution_count": 16, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "1374" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "da.hvplot(x='time', grid=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66ff87fb-2f18-4973-89ad-7d37567110cd", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.9.16" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/CreateVirtualZarr.ipynb b/201/CreateVirtualZarr.ipynb new file mode 100644 index 0000000..08c6664 --- /dev/null +++ b/201/CreateVirtualZarr.ipynb @@ -0,0 +1,811 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f83aa4d9-364e-42b2-8de6-f31bf9034f1c", + "metadata": {}, + "source": [ + "# Generating a Virtual Zarr Store" + ] + }, + { + "cell_type": "markdown", + "id": "a670e170-eaf4-4158-bf02-a96b13f3f935", + "metadata": {}, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "This notebook builds off the [Kerchunk](https://fsspec.github.io/kerchunk/index.html) and [VirtualiZarr](https://virtualizarr.readthedocs.io/en/stable/index.html) docs.\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "markdown", + "id": "afb02d98-a534-4cb4-9c37-0250aa2f78d9", + "metadata": {}, + "source": [ + "The objective of this notebook is to learn how to create a virtual Zarr store for a collection of NetCDF files that together make up a complete data set.\n", + "To do this, we will use [Kerchunk](https://fsspec.github.io/kerchunk/index.html) and [VirtualiZarr](https://virtualizarr.readthedocs.io/en/stable/index.html).\n", + "As these two packages can both create virtual Zarr stores but do it in different ways, we will utilize them both to show how they compare in combination with [dask](https://www.dask.org/) for parallel execution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7cf6a00-e79f-400e-b9a6-e60858d99a3c", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "import ujson\n", + "import time\n", + "import kerchunk.hdf\n", + "import kerchunk.combine\n", + "from virtualizarr import open_virtual_dataset\n", + "import dask.distributed\n", + "import logging" + ] + }, + { + "cell_type": "markdown", + "id": "db16a5a6-e56e-4907-baf4-da9c91b2aba0", + "metadata": {}, + "source": [ + "## Kerchunk vs VirtualiZarr\n", + "\n", + "To begin, let's explain what a virtual Zarr store even is.\n", + "A \"[**virtual Zarr store**](../back/Glossary.md#term-Virtual-Zarr-Store)\" is a virtual representation of a Zarr store generated by mapping any number of real datasets in individual files (e.g., NetCDF/HDF5, GRIB2, TIFF) together into a single, sliceable dataset via an interface layer.\n", + "This interface layer, which Kerchunk and VirtualiZarr generate, contains information about the original files (e.g., chunking, compression, data byte location, etc.) needed to efficiently access the data.\n", + "While this could be done with [`xarray.open_mfdataset`](https://docs.xarray.dev/en/stable/generated/xarray.open_mfdataset.html), we don't want to run this command every time we open the dataset as it can be a slow and expensive process.\n", + "The reason for this is that `xarray.open_mfdataset` performs many consistency checks as it runs, and it requires partially opening all of the datasets to get general matadata information on each of the individual files.\n", + "Therefore, for numerous files, this can have significant overhead, and it would be preferable to just cache these checks and metadata for more performant future reads.\n", + "This cache (specifically in Zarr format) is what a virtual Zarr store is. \n", + "Once we have the virtual Zarr store, we can open the combined xarray dataset using [`xarray.open_dataset`](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html) for an almost instantaneous read.\n", + "\n", + "Now that we know what a virtual Zarr store is, let's discuss the differences between Kerchunk and VirtualiZarr and their virtual Zarr stores.\n", + "At a top level, VirtualiZarr provides almost all of the same features as Kerchunk.\n", + "The primary difference is that Kerchunk supports non-Zarr-like virtual format, while VirtualiZarr is specifically focused on the Zarr format.\n", + "Additionally, Kerchunk creates the virtual Zarr store and represents it in memory using json formatting (the format used for Zarr metadata).\n", + "Alternatively, VirtualiZarr represents the store as array-level abstractions (which can be converted to json format).\n", + "These abstractions can be cleanly wrapped by xarray for easy use of `xarray.concat` and `xarray.merge` commands to combine virtual Zarr stores.\n", + "A nice table comparing the two packages can be found in the [VirtualiZarr FAQs](https://virtualizarr.readthedocs.io/en/stable/faq.html#how-do-virtualizarr-and-kerchunk-compare), which shows how the two packages represent virtual Zarr stores and their comparative syntax." + ] + }, + { + "cell_type": "markdown", + "id": "6eb26405-82de-41b3-b552-55a34fd2b1be", + "metadata": {}, + "source": [ + "## Spin up Dask Cluster\n", + "\n", + "To run the virtual Zarr creation in parallel, we need to spin up a Dask cluster to schedule the various workers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88de9acf-7cb6-4c0d-a918-003eaca707e1", + "metadata": {}, + "outputs": [], + "source": [ + "cluster = dask.distributed.LocalCluster(\n", + " n_workers=16,\n", + " threads_per_worker=1, \n", + " silence_logs=logging.ERROR\n", + ")\n", + "client = dask.distributed.Client(cluster)\n", + "client" + ] + }, + { + "cell_type": "markdown", + "id": "23951132-87c8-4f67-9cb0-2ab36bea7b7c", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Example Comparison\n", + "\n", + "With our Dask cluster ready, let's see how Kerchunk and VirtualiZarr can be utilized to generate a vitrual Zarr store.\n", + "For this example, we will use the same daily gridMET NetCDF data as used in the [Writing Chunked File tutorial](../101/WriteChunkedFiles.ipynb).\n", + "Only this time we will use all of the variables not just precipitation.\n", + "These include:\n", + " - precipitation,\n", + " - maximum relative humidity,\n", + " - minimum relative humidity,\n", + " - specific humidity,\n", + " - downward shortwave radiation,\n", + " - minimum air temperature,\n", + " - maximum air temperature,\n", + " - wind direction, and\n", + " - wind speed.\n", + " \n", + "The data is currently hosted on the HyTEST OSN as a collection NetCDF files.\n", + "To access the data with both Kerchunk and VirtualiZarr, we will use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) to get the list of files that we are wanting to combine into a virtual Zarr store.\n", + "\n", + "First we need to create the file system for accessing the files, and a second one for outputting the virtual Zarr store.\n", + "\n", + "```{note}\n", + "We will exclude the year 2019 for now and use it later to show how to append virtual Zarr stores.\n", + "Also, we will not use 2020 as it is a partial year with different chunking than the other 40 years, which is currently incompatible with Kerchunk and Virtualizarr.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fcd0b92c-4943-419a-a85d-907a84764893", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# These reader options will be needed for VirtualiZarr\n", + "# We created them here to show how they fold into fsspec\n", + "reader_options = {\n", + " 'storage_options': {\n", + " 'anon': True, \n", + " 'client_kwargs': {\n", + " 'endpoint_url': 'https://usgs.osn.mghpcc.org/'\n", + " }\n", + " }\n", + "}\n", + "\n", + "fs = fsspec.filesystem(\n", + " protocol='s3',\n", + " **reader_options['storage_options']\n", + ")\n", + "\n", + "fs_local = fsspec.filesystem('')\n", + "# Make directories to save the virtual zarr stores\n", + "fs_local.mkdir('virtual_zarr/kerchunk')\n", + "fs_local.mkdir('virtual_zarr/virtualizarr')\n", + "\n", + "file_glob = fs.glob('s3://mdmf/gdp/netcdf/gridmet/gridmet/*198*.nc')\n", + "file_glob = [file for file in file_glob if (('2020' not in file) and ('2019' not in file))]" + ] + }, + { + "cell_type": "markdown", + "id": "5c816bf0-6268-41e7-b159-e0b1e91c3ffa", + "metadata": {}, + "source": [ + "Now, we are ready to generate the virtual Zarr stores.\n", + "For both Kerchunk and VirtualiZarr ([for now](https://virtualizarr.readthedocs.io/en/stable/usage.html#opening-files-as-virtual-datasets)), this consists of two steps:\n", + "\n", + "1) Convert a single original data file into individual virtual Zarr stores,\n", + "2) Combine the individual virtual Zarr stores into a single combined virtual Zarr store.\n", + "\n", + "We will show these two steps seperately and how they are done for each package." + ] + }, + { + "cell_type": "markdown", + "id": "41f65cc2-6a43-455d-88fd-69e96d5ab020", + "metadata": {}, + "source": [ + "### Generate Individual Virtual Zarr Stores\n", + "\n", + "#### Kerchunk\n", + "\n", + "To generate the individual virtual Zarr stores with Kerchunk, we will use [`kerchunk.hdf.SingleHdf5ToZarr`](https://fsspec.github.io/kerchunk/reference.html#kerchunk.hdf.SingleHdf5ToZarr), which translates the content of one HDF5 file into Zarr metadata.\n", + "Other translators exist in Kerchunk that can convert GeoTiffs and NetCDF3 files.\n", + "However, as we are looking at NetCDF4 files (a specific version of a HDF5 file), we will use the HDF5 translator.\n", + "As this only translates one file, we can make a collection of [`dask.delayed`](https://docs.dask.org/en/stable/delayed.html) objects that wrap the `SingleHdf5ToZarr` call to run it for all files in parallel." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2289fac1-96a3-424a-89f5-e7d52c5c2006", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "scroll-output" + ] + }, + "outputs": [], + "source": [ + "# Make a function to run in parallel with dask\n", + "@dask.delayed\n", + "def generate_single_virtual_zarr(file):\n", + " with fs.open(file) as hdf:\n", + " h5chunks = kerchunk.hdf.SingleHdf5ToZarr(hdf, file, inline_threshold=0)\n", + " return h5chunks.translate()\n", + "\n", + "# Time the duration for later comparison\n", + "t0 = time.time()\n", + "\n", + "# Generate Dask Delayed objects\n", + "tasks = [generate_single_virtual_zarr(file) for file in file_glob]\n", + "# Compute the delayed object\n", + "single_virtual_zarrs = dask.compute(*tasks)\n", + "\n", + "kerchunk_time = time.time() - t0\n", + "\n", + "single_virtual_zarrs[0]" + ] + }, + { + "cell_type": "markdown", + "id": "e288b09f-ae7d-48d0-afff-e50ba278f086", + "metadata": {}, + "source": [ + "Notice that the output for a virtualization of a single NetCDF is a json style dictionary, where the coordinate data is actually kept in the dictionary, while the data is a file pointer and the byte range for each chunk." + ] + }, + { + "cell_type": "markdown", + "id": "b8bfcf7b-77ae-4fa9-8c8c-e6e6a4a4002c", + "metadata": {}, + "source": [ + "#### VirtualiZarr\n", + "\n", + "To generate the individual virtual Zarr stores with VirtualiZarr, we will use [`virtualizarr.open_virtual_dataset`](https://virtualizarr.readthedocs.io/en/stable/generated/virtualizarr.backend.open_virtual_dataset.html#virtualizarr-backend-open-virtual-dataset), which can infer what type of file we are reading instead of us having to specify.\n", + "Like Kerchunk, this only translates one file at a time.\n", + "So, we can make a collection of [`dask.delayed`](https://docs.dask.org/en/stable/delayed.html) objects that wraps `open_virtual_dataset` to run it for all files in parallel.\n", + "\n", + "```{important}\n", + "When reading in the individual files as virtual datasets, it is critical to include the `loadable_variables` keyword.\n", + "The keyword should be set to a list of the coordinate names.\n", + "By adding this keyword, the coordinates are read into memory rather than being loaded as virtual data.\n", + "This can make a massive difference in the next steps of (1) concatenation as it gives the coordinates indexes and (2) the serialization of the virtual Zarr store as it saves the in-memory coordinates directly to the store rather than a pointer.\n", + "Also, if this is not included, coordinates of different sizes will not be able to be concatenated due to potential chunking differences.\n", + "The only downside is that it can slightly increase the time it takes to initially read the virtual datasets.\n", + "However, this slowdown is more than worth the future convenience of having the coords in-memory when reading in the virtual Zarr store.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d998158-c484-41db-a476-2bd8ffd2c501", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "tasks = [\n", + " dask.delayed(open_virtual_dataset)(\n", + " f's3://{file}',\n", + " indexes={},\n", + " loadable_variables=['day', 'lat', 'lon', 'crs'],\n", + " decode_times=True,\n", + " reader_options=reader_options\n", + " )\n", + " for file in file_glob\n", + "]\n", + "\n", + "virtual_datasets = dask.compute(*tasks)\n", + "\n", + "virtualizarr_time = time.time() - t0\n", + "\n", + "virtual_datasets[0]" + ] + }, + { + "cell_type": "markdown", + "id": "79eb52f0-aec7-4d65-bb02-918e22797483", + "metadata": {}, + "source": [ + "Notice that the output for a virtualization of a single NetCDF is now an `xarray.Dataset`, where the data is a [`ManifestArray`](https://virtualizarr.readthedocs.io/en/stable/generated/virtualizarr.manifests.ManifestArray.html) object.\n", + "This `ManifestArray` contains [`ChunkManifest`](https://virtualizarr.readthedocs.io/en/stable/generated/virtualizarr.manifests.ChunkManifest.html#virtualizarr.manifests.ChunkManifest) objects that hold the same info as the Kerchunk json format (i.e., a file pointer and the byte range for each chunk), but allows for it to be nicely wrapped by xarray." + ] + }, + { + "cell_type": "markdown", + "id": "ba9eec47-691e-40b7-a255-d7684eb31cc2", + "metadata": {}, + "source": [ + "### Combine Individual Virtual Zarr Stores\n", + "\n", + "#### Kerchunk\n", + "\n", + "To combine the individual virtual Zarr stores into one virtual Zarr store with Kerchunk, we will use [`kerchunk.combine.MultiZarrToZarr`](https://fsspec.github.io/kerchunk/reference.html#kerchunk.combine.MultiZarrToZarr), which combines the content of multiple virtual Zarr stores into a single virtual Zarr store.\n", + "This call requires feeding `MultiZarrToZarr` the remote access info that we needed for our file system, along with the dimension we want to combine." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d4e92e9-3fe4-41c4-ab42-ea2133396f82", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "scroll-output" + ] + }, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "mzz = kerchunk.combine.MultiZarrToZarr(\n", + " single_virtual_zarrs,\n", + " remote_protocol='s3',\n", + " remote_options=reader_options['storage_options'],\n", + " concat_dims=[\"day\"]\n", + ")\n", + "\n", + "out = mzz.translate()\n", + "\n", + "# Save the virtual Zarr store, serialized as json\n", + "with fs_local.open('virtual_zarr/kerchunk/gridmet.json', 'wb') as f:\n", + " f.write(ujson.dumps(out).encode())\n", + "\n", + "kerchunk_time += time.time() - t0\n", + "\n", + "out" + ] + }, + { + "cell_type": "markdown", + "id": "cf64912b-be1f-42ae-bc77-a1c07b04ead2", + "metadata": {}, + "source": [ + "Again, notice the output type is in a json format with the coords in the dictionary and data chunks having pointers, but this time all chunks are in the one dictionary." + ] + }, + { + "cell_type": "markdown", + "id": "a08f6432-3073-484a-9bc9-86d46d5b0324", + "metadata": {}, + "source": [ + "#### VirtualiZarr\n", + "\n", + "To combine the virtual datasets from VirtualiZarr, we can just use [`xarray.combine_by_coords`](https://docs.xarray.dev/en/stable/generated/xarray.combine_by_coords.html) which will auto-magically combine the virtual datasets together." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1331f08-5029-4ae5-aed8-4a6ccebefe4a", + "metadata": {}, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "virtual_ds = xr.combine_by_coords(virtual_datasets, coords='minimal', compat='override', combine_attrs='override')\n", + "\n", + "# Save the virtual Zarr store, serialized as json\n", + "virtual_ds.virtualize.to_kerchunk('virtual_zarr/virtualizarr/gridmet.json', format='json')\n", + "\n", + "virtualizarr_time += time.time() - t0\n", + "\n", + "virtual_ds" + ] + }, + { + "cell_type": "markdown", + "id": "a9b603bd-f7ed-40a9-8f4d-97a8f917e0aa", + "metadata": {}, + "source": [ + "Notice that when we saved the virtual dataset that we converted it to a Kerchunk format for saving." + ] + }, + { + "cell_type": "markdown", + "id": "bf70fafa-c21e-446a-b856-8d747f4f9da4", + "metadata": {}, + "source": [ + "### Opening the Virtual Zarr Stores\n", + "\n", + "To open the virtual Zarr stores, we can use the same method for both stores as we converted to Kerchunk format when saving from VirtualiZarr.\n", + "\n", + "#### Kerchunk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "368b69da-fe1f-43a1-a46d-ea89ceadbe70", + "metadata": {}, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "ds = xr.open_dataset(\n", + " 'virtual_zarr/kerchunk/gridmet.json',\n", + " chunks={},\n", + " engine=\"kerchunk\",\n", + " backend_kwargs={\n", + " \"storage_options\": {\n", + " \"remote_protocol\": \"s3\",\n", + " \"remote_options\": reader_options['storage_options']\n", + " },\n", + " }\n", + ")\n", + "\n", + "kerchunk_read_time = time.time() - t0\n", + "\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "25d4365f-7b7d-4be4-a97b-3db4b6a17a38", + "metadata": {}, + "source": [ + "#### VirtualiZarr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26a9e7c9-6e58-4fd2-896a-d4b0dbbe2af1", + "metadata": {}, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "ds = xr.open_dataset(\n", + " 'virtual_zarr/virtualizarr/gridmet.json',\n", + " chunks={},\n", + " engine=\"kerchunk\",\n", + " backend_kwargs={\n", + " \"storage_options\": {\n", + " \"remote_protocol\": \"s3\",\n", + " \"remote_options\": reader_options['storage_options']\n", + " },\n", + " }\n", + ")\n", + "\n", + "virtualizarr_read_time = time.time() - t0\n", + "\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "cdd0e99a-f589-46be-ab84-9cf346aa81a1", + "metadata": {}, + "source": [ + "### Reading with `xarray.open_mfdataset`\n", + "\n", + "As a comparison of read times, let's also compile the dataset using [`xarray.open_mfdataset`](https://docs.xarray.dev/en/stable/generated/xarray.open_mfdataset.html) in parallel with Dask.\n", + "This way we can see if we will be saving time in the future by having the compiled virtual Zarr for faster reads." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd10f6f4-f380-4f01-be6f-2b28bc1c9d4c", + "metadata": {}, + "outputs": [], + "source": [ + "t0 = time.time()\n", + "\n", + "ds = xr.open_mfdataset(\n", + " [fs.open(file) for file in file_glob],\n", + " chunks={},\n", + " parallel=True,\n", + " engine='h5netcdf'\n", + ")\n", + "\n", + "open_mfdataset_time = time.time() - t0\n", + "\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "0210ea1d-b59b-4466-b65e-1f7da4b698b2", + "metadata": {}, + "source": [ + "Now, let's compare the computational times!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b414bd2-7ed9-4b2b-bcdb-403e1971a438", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Kerchunk virtual Zarr creation time: \"\n", + " f\"{kerchunk_time:.0f}s ({kerchunk_time/60:.1f} min)\")\n", + "print(\"VirtualiZarr virtual Zarr creation time: \"\n", + " f\"{virtualizarr_time:.0f}s ({virtualizarr_time/60:.1f} min)\")\n", + "print(\"open_mfdataset dataset creation time: \"\n", + " f\"{open_mfdataset_time:.0f}s ({open_mfdataset_time/60:.1f} min)\")\n", + "print(f\"Time ratio: Kerchunk to open_mfdataset = {kerchunk_time/open_mfdataset_time}\\n\"\n", + " f\" VirtualiZarr to open_mfdataset = {virtualizarr_time/open_mfdataset_time}\\n\"\n", + " f\" Kerchunk to VirtualiZarr = {kerchunk_time/virtualizarr_time}\")" + ] + }, + { + "cell_type": "markdown", + "id": "948bea17-7fd2-44bb-aed8-2f0d40056603", + "metadata": {}, + "source": [ + "As we can see the Kerchunk is about 1.6x faster than VirtualiZarr and about the same speed as `open_mfdataset` for creating the `Dataset`.\n", + "Therefore, it is definitely worth creating a virtual Zarr store in this case.\n", + "Looking at read speed after the virtual Zarr store creation:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "082d983f-7528-4dfb-8a48-a8eeaffbd92c", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Kerchunk virtual Zarr read time: \"\n", + " f\"{kerchunk_read_time:.2f}s\")\n", + "print(\"VirtualiZarr virtual Zarr read time: \"\n", + " f\"{virtualizarr_read_time:.2f}s\")\n", + "print(\"open_mfdataset dataset read/creation time: \"\n", + " f\"{open_mfdataset_time:.0f}s ({open_mfdataset_time/60:.1f} min)\")\n", + "print(f\"Time ratio: Kerchunk to open_mfdataset = {kerchunk_read_time/open_mfdataset_time}\\n\"\n", + " f\" VirtualiZarr to open_mfdataset = {virtualizarr_read_time/open_mfdataset_time}\\n\"\n", + " f\" Kerchunk to VirtualiZarr = {kerchunk_read_time/virtualizarr_read_time}\")" + ] + }, + { + "cell_type": "markdown", + "id": "e1071966-3d4b-43fa-9274-ce2be1933c63", + "metadata": {}, + "source": [ + "From this, it is very clear that performing more than one read using either the Kerchunk or VirtualiZarr virtual Zarr store is more efficient that reading with `open_mfdataset`.\n", + "Additionally, the differences in read times between Kerchunk and Virtualizarr, while appearing drastic, is likely not going to be significant in any workflow." + ] + }, + { + "cell_type": "markdown", + "id": "b6c44f7d-9bca-4856-a0ea-7212a48a52a2", + "metadata": {}, + "source": [ + "## Appending to Existing Virtual Zarr Store\n", + "\n", + "As noted when [introducing the gridMET data](#Example-Comparison), we did not utilize the 2019 data in order to show how to append it to a virtual Zarr store.\n", + "The ability to append more data to the virtual Zarr store is highly convienient, as plenty of datasets are continuously updated as new data becomes available.\n", + "So, let's appends some data to our virtual Zarr stores we just made.\n", + "\n", + "First, we create the 2019 file glob." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b657a5f-752c-4236-a62d-809e79c7d4c2", + "metadata": {}, + "outputs": [], + "source": [ + "file_glob_2019 = fs.glob('s3://mdmf/gdp/netcdf/gridmet/gridmet/*_2019.nc')" + ] + }, + { + "cell_type": "markdown", + "id": "17b1fbd6-5038-4a54-8ec3-cd78a57b03de", + "metadata": {}, + "source": [ + "### Create New Virtual Zarr for New File\n", + "\n", + "Next, we need to get our 2019 NetCDFs into a virtual Zarr store.\n", + "\n", + "#### Kerchunk\n", + "\n", + "We will do this for Kerchunk the same way we did before, by using [`kerchunk.hdf.SingleHdf5ToZarr`](https://fsspec.github.io/kerchunk/reference.html#kerchunk.hdf.SingleHdf5ToZarr), which translates the content of one HDF5 (NetCDF4) file into Zarr metadata." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04faebef-edba-43ff-9db4-dccbd3bc5a3e", + "metadata": {}, + "outputs": [], + "source": [ + "tasks = [generate_single_virtual_zarr(file) for file in file_glob_2019]\n", + "single_virtual_zarrs_2019 = dask.compute(*tasks)" + ] + }, + { + "cell_type": "markdown", + "id": "f3e76b73-4e61-4a67-9253-6a84e479d260", + "metadata": {}, + "source": [ + "#### VirtualiZarr\n", + "\n", + "And for VirtualiZarr, we will use [`virtualizarr.open_virtual_dataset`](https://virtualizarr.readthedocs.io/en/stable/generated/virtualizarr.backend.open_virtual_dataset.html#virtualizarr-backend-open-virtual-dataset)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22940c8d-10ff-467c-922d-9d1777cfdda9", + "metadata": {}, + "outputs": [], + "source": [ + "tasks = [\n", + " dask.delayed(open_virtual_dataset)(\n", + " f's3://{file}',\n", + " indexes={},\n", + " loadable_variables=['day', 'lat', 'lon', 'crs'],\n", + " decode_times=True,\n", + " reader_options=reader_options\n", + " )\n", + " for file in file_glob_2019\n", + "]\n", + "\n", + "virtual_datasets_2019 = dask.compute(*tasks)" + ] + }, + { + "cell_type": "markdown", + "id": "d9b22cd8-f39f-4f52-9bbb-3ecbaa53682a", + "metadata": {}, + "source": [ + "### Append to Existing Store\n", + "\n", + "Now, we can append the virtualized NetCDFs to our existing stores.\n", + "\n", + "#### Kerchunk\n", + "\n", + "For Kerchunk, we will use still [`kerchunk.combine.MultiZarrToZarr`](https://fsspec.github.io/kerchunk/reference.html#kerchunk.combine.MultiZarrToZarr).\n", + "However, this time we will need to use the `append` method to append our new data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "349f7e19-0635-402c-98ca-8c85f5579b9a", + "metadata": {}, + "outputs": [], + "source": [ + "# Append to the existing reference file\n", + "mzz = kerchunk.combine.MultiZarrToZarr.append(\n", + " single_virtual_zarrs_2019,\n", + " original_refs=out,\n", + " concat_dims=[\"day\"],\n", + " remote_protocol='s3',\n", + " remote_options=reader_options['storage_options'],\n", + ")\n", + "\n", + "out_2019 = mzz.translate()\n", + "\n", + "# Save the virtual Zarr store, serialized as json\n", + "with fs_local.open('virtual_zarr/kerchunk/gridmet_appended.json', 'wb') as f:\n", + " f.write(ujson.dumps(out_2019).encode())" + ] + }, + { + "cell_type": "markdown", + "id": "0e9fba22-70f3-4192-a067-d431c96237a1", + "metadata": {}, + "source": [ + "#### VirtualiZarr\n", + "\n", + "For VirtualiZarr, we can just use `xarray.concat` and `xarray.merge` like would to combine any `xarray.Dataset`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "030add3c-eee2-42b9-9039-3282c9b49711", + "metadata": {}, + "outputs": [], + "source": [ + "virtual_ds_2019 = xr.merge(virtual_datasets_2019, compat='override', combine_attrs='override')\n", + "virtual_ds = xr.concat([virtual_ds, virtual_ds_2019], dim='day', coords='minimal', compat='override', combine_attrs='override')\n", + "virtual_ds" + ] + }, + { + "cell_type": "markdown", + "id": "a8259334-e55d-418b-b260-893a255bbec8", + "metadata": {}, + "source": [ + "This simple `xarray.merge` and `concat` is the major advantage of VirtualiZarr.\n", + "Rather than having to figure out Kerchunk's syntax and commands, we can keep using xarray as we already do.\n", + "Therefore, the increase in time to create the virtual Zarr store compared to Kerchunk is likely worth it due to its native compatibility with xarray." + ] + }, + { + "cell_type": "markdown", + "id": "aff1cd3e-2f55-41ab-9dae-64f1a67f51d9", + "metadata": {}, + "source": [ + "### Double Check New Stores\n", + "\n", + "Finally, let's read in the appended stores to make sure that we correctly appended the 2019 data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30423f47-7a4d-4ff3-9e94-8cc1268cabd7", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(\n", + " 'virtual_zarr/kerchunk/gridmet_appended.json',\n", + " engine=\"kerchunk\",\n", + " chunks={},\n", + " backend_kwargs={\n", + " \"storage_options\": {\n", + " \"remote_protocol\": \"s3\",\n", + " \"remote_options\": reader_options['storage_options']\n", + " },\n", + " }\n", + ")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "e2f33304-1bc2-4c28-8a2a-37c217c6b44f", + "metadata": {}, + "source": [ + "Nice!\n", + "The 2019 data is now appended and showing on the day coordinate." + ] + }, + { + "cell_type": "markdown", + "id": "446b9e9e-cc6d-432c-b822-e3dac040c66c", + "metadata": {}, + "source": [ + "## Clean Up\n", + "\n", + "Rather than deleting the virtual Zarr stores that we created, we will actually keep them for use in future tutorials.\n", + "However, we will do want to conform with best practices and close our Dask client and cluster." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "433b1321-8bc7-422a-a81c-d0bf2b87fef4", + "metadata": {}, + "outputs": [], + "source": [ + "client.close()\n", + "cluster.close()" + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/IncludeCRSinZarr.ipynb b/201/IncludeCRSinZarr.ipynb new file mode 100644 index 0000000..6d49d21 --- /dev/null +++ b/201/IncludeCRSinZarr.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "338bbd68-eb43-4687-a4dc-f3d5f5d46142", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Adding Coordinate Reference Systems (CRS) to Zarr Datasets" + ] + }, + { + "cell_type": "markdown", + "id": "0d8b8c41-f241-4b6b-9e9c-de7c0d98f236", + "metadata": {}, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "This notebook is a pared down version of the material in [this notebook by Kieran Bartels and Sarah Jordan](https://code.usgs.gov/wma/nhgf/geo-data-portal/gdp_data_processing/-/blob/main/workflows/opendap/CIDA/crs_notebooks/tutorial.ipynb).\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "markdown", + "id": "6aefa4fe-f265-4803-be6c-11f56f0eefd9", + "metadata": {}, + "source": [ + "The goal of this notebook is to learn how to add and verify the addition of coordinate reference systems (CRS) to Zarr datasets.\n", + "We will be utilizing [the Climate and Forecast (CF) Metadata Conventions](https://cfconventions.org/) for our CRS format and to determine where we include the CRS in the Zarr store.\n", + "While these conventions were [originally designed for NetCDF files](https://cfconventions.org/cf-conventions/cf-conventions.html), Zarr has become the cloud optimized alternative to NetCDF, and it retains the same general metadata and data representation standards.\n", + "Therefore, we can easily apply the CF conventions to promote the standardization and interoperability of climate data even within Zarr stores." + ] + }, + { + "cell_type": "markdown", + "id": "f14c6b29-9a49-406b-8c28-5d88ebe82af1", + "metadata": {}, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "See the [blog post by Thomas Martin and Ward Fisher](https://www.unidata.ucar.edu/blogs/news/entry/netcdf-vs-zarr-an-incomplete) for some details on the differences between Zarr and NetCDF.\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1855bd3c-33d8-4a37-81cf-0d14084c5985", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import ujson\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "id": "d0a0f6f0-09c5-4371-8fda-2d4eda6db2d1", + "metadata": {}, + "source": [ + "## Example Dataset\n", + "\n", + "In this notebook, we will use the virtual Zarr store of the daily gridMET dataset that we created in [the notebook on Generating a Virtual Zarr Store](VirtualZarr.ipynb).\n", + "Note that this means you will need to run that notebook to run this one.\n", + "However, the contents of this example can easily be used for any Zarr store, virtual or not.\n", + "The only difference will be how the data is read in.\n", + "\n", + "On that note, let's read in the data using [`xarray.open_dataset`](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html) and Kerchunk as the engine (i.e., `engine='kerchunk'`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c2c18828-52d0-4147-84f6-c45689e3cdb0", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(\n", + " 'virtual_zarr/kerchunk/gridmet.json',\n", + " engine='kerchunk',\n", + " chunks={},\n", + " backend_kwargs={\n", + " 'storage_options': {\n", + " 'remote_protocol': 's3',\n", + " 'remote_options': {\n", + " 'anon': True,\n", + " 'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + " },\n", + " }\n", + ")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "c8f57316-5459-496c-819f-c6cff25f0857", + "metadata": {}, + "source": [ + "## Identify the CRS\n", + "\n", + "A \"[**coordinate reference system**](../back/Glossary.md#term-Coordinate-Reference-System)\" (CRS) is a framework used to precisely measure locations on the surface of Earth as coordinates ([wikipedia.org, 2024](https://en.wikipedia.org/wiki/Spatial_reference_system)).\n", + "To be CF-Compliant, a dataset must contain a \"grid mapping\" variable that is used to explicitly declare the CRS for any variables with spatial dimensions.\n", + "Specifically, the grid mapping variable provides the description of the CRS via a collection of attached attributes.\n", + "Common grid mapping variable names include:\n", + "- `crs`,\n", + "- `polar_stereographic`,\n", + "- `albers_conical_equal_area`,\n", + "- `rcm_map`.\n", + " \n", + "Spatial variables that need the CRS to define their positions are then linked to the grid mapping variable by having a `grid_mapping` attribute, which is set to the name of the grid mapping variable.\n", + "\n", + "To locate the grid mapping variable, the first thing is to check for a variable (or coordinate) with one of the common grid mapping variable names.\n", + "If one exists, it can be confirmed to be the grid mapping by checking a spatial variable for the `grid_mapping` attribute and making sure it matches the grid mapping variable name.\n", + "If so, you are good to go.\n", + "Otherwise, still check a spatial variable for a `grid_mapping` attribute.\n", + "If there is one, but no variable by the given name, or no attribute at all; you will need to create the CRS given what you know about the data.\n", + "However, creating a CRS is beyond this notebook and we refer readers to [this notebook by Kieran Bartels and Sarah Jordan](https://code.usgs.gov/wma/nhgf/geo-data-portal/gdp_data_processing/-/blob/main/workflows/opendap/CIDA/crs_notebooks/tutorial.ipynb) on how to add a missing CRS.\n", + "\n", + "Okay, now that we know how to identify the CRS, let's look at our data again and check for it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e279c411-0a1e-400c-bc6f-28b00dd1d203", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "574eb891-4ae9-4963-b98b-476e2f8e4835", + "metadata": {}, + "source": [ + "Right away, we can see that the dataset has a `crs` coordinate, and a check of a spatial variable, say `precipitation_amount`, shows a `grid_mapping` attribute of `crs`.\n", + "So, this dataset already has the CRS info, and it is stored in the `crs` coordinate with a dimension of `crs`.\n", + "\n", + "## Making the CRS CF compliant\n", + "\n", + "While we have the CRS info, to be CF compliant, the CRS needs to be a dimensionless **data variable**.\n", + "Since it is currently a coordinate with a dimension, we can convert it to a variable by squeezing ([`squeeze`](https://docs.xarray.dev/en/stable/generated/xarray.Dataset.squeeze.html#xarray.Dataset.squeeze)) out the `crs` dimension and reseting the `crs` coordinate ([`reset_coords`](https://docs.xarray.dev/en/stable/generated/xarray.Dataset.reset_coords.html))." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c7c4cde-abc7-4f75-bf5e-e9cc7adfacbb", + "metadata": {}, + "outputs": [], + "source": [ + "ds.squeeze().reset_coords('crs')" + ] + }, + { + "cell_type": "markdown", + "id": "9643d347-3152-4d06-a6df-16e0edc0343a", + "metadata": {}, + "source": [ + "Nice, that did it!\n", + "However, this actually gets us a CF compliant CRS for the **in-memory** dataset, and it does not actually adjust the Zarr store to be CF compliant.\n", + "As we don't want to rewrite the whole Zarr store, we can fix this by directly adjusting some of the keywords in the json serialized Zarr store.\n", + "\n", + "```{note}\n", + "The following code is for our virtual Zarr store, which is a single json file with nested keys that make the Zarr store.\n", + "See [below](#Adding-CRS-to-a-Regular-Zarr-Store) for how to adjust the CRS in a regular, non-virtual Zarr store.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e36dedcc-bd1f-4905-b199-d317fd095cf9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "fs_local = fsspec.filesystem('')\n", + "\n", + "virtual_zarr_store = ujson.load(fs_local.open('virtual_zarr/kerchunk/gridmet.json'))\n", + "\n", + "zattrs = ujson.loads(virtual_zarr_store['refs']['crs/.zattrs'])\n", + "zattrs['_ARRAY_DIMENSIONS'] = []\n", + "virtual_zarr_store['refs']['crs/.zattrs'] = ujson.dumps(zattrs)\n", + "\n", + "zarray = ujson.loads(virtual_zarr_store['refs']['crs/.zarray'])\n", + "zarray['chunks'] = []\n", + "zarray['shape'] = []\n", + "virtual_zarr_store['refs']['crs/.zarray'] = ujson.dumps(zarray)\n", + "\n", + "with fs_local.open('virtual_zarr/kerchunk/gridmet_cf_crs.json', 'wb') as f:\n", + " f.write(ujson.dumps(virtual_zarr_store).encode())" + ] + }, + { + "cell_type": "markdown", + "id": "825c7d3d-f914-438b-9a12-799420e2c210", + "metadata": {}, + "source": [ + "Now that we have updated our virtual Zarr store, let's read it in to make sure everything looks right." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af842f45-f1cc-4dd9-b52a-329230c66512", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(\n", + " 'virtual_zarr/kerchunk/gridmet_cf_crs.json',\n", + " engine='kerchunk',\n", + " chunks={},\n", + " backend_kwargs={\n", + " 'storage_options': {\n", + " 'remote_protocol': 's3',\n", + " 'remote_options': {\n", + " 'anon': True,\n", + " 'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + " },\n", + " }\n", + ")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "4e3481c1-f819-4b5f-ab96-aa3acd2b513a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "Look at that, easy as can be, and we now have a CF compliant virtual Zarr store!\n", + "\n", + "## Adding CRS to a Regular Zarr Store\n", + "\n", + "As you may want to apply this process to a regular Zarr store, we have included some code that does the same adjustments as above, but for a regular Zarr store.\n", + "\n", + "```python\n", + "zarr_store_path = 'gridment.zarr'\n", + "\n", + "with fs_local.open(f'{zarr_store_path}/crs/.zattrs', 'wb') as f:\n", + " orig_metadata = ujson.load(f) \n", + " orig_metadata['_ARRAY_DIMENSIONS'] = []\n", + " f.write(ujson.dumps(orig_metadata).encode())\n", + "\n", + "with fs_local.open(f'{zarr_store_path}/crs/.zarray', 'wb') as f:\n", + " orig_metadata = ujson.load(f) \n", + " orig_metadata['shape'] = []\n", + " orig_metadata['chunks'] = []\n", + " f.write(ujson.dumps(orig_metadata).encode())\n", + "```" + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/NWM_1km_DFReferenceFileSystem-local.ipynb b/201/NWM_1km_DFReferenceFileSystem-local.ipynb deleted file mode 100644 index e1f39ba..0000000 --- a/201/NWM_1km_DFReferenceFileSystem-local.ipynb +++ /dev/null @@ -1,3990 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "05681bd5-20c7-4528-822c-6ca6826714d4", - "metadata": {}, - "source": [ - "# Open NWM 1km dataset as DFReferenceFileSystem \n", - "\n", - "Open dataset as a fsspec `DFReferenceFileSystem` filesystem by reading references from a collection of Parquet files: one file containing global metadata and coordinate variable references, and one file for each of the data variables. \n", - "\n", - "The big wins here are lazy-loading of the references for each variable, and the more efficient construction of the virtual fsspec filesystem from the Parquet files (JSON is slow to decode)." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "584ab9a2-4f6b-4907-93b1-3d2b0786f601", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "from fsspec.implementations.reference import DFReferenceFileSystem\n", - "import xarray as xr" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "732722cb-4430-4359-9014-eb9c551e7873", - "metadata": {}, - "outputs": [], - "source": [ - "fs = fsspec.filesystem('s3', anon=True, \n", - " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "c6f5f293-ced5-44c2-8231-a77e22c451e1", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip/noaa/nwm/lazy_refs'" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "691c9634-cc24-407f-ae56-50d4247960a5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of reference files: 21\n", - "Total size of references: 0.492091486 GB\n" - ] - } - ], - "source": [ - "print(f'Number of reference files: {len(fs.ls(s3_lazy_refs))}')\n", - "print(f'Total size of references: {fs.du(s3_lazy_refs)/1e9} GB')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b5f4c4da-27c1-4374-ba60-61315cd965b1", - "metadata": {}, - "outputs": [], - "source": [ - "r_opts = {'anon': True}\n", - "s3_lazy_refs = './combined.parq'" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "69e11199-c729-42a0-ad25-0cbbf97088df", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.98 s, sys: 379 ms, total: 5.36 s\n", - "Wall time: 8.89 s\n" - ] - } - ], - "source": [ - "%%time\n", - "fs2 = DFReferenceFileSystem(s3_lazy_refs, lazy=True, \n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs2.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "cd8ddfb0-7b57-43aa-98dc-b9a837e57542", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "04d02447-a134-45eb-978f-e0d392435dbb", - "metadata": {}, - "source": [ - "Examine a specific variable:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "ce2ec93e-a879-459f-804c-66a9f977db3f", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'TRAD' (time: 116631, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-cd5df30e9fe2fa406c82b97203ab8a0aTRAD, shape=(116631, 3840, 4608), dtype=float64, chunksize=(1, 768, 922), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Surface radiative temperature\n",
-       "    units:           K\n",
-       "    valid_range:     [0, 4000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Surface radiative temperature\n", - " units: K\n", - " valid_range: [0, 4000]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.TRAD" - ] - }, - { - "cell_type": "markdown", - "id": "151133ab-e6ee-4903-b23a-36bfef0286d9", - "metadata": {}, - "source": [ - "How big would the uncompressed size of the whole dataset be?" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "8dd5b70a-2585-4dce-b0b1-a2cd915c7952", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "462.28064798432" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.nbytes/1e12 #TB" - ] - }, - { - "cell_type": "markdown", - "id": "7496c3b2-ae11-4af4-952f-18c3f3a3b73c", - "metadata": {}, - "source": [ - "Load some data at a specific time step. The first time a variable is accessed it will take longer as the references need to be loaded." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "7b0a2164-053c-4f84-a9b7-172bf3cd83a5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 6.52 s, sys: 1.21 s, total: 7.74 s\n", - "Wall time: 10.4 s\n" - ] - } - ], - "source": [ - "%%time \n", - "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "26510252-7ec2-4e21-8ddf-aff2eca56793", - "metadata": {}, - "source": [ - "Loading data for another time step is much faster as the references are already loaded:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "ef01e203-f6cd-4c4e-ac3d-410afd5a4524", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.05 s, sys: 404 ms, total: 4.45 s\n", - "Wall time: 6.24 s\n" - ] - } - ], - "source": [ - "%%time\n", - "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "1f41f59f-12aa-4e4c-bf64-c61ecfe50db5", - "metadata": {}, - "source": [ - "Compute the mean over the domain:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "bd30a9a2-2264-4628-8826-8b965fe55ded", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(266.92635398)" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "da.mean().data" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "73fe200b-ee97-4f49-8d42-60d53d0a7160", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlMAAAHFCAYAAADWlnwrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9ebwcVZk/jr/Pqerue282CMg2KiGBJGQBERFx+eh83Z1xxH1URBCdUQGlb0IgC9kXSMhtEIFxQVBBRUfB0fmNu+g4DIrIEhKSQEIQR1aBbPfe7q46z++P5zxnqe6bBBJCkH5er7rdt+rUqVOnqs95n/ezKSIidKQjHelIRzrSkY505BmJfq4b0JGOdKQjHelIRzryfJYOmOpIRzrSkY50pCMd2Q3pgKmOdKQjHelIRzrSkd2QDpjqSEc60pGOdKQjHdkN6YCpjnSkIx3pSEc60pHdkA6Y6khHOtKRjnSkIx3ZDemAqY50pCMd6UhHOtKR3ZAOmOpIRzrSkY50pCMd2Q3pgKmOdKQjHelIRzrSkd2QDpjqyAtebr75ZsyfPx9PPfVUy7E3vOENeMMb3rDX27Q3ZP369Zg+fTqOP/547Lfffhg9ejRe85rX4N///d/bln/00Udx2mmn4cADD0RPTw9OOukk/OIXv2gp96Mf/Qinnnoqpk6dilKpBKVU2/o2bdoEpVTb7dvf/vYu38eebtfO5LLLLsPEiRNRqVRwxBFHYMGCBWg2m1GZP//5zzjnnHPw+te/Hvvttx+UUrjmmmue0fU60pGO7PvSAVMdecHLzTffjAULFrQFU1dccQWuuOKKvd+ovSA//elP8Z//+Z9473vfi+9+97u47rrrcNRRR+H9738/Fi5cGJWt1+t44xvfiF/84he49NJL8YMf/AAHH3ww3va2t+HXv/51VPaGG27ALbfcgkmTJuHYY4/daTvOPvts/O///m+0vfnNb96le3g229VOlixZgs997nN4z3veg5/85Cf4zGc+g6VLl+LMM8+Myt1333247rrrUC6X8Y53vOMZXasjHenI80ioIx15gcuKFSsIAN1///3PdVP2qjz22GNkjGnZ/w//8A/U09NDg4ODbt/ll19OAOjmm292+5rNJk2aNIle+cpXRufnee6+n3nmmTTUMHP//fcTAFqxYsUzvodno11DyeOPP05dXV30L//yL9H+JUuWkFKKVq9e3fZat956KwGgq6+++mldryMd6cjzRzrMVEde0DJ//nyce+65AIAjjjjCqZluuukmAK1qPlFNrVixAhdddBHGjBmD7u5uvOENb8D69evRbDZx/vnn47DDDsOoUaPw7ne/G48++mjLda+//nqcdNJJGDZsGIYPH463vvWtuP322/fGLTs58MAD26q6XvnKV6K/vx9PPPGE23fDDTdgwoQJOOmkk9y+NE1xyimn4Pe//z3+7//+z+3Xeu8NK3uzXT/+8Y8xODiI008/Pdp/+umng4hw44037rFrdaQjHXl+SecX35EXtHziE5/A2WefDQD4/ve/79RML3/5y3d43uWXX47/+Z//weWXX46vfOUrWLt2Ld75znfijDPOwGOPPYavfvWrWL58OX7+85/jE5/4RHTu0qVL8aEPfQiTJk3Cd77zHXzjG9/A1q1b8brXvQ5r1qzZaZuzLNuljYieUZ/86le/wote9CIcdNBBbt/dd9+NY445pqWs7Fu9evUzuhYAXHjhhSiXy+jp6cFrX/ta/Md//Mcun/tstqvdtQBg6tSp0f5DDz0UBx54oDvekY505IUn6XPdgI505LmUF7/4xXjpS18KADjuuOMwZsyYXTpvv/32w4033ugYiMcffxznnHMOJk6ciB/84Aeu3Nq1a3HJJZdgy5YtGDlyJB588EHMmzcPZ511Fj7/+c+7cm9+85tx1FFHYcGCBbj++uuHvO6mTZtwxBFH7FIbf/WrXz1t4/mvfOUruOmmm3DppZciSRK3/69//StGjx7dUl72/fWvf31a1wGASqWCT37yk3jzm9+MQw89FH/6059w2WWX4V3vehe+/OUvt4DQdvJstGtH16pUKhg2bFjb6+3Ja3WkIx15fkkHTD0N+c1vfoMVK1bgtttuw0MPPYQbbrgBJ5988tOqg4iwcuVKfOlLX8IDDzyAgw46CJ/+9Kcxa9asZ6fRHXlW5B3veEekyjn66KMBAP/wD/8QlZP9f/rTnzBlyhT85Cc/QZZlOPXUU5FlmSvX1dWF17/+9fjVr361w+sedthhuPXWW3epjRMmTNilciL/9V//hTPPPBPve9/7HFsXyo68356JZ9yhhx6KL33pS9G+97///TjxxBNx/vnn47TTTkOapiAi5HkelUtTP3Tt6XaFzwUAkiRx9ezpa3WkIx3525AOmHoasn37dhx77LE4/fTT8d73vvcZ1fG5z30OP/3pT3HxxRdj6tSp2Lx5Mx5//PE93NKOPNtSZEPK5fIO9w8ODgIAHnnkEQDACSec0LbendnalMtlvOxlL9ulNobM0s7kJz/5Cd7znvfgzW9+M6677roWYHDAAQe0ZV7ErqodO/RMpFQq4YMf/CDOP/983HvvvTj66KPxta99rcVOSVSYz0a7SqVS9P/VV1+N0047DQcccAAGBwfR39+Pnp6elusdf/zxT/taHelIR/42pAOmnoa8/e1vx9vf/vYhjzcaDcyZMwfXXXcdnnrqKUyZMgUXXXSRU7Xcc889uPLKK3H33Xc/bdagI38bcuCBBwIA/v3f/x2HH3740z7/2VDz/eQnP8HJJ5+M17/+9fje977nAGAoU6dOxapVq1r2y74pU6bsUpt2RQQoCbB85zvfOSQb92y0q3gt6W+xlVq1ahVOPPFEd/zhhx/G448/vkf7oCMd6cjzSzpgag/K6aefjk2bNuHb3/42DjvsMNxwww1429vehlWrVuGoo47CD3/4Q4wdOxY/+tGP8La3vQ1EhDe96U1Yvnz5HlvZd+TpS6VSAQAMDAw869d661vfijRNsWHDhmfEbu5pNd9Pf/pTnHzyyXjta1+LG2+80fVFUd797nfjM5/5DH73u985IJFlGa699lqceOKJOOyww3b9JnYgzWYT119/PQ488EAceeSRAJh9OuCAA/Zau17xile03f+2t70NXV1duOaaayIwdc0110Ap9bRV/h3pSEf+dqQDpvaQbNiwAd/61rfw5z//2Q3g06dPx49//GNcffXVWLp0KTZu3IgHHngA3/3ud/H1r38deZ6jWq3ife97H375y18+x3fwwhVhHC699FJ87GMfQ6lUwoQJEzBixIg9fq0xY8Zg4cKFmD17NjZu3Ii3ve1t2H///fHII4/g97//PYYNG4YFCxYMeX65XB5ysn+68tvf/hYnn3wyDjnkEMyaNQt33HFHdHzSpEkYOXIkAODjH/84Lr/8crz//e/HhRdeiIMOOghXXHEF1q1bh5///OfReQ888IADfBs2bAAAF1V9zJgxrv29vb1oNpt4zWteg0MOOQQPPvggLrvsMtxxxx24+uqrd0lN+Wy0aygZPXo05syZgwsuuACjR4/GW97yFtx6662YP38+PvGJT2DSpElReal748aNAIA//OEPGD58OADgfe97307vrSMd6cjzSJ7DGFfPawFAN9xwg/v/O9/5DgGgYcOGRVuapvSBD3yAiIg++clPEgBat26dO++2224jALR27dq9fQsdCWTmzJl02GGHkdaaANCvfvUrIiJ6/etfT69//etduaECTf7qV78iAPTd73432n/11VcTALr11luj/TfeeCP9/d//PY0cOZIqlQodfvjh9L73vY9+/vOfPyv3107mzZtHAIbcpA9EHn74YTr11FNp9OjR1NXVRa961avoZz/7WUu9cs/tto997GOu3FVXXUWvfOUrafTo0ZSmKe2///701re+lX7yk588rfvY0+3amVx66aU0fvx4KpfL9NKXvpTmzZtHjUajpdyO+rYjHenI35YoomcYjOYFLkqpyJvv+uuvx0c+8hGsXr26ZUU9fPhwHHLIIZg3bx6WLl0a5fEaGBhAT08PfvrTn+5yCo2OdKQjHelIRzqy70hHzbeH5LjjjkOe53j00Ufxute9rm2Z17zmNciyDBs2bMC4ceMAcLJZAM/IGLkjHelIRzrSkY4899Jhpp6GbNu2Dffddx8ABk99fX34+7//e4wePRovfelLccopp+B//ud/sHLlShx33HF4/PHH8ctf/hJTp07FO97xDhhjcMIJJ2D48OG45JJLYIzBmWeeiZEjR+KnP/3pc3x3HelIRzrSkY505JlIB0w9Dbnpppvw93//9y37P/axj+Gaa65Bs9nE4sWL8fWvfx3/93//hwMOOAAnnXQSFixY4Iyc//KXv+Dss8/GT3/6UwwbNgxvf/vbsXLlyo43X0c60pGOdKQjz1PpgKmOdKQjHelIRzrSkd2QTqLjjnSkIx3pSEc60pHdkA6Y6khHOtKRjnSkIx3ZDel48+1EjDH4y1/+ghEjRnQSmXakIx3pSEd2KESErVu34rDDDttprs3dkcHBQTQajd2up1wuo6uraw+06IUtHTC1E/nLX/6Cl7zkJc91MzrSkY50pCPPI3nwwQfx4he/+Fmpe3BwEEccPhwPP5rvdl2HHHII7r///g6g2k3pgKmdiKQUefDBB11qDZE3/mIetCL0lBrY1qjgF28cOg0IALz5l3PRzBMYKDSaKZQiZLlGbhTyRgpdyqEUQSuC1sBgfwlkmA3rGtYAEUCkYIwCGYWskaJ7eB1ZpgFSMLlGPpgCmqBT/yO76wPTMfX6laBcg5oaqqGgMw1S3vdA5QqUEHRTwZR5vyIg6dcwJUJeISAlUMlAlQxK3Rx4tJQaVEoZslxDKYIxGoa4zURAlmtQrkBGA4r4OylQpgFtr6ODdigCFO8jo6AU1wN770q1+kuQXM8o3P2hXgDAlOtqgOLz3CcAkOL6jIIyAHIFlSkI50jg8irn4yq3ZXNbj+3WsBmuHArHjD1mNxf/2pb53wvPxGvOvRz/s+JMvLb3cj5P2ivnF26XFNdFCWBSQOf8+T8rzmzpl1fOvTy+tmsgcMvSM/GqWZcDFHdP+P2WZVznq2ZeHlccELS3LD0Tr5p9OUjxfvmMKlO+7VCF/wv1yb7bZrXeT0eembxi8eX4wxzfn6+aeTm0vM9A9E4OJf+z4ky8ZvrlvgzZ8gbR83P1qUI5AhQRyLL78l0R+TJBW6I6C+3y9QXHiIBAc/DLL5+F/++TX8Avv3wW3njGZfjFVWcDAP6/T34hbqoQR8V3lPi39csvnYU3fPoLrlx4TWX4My8r6IzcPlMfxB03LHpW0lGJNBoNPPxojgduG4ORI545+7Vlq8Hhx29Co9HYJTB15ZVX4sorr8SmTZsAAJMnT8bcuXPx9re/HQCzcgsWLMCXvvQlPPnkkzjxxBNx+eWXY/Lkya6Oer2O6dOn41vf+hYGBgbwxje+EVdcccWzBjz3lnS8+XYiW7ZswahRo7B58+YWMPXmm6p4bPtwHDx8KwDgJ6+/ZId1vfLHs/D7ty3Fy/9/cxz46B+oOOBABHR3NbHqnxbgqO8uhtKE5mCK+z8yE0ffsABpYpAbBWM0skyDSKFczpAb7UBXczAFCNh06vkY840LAaMYtBgF2Gvofh+hXTeUH1DITtQlgkmAdLsGpcSbBigloCeH0gZKE5KS/dQ8qqSJQZIYEAHG6Bbgk+UaWZ7ACKCyn2G5pGTPz7lRMj6SKYCpYLAmUvxp2szO8OVkECTD5VWmeZ8AJ/KTuTLKgSGQBVe2f9wEouAAj8p9/W6wd+fC1V8EVHfVqnjZ2TXojMtR4gd0qVMZHvQV2cFf7iPh/+/4QhUA8LKza7jjsiqOqdZA9hGTar1u28mvjazq43qn9tZ4fimCJIK7jqtKB30D21e2zcVjVPwetG3t/Gr7RnXkacnE+TUkdbj3UOcFYF8AVEABVNnv8o4dd2YNAHD75VW8/NO1uJx9L/74b1W8/FM1/vzXWnswZTyKl99dBKiGAHrh+yxgRhmKfrv+RhRuubbX/fva916M335vOk44vQ8643f399fw8Vd+rM+eU1gQSDNUazvldynHAbu4GRjEbd+Z3XbO2FMi89Jf1x+x22DqgPH373Jbf/jDHyJJEpeE/Gtf+xpWrFiB22+/HZMnT8ZFF12EJUuW4JprrsH48eOxePFi/OY3v8G6descuPz0pz+NH/7wh7jmmmtwwAEHYNq0aXjiiSdw22237VI+zn1VOgbouyHNPEF3qYltjQr0jpZ1VupZgmN/dAFyo5DlGsZolMsZKqUMXZUm7vvAHKz6pwU4+oYF6Ko0kSY5klKOcd9eilKaY/u2CtLEwBiFSiVDkhoMbK2gOZCiOZAyADEKShOOuHYZkCts+th5oKbmwSEhlB4v4f6zpoE0gRRgSgRK/OqQSgSTEq+wygSYYJCyK9GuYaynV4qQJjnyXENrgiGFZpYwe0YKufGvl3zXiqATYaSYgUrLOZKSARSDKAFSgGWlgrK8T8XgQMQNgtRmY9l02nlBeTugawsWWwZjO1haIEna/+8GXbuPEgssgsE4KhvUr+AH5GM/V4suSUFZSmz9ATCCAnRO7loA8PJ/rfnnA7TcC4VtKfZVgS0KJ5GpvTXfD4Xjcs93r6j6+9PB+TJha19+h0CqMIFNnB/3ywtZ5Dm45/E0ZO38KgPxdiAqAOYA77vz8wUQa5/Ly86q4WVn+eu//NM1fq8KAFuAFAD36cQCqtu+zO/MH77SCyjg1q/24g9X9eLWr/ZGdbkmBD9jWdDI4kS2//3mtKj8LddNgzKEV39wJV79wZV4zftXwiTc2Fuv7nXXOOHjfTjh433u/c1LCiZV7t5Ic/vk3TSpf0mN1esUf2vt1nLPluRkdnt7OvLOd74T73jHOzB+/HiMHz8eS5YswfDhw3HLLbeAiHDJJZdg9uzZeM973oMpU6bga1/7Gvr7+/HNb34TALB582ZcddVVWLlyJd70pjfhuOOOw7XXXotVq1a1JCZ/vkkHTO2GdJeayI3G/7z5Ijw50LPT8nf+4yIoxZ9pwi+xMQqr/mkBGlmCCd9fiInfX4hmM4EhhcGBMvJmAiJg+/YulLsyAECa5hgcLCGrJ0gquQUXCiZTTnVGRmPTaedhzNcvYhBiB6Pm6AxjLl/pZnSZ5CglGAuk3MBRIlBJmBfFrFRqoBRZBkkhyxNUypm7xzTJndpNK0JuNKv6LAsvKsAk8TqsrJkgtyyR0sYPnMoCKDtiKk0MqhQxs2U8s6U0tbJWxe8Axly9HJEfgQCqxIJKMCtFmly/eHDkARUFIMGBFwEtwUDsQFE4yIYrb1vuj1dWY0AiExUBSd0/E5WzWkHqLm8j9ysW9mDVyiruXlGNBnmH9W3dqy4OJs0ikCp8rlpZxaqVVX8/IeCazpPq6ovaTMJyu21W+UMdK4KqdnL03BpvF/ztA66p02uOIaQUmDqN7/mYpwGsQlbUAWt3MPhOwLGfZXYTAO64rOq+S7nbL68OyWRCwbFVjpUtgDUAeMUn+gACjv9kjQEVgFec0ddaH/l2h/fi9xNAhP/95jSc9KGVHmhlwEkfXslVJMDN10+DKfH5J31oJV51Sp+rQzd5k/bpnJhB08pd+xVncHmdATqj6Pcf3peyv2vai7OqAe32BjDTFW71en2n187zHN/+9rexfft2nHTSSbj//vvx8MMP4y1veYsrU6lU8PrXvx4333wzAOC2225Ds9mMyhx22GGYMmWKK/N8lQ6Y2g35r/93KQ7o2Q4AuOWty3bpHFGJAcLs8P/r3jMX694zF4YU0tSgmSUYPnwQpUqGru4GTK6gtcFd71yILEssGAHyemIZI2uHBM/cjLnmIiDnX/qmj50HyhQe+MS5QClejbiJPyWr3lKePjGAalhw0dCg/hT9W7scgGHQw3Zeot4zwQyprR1VYkFeoo1n8QoMk9KIWKmwgUpZsBQZKxXKKQTl2hyX6gTMyMCXUFSWBJBqVh8IO0SJZ/KMZar8jQLrLqhGTM/aBdWYyQmvadsr+152NqtFikDQpEDWrXx7Ex7U7/hCFXd8oYrGCAZWRYZr6vRa1FUUXEuOu9V3AAJFVvUxgAKAKefWMHV6UH8BCALA5PNqLcfaMVrt6mj7nIZ4dhPn1SIAdvQFNUya87cJqo49J77XEFTc1VdtKd9OJs2uOZZQftICSO68pA2gBr+LgGWj7HcBVcedWYue6+1XVHkhUHhvw0VFsX4A+MNVvbjty1W84oy+CEjd+tXeVqZSwEoBSMlwcNKHeXHo2Cm7CIFlrE768Er87zen4ebvTGuxfQoXMCHQZJUkf0+aQNIATIKI3VPGslYBiGoBq88TeclLXoJRo0a5bdmyoeezVatWYfjw4ahUKvjUpz6FG264AZMmTcLDDz8MADj44IOj8gcffLA79vDDD6NcLmP//fcfsszzVToG6Lspg1mKt/76nJ3aS4l0l5o4/r9mA0hw1zsX4tgfXeCOTbpxPkyeIre/ym31hNVeFYVKdxP9T/awLZViRkuYG2qyHohMYEidK2ZYEgJyjTFfvwggjcO/sgJKQAzATBYByaBG3mWZGQE3RjFjVbb2U00Fc3AdlCvUt1Qw/IB+pEmO/oEKdMIgyRAcWMqtDZPWhtWawkppNqShxCA3Giphm7HQ8IFIQcEDKGeIDjBosjcgDJUbQOWzKG32xxOApcIKZUmuxV/YTkJx34Rsz/qZVV+n5nIT59WgA3sntuvy/UtyLXvZYz/LtkliC2JCRsuuuMVO6uWfrrnjpmBmMHV6LWa/wntuo9qRxpAC7r64iqnTPXgSBqs4QSgCTHF1biekFvuVoUDtDsqsnReDhVDtF7Fs9loCqNYs3jWQ8XwQUqxGnXxejZk/BQdwd1V00zNT8u5KvzkA3qY/VeH9ednZFkSBj91+hQVXn6m5706NLWAjeA9u+1IVx3+y5gzOX/EJBlB/uKqX1WzKs1Oh7ZS0xY9J8RjlO4tZJ3EUaWfPdOJH+5A0gZu/0+v+D4EapVyPzuEcSkwKpyYNRep/xRl9LWNLC9v6LIqBwdNT1LWeD7Q6WFUqlSHPmTBhAu644w489dRT+N73voePfexj+PWvf+2OF0MIEdFOwwrtSpl9XZ6HGHrfktQyTW/4xfRdKv/bNy3HbW9fgrveuRAAIpVTs5miUsnQ091AUsqhEmKQoglr3zMX6bAGmoMp1r/vAgsipBEGm06fAWXVVGKITdqqv4SJEq85Ray2C1RKeRePtM5+KpORE0j7FUzF0tvbSkjKBio1GBwowxiNNM3duMuAKjYqN0ZbcMSS5Rb8EZBWcqSlHEnK99lOlIoZK6WAjR+ehY0fnuULBUBK1IybPnq+RyxuwiAUf7NugrH9oYbyUJKyGrhvhld7AcCRF9UwfmmthVkK1YIhAyQ2TKv6qp4ZtEDp9surbI9RaIMpAdqGlfnjlTy5OjVMIKsurjpgc/cKPi6f0q4WtaOVKed6NqTIoN293NchANGp9wIWoshyRddtJ236euKCWrQV1YYR0xZce9Kcmt9mP78Zq7tq3LfaatGLE/quSGgrtcPnUnxvwz4mvymyqj4rt19RxXGfadPPBcbHASm5npVXfKLP2Ur94apeD8D8UOWbVQRSskAJAFFRXvWRlSCtcOJH+3gBUFZ41Sl9OPFUz4bJfSrDLJQAMrFV9IbuhU/HkmHod/tZlpxotzcAGDlyZLTtCEyVy2UceeSReMUrXoFly5bh2GOPxaWXXopDDjkEAFoYpkcffdSxVYcccggajQaefPLJIcs8X6UDpnZTfvaGGn7y+ktw0xsv3uVzXvvzGTj+v2bj2B9dgDv+YRGO/dEFmPD9hcwyEVBvMmEoNkHGKIz95lKQ0ShZuyml2HD7/lNmQinCmK9dxIbm9QQPfJyBldK2jlxZdZ3mwSohmG62Tdr0qen+LbBACgowZR4xKCHHWFHCoRHyRoJSdwalDeqN1IEXkdC7T4zR3XhsgRaBPRf9fQJ5UzswpKzaELCMVGEpOu76Ja0dWxjUxnz9wnhH+FW11in3aBK0ri7bTNxk1YPy//pZBbuiADwB4H7WcPWTYvDisJ4tf+xn48lJGXuOBvIKnyfGwFJW5TxhAdauxrIRYmMj1wEYFIXASO7r7hVVB7pWXVwFyKvvFBWAlm3/5PN9vU6FBAAErFkaA72QNSoCoRY1Ufh/e4wdtaPlHFvP3wqwOqa39rRZqUjVG4KiHUmBZWkHUESO+0zNA6kAkP3xyqoHXwb44xcL7SaAlMIfvtKLP3yl17E7rzijb2i1MADS7RFLFP6j2H5iOyid2zFMfpMAfveN3rieHPjd13sjbz2d+fdLkTVeb3NttwB7jkDVcylEhHq9jiOOOAKHHHIIfvazn7ljjUYDv/71r/HqV78aAHD88cejVCpFZR566CHcfffdrszzVTpgag/I23/zuadVPlUGXWmGO/9xEQBgoF5Gmhisf+8FSDQhqydY/94LoBMDMgomY1WYyRUaW8s44rplIKORZwmOuG4Zs0+JgSoboDvH4VctB2XaxWdSMulbhkpJCIGUMObKixF6XYEUdCOkAcAefmUD6jLMaAE21pVGY6Dk7ysx0No4A/HcsJdfaCcGeOasmSXOvkmYJxczyn4qZYFPOIvbz7HfWsrfFXD/KTPdQCp2U5tOPR8x/24/Q0N1RXHoAOUPR3YfirDxc73xgKngDNUVMTsVMkyhjVJkm1T0/iueU/CMcyxVAM6Karc7vlBlLynYgT30ogOidkw+r4YpM3gSvHu5Z8amnGv3CYtl76todN8iCli9zNcjbZ00u+YBlQU27eyzitIWyLb73uaconF7+P/zFVCtWlndZRupSOzPzv0Cgnd7h5O+fX53fr7a1gtTPPtuv6LKKj6py9b98k9b+z9b/vh/qUXHmYEiHP/JGl7xiT784aoAoLR5jrFaWoG0arGrCr1bRXQGx1yJJ5/UTQp45WmenZJ+OfHUvihUjGOqbT2v/FhfrIYMfhMOVO1F2VMG6Lsqs2bNwn//939j06ZNWLVqFWbPno2bbroJH/nIR6CUwjnnnIOlS5fihhtuwN13343TTjsNPT09+PCHPwwAGDVqFM444wxMmzYNv/jFL3D77bfjlFNOwdSpU/GmN73p2eiivSadOFM7kR3FmRJ566/PQVnn+OHrLnva9R/zw7loZgm0Jqci277FG3jHMZQUNp16HsZ+cyl0amAyDiMg4EUpgrFBO1XGKjtl7MAjxuK5igedjINWUslS6E2hGeAHC03MWpUNMJCASoTyqDqyRoKyDd7JgUY5VIKo0fJcI0kMGs0kCpMgIotIk2vnzedBFDNrMnJpTTDGjoKKXKyoiBWTwU8F/Sb2YZGdGKxRLqtKla3LNShXHmAGx5XUE1xP5WCVqGLVHwBW9wE+ThTBTWyhZ5XErFLEoGbKuTVvZAt/rrNhsdudn+fYVMVVfBHAtQNdpFg1N/m8WvQerL4wnqwnn1fzKhfpl3DVr/icyTNrTkUSgaTCxLZmcZW971TcRmdPtitChU97nWgCK9QV1W2/r1nyDIDJ81CO6a1F5lAha0g6+L8AhkRUHj+f6D2UMuEzkaEjDBJr32FlqOW5iTiPvk/0RftecUZfBFDC5xyp/OR3L07F4U/Uvv8mVf7dA/D7r/XihNNjD8Jbr+5l9V/QaZGdGfz3FgaNfF/kjUH88Vt7J87U/WsPxYjdiDO1davBERMf2uW2nnHGGfjFL36Bhx56CKNGjcIxxxyD8847D29+85sBwAXt/OIXvxgF7ZwyZYqrY3BwEOeeey6++c1vRkE7n++ZRjpgaieyK2DqXb89Cz947RfaHtuZSABPDjPARtqJZsPsSinD9v4KjAUaZpDVf7ors2BCQSUy0gD3f2QmB+rMlTdAt+EEHEtlmSVkCjpT7LlHNqaUeMFJdHBbr24o5MMMVIONrjd+dhoOv2o5g4yKQbmnYYN1KpRLGZQilJMcTWsZ3cwSNLOEPfmsXZQYqdebKbNvuWfSoMCsHCloq/okUtjwwdmu3478zmJvRxWCJvh2x/sFVNnjFERCL064btbg4y6oZwi63Mip/IBvR1gHqpYE4Kg4IVggpjMLpCxT1BIpHd5zywEoHdchIRGOqdbcYL9qpa9T2hxOAKsvbAVUUm71hVVMPr/mwFLE2hm0BOpcvcyWA2I2Dx4MynUjsBfsKxqtRyAyejaIQV1QPpIiEIU/Z82SKrNmf8OgKgyd0EJGybtVBOpDgKoQKBT3Sz2hHZWIxD/TeRDtHBYo2fAIQzJkQd1+IVP89Kxy+Lu6+TvT8OoPsIcfs7p8EVL23S38Hm69moFV+J7onI//7hu9eNUpfbjl2l4bUoE4DlURv9h3UmdA3hzEbdf/bYKpjgwtHTXfHpBUG7zrt2c9rXPefFMV/+8X57I9kbUrSq1H3IANzjnYKHEIBAEFsAOgZXkos3GWbIylcd9eyqxMZIAOBlZuoLQDQRhpm8DACvCTkJYVJQMtPah5cCoTxly+Eg+cMQNocKHmYApDCpVy04GlpklYFUisEkyc+o8vkxu+Z9jjG/55FnRiOHgnmK1KEo6wroP7O/I7i7mZpLDxQ7Ow8UOzrF2YdjZmYidGNoipAMZI4xf832qzM8RMLWAzOGdjtTdwrybcN6OKoy6s4agLCyyMrGhD9sie50AP4OrS1gaDwC7yck1XTgF3XsrhEY49pxaFRli1klkusY0qXhMAg5+wbfDG5HLMAangmEkL/UWsPmthxYL74b4L3jcT72s3UbdVKRZZMtltz79nYTyhr1lcjVgVOWfSrBr+lmXqtJojYne0Um5RpxZPKLxvxecO+L4/7szWoJ7+t+Ir2imQKv5O2zxnZ+ukbHDNRDkvVUXAqz+40huPU9zu31/Ti99/rdcBMFW4j/C6isAACmzILsHyVOHcpEE+g8JenlH3tpqvI0NLB0ztAfneq6/YpQjooWhF+M0bVwBg5mb1u+a7qOEjRg2g2UzQHEyRpjm0TduiEgIqOTadeh5PShrRaCPefcoeUykBifHefCSqPwTLVR8vSVgrZ38ixE9KNmAlsboqIYz50gogJWB7iqScI880Bupl1Bspsjyx4w65tDKshuT6chv9nQicjiYxGPdtNrBXmpCkBhs/NIsZKgtgBECaXDtbqXHf5k9dMtBpDp3afrKbc7cpUPKiInRin10LGIhG8qAsgfP52To2VnvjfpOJJ1B7RWAjGNzFdiqaqBSQl+Kyx55jwVkCVmcoZqJ8W9n7a1Vf1YU1cCAtAHKi4lm9rBrbhsCCjBZgOfT31cuqbt+aJVWsWVqNDMKhLMAp9n/IrBUmOyk3pO1JCKgQT4JHz63F9xPEn4pshf7GQVXxtQcYnLuuUr4Mgn0tjJ8FPHd+vhpXFlwnLBumnAmZSVdEKeckIfX94Su9O0R9f7iqt+XakV0TAJUTqyRT9ni9+fppbXNlKoLz4pNFizIcIuH313iApfPgHEOQFeAt101jNswwgNIZkNZtgE9JGWUAmL0HUPaUN19Hdl86YGoPyQ2vuXznhQIxpPDKH8/CHf+wKAojUEpzVvGVM1Cm0b+5G/kAJ0VGxoE5x1y9nN3+E8MRw+1A6NRelh3a9LHzIEtUEgCQK6CpkWzT/H9TsXF5wjn4ilQBKbDaMCUgsYCrK4dqaKCSg8oG2VMVNLeVmWUi9j5sZgmM0S69TCnN2eYJDKYIHCJBgduepDl0YmByZtqO+u7iqL+U5px9wrqZTIMMq/u0JgukEAApWI9G4v6Q2aU4Yeh41nGTuvWALLJXEdNECmMv6cPYS3hw3zBdVsxBXQWg4ECWePW1AVl3L6+6dq5a6QGKSyuTWtWfACo76R1TrWFqb83FhlJ5DKjWLK1GhrohwBCbqRAQujZreNsoe46oymRSO/qCICJ5UMfEedy+exZWfb69wuTZTkXXwpq0kchxIKxXAF4x5lQboPC3JuK9WRS3MHJ/WGKwAx8uJegfx3oWAG/ouSr1h+xUq34R0bHQk69YXtol0celfSHw9gsSxcFsGxwN/dUfWBldRxnyoMjWJYCJARCxYblhbz5SwC3X9kLlFL2HrzqFy+gGQTfJ2W2VtxmU+g3SfgOdkY+o3pEXlHTA1HMkP3tDDb9/21K87D85ZtTRNyxwIEQrwtanugGAwxok1qDaxnciAg7/6nKOep77JMc6EWBFUKUcY752EV9MM1uFrtwZk+ejciAhmDLHnJL4UtAEbUMoODsZYhCl+znxsX6yBBqRIXmiBDWoOeSCAhr9ZQfochsJXbz7jLV/yvLEgcfwk0ghSQyS1FMSDmQSoCXmVsLMldJkARUb4ZPxlrIbPzwrjoTOtQEgbPrYedawvfBApC1Fo9yoDH9s/Fxvy8Qt7NS4lX1RXaSB9XOqLd5Hrj47gYV2SJPP87ZPU86tee8+ez1hqtzcY+Pi3FWrAjoItxDUSQrOTmjNkqpjZWRyKrI0wjKtXhaALKlTW8842Wf7855F1Qg8rl1QdaqPifNtvKg2C+F2dlThZ1G1FE6uIUAuMi2T5tQYUJEFVsVrEN/H3wpDJUBKuiH0AIxwZOHdlncgVFO5dycEncH7d8dl/p2+4wvcty87y9sIRoE8CTFLq1T8LIrAdgiw9/uv9bp9v/u6/64MOWbopA+tjN7LKGq6pcZP/CgDNJX7+06afKFXfWQlkgbhpA+vjPL/pQNkQZlvVzLI19UNA23PZ8Zq77E9Zg9sHdkz0jFA34nsigH67sjU/5iH3Nr6AAwgsoxHssa2MtS2FFQ2UD1sdK4SAvWnbA9VZlBBuXIBO0GAaSSs4lMEamrocs6pZmRCBkCZgso0kAXLQNsGnSmX7FhZVioZUMh6LMU9oNEcnUE1lfNkoxIBlRxdI+vIMo00NWjUU3T3NJwKVJI4E6nIjliMxMVjTxIawx4TL0cKjuWZRl5PHBMltmNklAOXAAfuHPONCx1DZ0dVTuBsvOrRGei3s7Fyn94wXwXXAAEbz+nF2Eus91EOrgO+a+89nyeX8YtrsRFtwbtvzRI2/pZ6ZfUs/69aWY1TuwQg4q5AxUfaG7ZHOf/aTI6hIXYELIogRvvJx3ZH+3ICqArXiUQm5naGvMHx8N6juorgqVDvPQvZe1CFz7EoCq3PGFyvgMjnizhPUCC6l1V9VUzt5cj6IeOnwnJt3ovQON09c1terlN8F4qhAWJzguB89/4HDQ2OtdjRUVzv77/GXncCqE768EroJqv4JE8fAKfqu/k7vO9/vzUNrzqlj9PCFN4nbiuBEoWkTk6dfvN3puE177sYlPjf/v98dxr+37tWuBANAp7EYzBrDuJ3P7xgrxigr77noN02QJ989KMdA/Q9IB0wtRN5tsGUyOQfzA+MszXKaY4tjw+D3p6ARjWx6dTzMenG+ejf2gVqak44LHZU5AEJGc0qqkRGLERG6SDr6ScgrKGd+s9UjAMUlHB4BZVZFR/gvdk056ZL+jXybh55lVGg4Rl0JYfShFIph9aGbaPsPYbzqbaxp4zRrP4LBnJjmMUKT8ib3qK0VMrRbKQOALnwCPI9BDqqOJorP8AH5YiABz4+A2O+vMJ68AGbPjMdY64IgrEqBpcg4P6zp2Hs51d6kOYq4kGcJwx/zIGwnJmqCQsZtKyby99VoHZwk0ewCibFqolVNt2LfIagzzELyqeYCSclSfYKYuYp9GibNKcWtbUdkzakLRW88XcU/iAsNwTgcm0OJvBQ3OQ61BK6AIKKL1sEMIYAdLDG/u0YkecDqJpybpyHEcaDKBF360E/tMHVXoJ+jEIkBO/kHZdVnQqwXWLj2y+vsiF62M9W/vjFqksjI/W1gLegLSp4N9095dZeybBqLWkSsm7lbAoBBjomUQyobI6+E0/tc+9UFJqDuLyAMG3VfDq3QIkoaoMclzbkZWb08/rAXgNTd63ZfTB1zKQOmNoT0gFTO5G9AaaO+eFcVotZhqoxmPKE2ExQGV5H/aFhUPs1PMtkFJJyzio1QhQiAIAFSgy4SEIhyKhl/EhFRkE1NXSdbafyETnQ1Nb9naAzu/JqWq+ZlAEOJQQkBN2fcKT0EgElVkGaeoKe0QORd2IzS1AuZS6eFhFc4uMs19YgXbn8e6KyE8/ATBgoq+IDAJNbNo8U21kpYaU0s24KrNI0yttFFVkI2ycU7HeAUYBQcYK2xzybJP3Kqr6xl7AKYWO1F0eu6GsJvaByYP3sKiYsqnFiZAATFtXcMcAHG5TQCabE9a++qIqp02q8r5huJgBSALNSEisKFAApAUjFX32wLwJYYVcVwQhaJ76hANfa+dVYzdcOcCEAcuF+mUwLbEL0vTCRF/dH7IoqtLv4aWXNUhvywU6eLnXOPiBTzq3h7hU2/AX5QKtFgO36AFGXtIoAmeA0J8QqZEm87BgnC4LvvLTqEiK7hYAqfLfH/vhvVbz8X2uOzdklvx1qfVaRGYIBdJPc+x/Gd9MZhzIwJXmH7W/evs8ClgTQ64w7Szd5X6nfADkh79KF94vtprKeBEndcLgE61WYNQZx641zOmDqBSYdm6l9QO5650Joq97T2qDS3USlq4myzcWHhEBPlUGZhmkkgALyRgLT5ETIEhpBAIfSBF223m2hETYBZNVbsIwUFMGUOGWMpJtRIVMkK0oZqAyg6xqlJ1JQSig/lbCqEAANpCiPbKBR55m70UhRb6RIEoNmliBNjPPka2aBQY/gPQFSVvKmBVkJp87RgRpPWy9ApY1X71kA5NSEMvgVvfcAgDhgJxUGaT+RF04IgJSUj4poYGyNPYUi774CsxMmX52wqOaAFMDH1s6vugTGlPj0MTpjW6pVK6vIy3AR08N6FQEq48lEYkiRBiiN2xoZZts2rlnMtlRQBWPyoe4jAEMhgGrrIaaCRMXBJNYCfop1FICXU1dqX084grU1WleIJs6obW3KhuJUnna/pNZ5rmXyzABIWXHJqUMGT+4nUPMOabtH3qnBvep2g7IxzEJbQwXceUkVd17K7FToSCHfb78izl8JcDT0P36xatmcXbzhEAEGz/J33+h170VetmBGsTeft8+yCw8gSkcj9lShnZgLuUCAMoSkbpxnXml7DpUTQIR0ew5FgClr6KYB2ejqeZnr+vnXzt7FG9t96dhM7TvSYaZ2IntLzQcAE76/kONLDZZQLmfIc5uuZUuJf/U9ubd7IoAyZpFUT+YrUYhsjpLUIM80G2vXPYDhQYSX7CpTDNgUOJ4UgZmpurb5+pg6z7sYQahcIRnkASQbZemUTIG6DDMxCRvAJ+UcpVKOnq4GBhsl58VHpJAmfF5ugvhQBTAFAEpzpHelgbTM9ynR3hXYMzBv+jqc6i5kn4p+4hYURUCquGQX+6hQjUf+3KFsp6DYQH3sJX2surNBPd0kZkFYaE8ida27wKr8AlWf855bXI0m83BlnjR8KAWnushY1QPw5Lt6WdUbjZP1xguYJ7mGgKii2kXskCbOaw8oIhWd9OUOlmrFlB0hOG0BRW3olBbAVfheZMtCw+GQ2VqzuOrTzLQZCR07VbhOO5Zq0uyam7h1hhZVrcrgbJUkifEzEaeSpTZJkAsUlFNj7WCUX7UyVgm2E1ctoUU9JmpAAP45FtikMGjtbV+qulhT0fMImKYigJfzf38NB9jUVpVXBPI6I2c3ZUoKuskhDPKKit9n+Hv43dd7ceJH+zh/X/CbTBoEXTfuPrIe7YBWKDoH8hKj0Lys0EAdf/z23gna+cc1B2P4bjBT27YavHzSIx1mag9IB0ztRPYGmHrtz2fgiW09WHPyfM61Z1VWlZ4mBh/tAbpy6EqOru4GBvvLMFkC1K1tVE8OXcpBuYKpJ9CVHPpRn/Fbv6SfA2dmms8DWA02qIEEDIIqhtPIJMxOkQJ79dW1DZcAZytkygQkbC9FCWC6c6i6tgborFZMhzdhcuU88EqlDLnRkWaGg3iymo+MQm5VlSbT0AnZUAjs4Zc1E/ZUBHv1Sf9IfkAyVtVJ4UwClzLGdwZFas5IzRfut8fcQB8CJhMAKCqAKcfg2RHbGqOHZe6bUcVRy3jiundmFeMXt4IXmYTXLggAj4nLyGRatDNafZE1YA/AjEQod3GmLKa+Z5E30m5R44WjQpGBKjIF0hdhtxbrQ9xOFB5VyFKsnedtyqJrBO0a0vg8+N7WeLoA2IZS9UlOwdAgv52Bd9g+l2tReXDj7efsPsuIPKNce1Ymzq85RweVBfXb9klCZBcmIXhe4sAgAHPVyurQ5abxe7Sqj7+LGtA9jsKiQFRsIZj645WB3ZQUM+DYUEVbtSJothe69atx6peiMbzEaRNgSdraOSXshWdKAJTCLdcyaGr7zmrfJv7NEpImIS9xLkBJlAyynn+GmJmqG1BJIS9r5BUFkwBZNojbv9kBUy806aj59gHJcs5dd9R3F+P+j8zExg/PQqkrw8CTXUA32zGFA05SyXhSLFs1lwJ0SlApRbnqKAHyP/eAHuzhgS7x5ZnWAQOonNkpZcET2yAoB6Sg4OylkkG7Ausx0HXlQIce1GzQXjLI6wkPOmmONM2RWG87CZMg3n0CoAD25BMbKbGXSiyASks8MznPO6OQZ4mLNeVTxhSAlK3LjZiBEf6m084LRtJgolRoQ40EUlgNh/WLei9iwzRsMmQuc+TygrpE1C/BSp/seWEcpzA5cqjuCm2nXM69sJ3EgIAUs1HFVDDuerYfIjwaAKIIIFF8zL0joddgSNjtqDtNXMYBqXbALni8VHwOrsLgtEANCrQHUtTuOmA2b/L53rBbtemTIqBbs6TqAHTS8IBM4oaFfX/MTpignYlTqSWFfgeDqCjeVNDOKefGKYdCz9BVF1cZiAV9IuzmqpXVIt6MfTsAz6QGz+nln/L1//HfqpwAmeCTGxcAsJM2QOrWq3vdNX//td7YecHIQsSHLyANmLIClEIyaJyXn5T/3Td6ccu1vZEDRHjvJlFONZhXFPIKj31ZRSHv0mwnlSo0e7SPuZUAprSDF34Pi6Hd3zqyZ6QDpvYBMaSw7j1zYYzCuG8vxZhrLkLjsW4kW1hnkD6VwGwuY+DBEcAjXRyPaaSPDMe56wBdZk86l6yY/OCmHuqCfqjCrJUi/+Tt5Gh6cpie3A7Q5CZVv6pWftBsKI5R1WU4UXKTvf/0gOYUMwAzRqSQZQmyXNugnRwNPU0Y0CWJ4e8StVwRSpXMxZFKgmM6KEPW3klsxiQJtBeK7WqsbDp9hvscc/Vy13dyz/ww2gyEtp5Nn5rewmCQ4lyFANj4PARX5/Tu0I7nqAt5Yls/u4r1s6vOIN29F2VWrZECYOBtqbSdqO2lVl9YdYzU6ouqrgzgP6HQotaTiOHFSVHaJ9eOgFRQZu38eOJ1dRCDIukfN+m1qSNku9oCqUL5IiMWAsGoXKFdYYDJexZVo3PbMWnOi4/agC4BMoVXbvJ5NRfvyKRghlB5Wyv5LVGwNnomIv1OArDDZ93m3lWhb+5ewWmGxCtUzplyLrdTgr4KOzW1l8HZqgKbRoVnE70rbeTln665fH3SLmU8SJLQCmF+yhBIvfI0z0698rS+1utrG6UcDKqSBg+MyaCBKSnPODW490/8aB8zVbbvdDNYB5m431hlzwAr69YcFkGD7aWUtdnSfFxUvXtDcqjd3jqyZ6QDpvYB+f3blmLC9xcCpJDXE44JBSAfmSF9pMxeJZsT6AbbLjUe7wb+0gWVUmQfBQL0IxVWuRkeHNiuwtpFgQeL9NEy0i3aP/2C/Y+2qVIU8QRuenKYkoFuAJQya6XqGiYBkrryA/vIDCixqk+XcjS2lmGMQqPO9lIChAyxWk9AYJoYVEoZKuXMGZObXLt4WybXgEIUKd6NAUZG8DbL2qC8C3QKMJCyx4TteuCMGXZS8WDIDda6zdQXjEFHXLaSA3kWxqWxl/Zx7j7HHsT1SP3jl9acum/dBVWsm1tlMEKs0iHtvfEkPcukOTVQypPppNk1P3HPrLVMMlCWlRoCFBWTE8uns48S4CRi35uJC2rR/1Jm7QIGRWvnVVuBCND6qMjbi7UAKSlfBHzFKi1YWjuv2hb4RMxZoZ6hbIokKryUEbCw03AJYX328+7l1eh4O4bwaYmCj2ZvWcqIrVNe3Rfuc84Jdr8AqGK8L2G3Vq2sOhAVqgMJ/np3Xlr1C69gv4A912QLNAEGSSr3gTgjW0Ll65J9J5ze1/ozB2JVIcGBI4DZQWfobt8B3YSLXq4oDn+QlwEohbwMG+pA2WtQ9P5RAmRdCs1hCo0R2hq/M4CmBPht35k7fHQd+duUjs3UTmRvGaCPu34Jg4hGgqQrQ765DHTxyFMZXkfzz8OQbuURr3FQhmRLgnyY4Ym+m1OxECmoxyoIDVNbmBZNLtBmXuEBxZSIWSlilknso2RAy4flSLam2HhOL8Zd3OdYquzgBvSTJZhuAz2okY9gMKRSw4FDNTNEupQjSQ3SlNV1HAldI9HeUIbVgIQ818gy7RIWCxslIREUgEY95UTGoXF4OPFGojgdjgzO0UTrZ3qJWfXAGTNw+FXLfRmxnQoDeVKwPxj0N37Wxp4KxbZR7KAU+X3S5vtm8GQ1fnEN6+e0TtTOEy5gSRTFgSnXLOao5op4spc8e9IFEcAKmYpCU4tdF322EVIcK0vaGIZAaAdcQnEAaifXiAyU27WvOMG2A0cOfPsy9yz0NmlF26qhbKxcdQVboWI7IpVr0KawPgln8ExFwKzK+V7CUBhFFWQIqEJgF55z94qArUJr/CoxNBeDdQd4is4UKt4fxaCy5STiuKRwCW2Z2r2r7vnY42E4g9juif/XTYLKORq5ImsgDgBKQWccj8qrp5Xz7iPFC5fyVq40HTRodmv3/lEq7BSfk9QZdPE4ym1omkGsuWLWXrGZunn1obttM/XqyQ91bKb2gHSYqedYXvtzVj0lKadS0aUc+RMVoGx4oNicovnnYVAH1aEMOEgmAkYoJcCGC6AgpAGv4pSPsSQMCyk/ODkjVo6GruraMViKwCBEAbqfWbGxNQZSVOI8fnpzCjMshx7UHPDTiovGnhCoqWAGU45YnlvVn/3kgJ38Coo6UNLO8E2wKlApZqeMjUfl0uYA7t4caxUOxK5BFNhbAfEMETBUyrNXgLBVu7bWIMUMVSgbPzsNYjsV2jv5dhIoIRy5og9HXhQDqYkLOGzChIW1SH1TTE4sE4oDBdp+V4BuBIwU/HlRTrVg832CHQOpgKVRFIc9mLiAGSmnAmwHgkJp97yGAkIKcfkhGCUgYG2k35RXPQL+fuXznkVtmLti3xTb0a7Ndn8IpJznn31+kc3cbsjaecxgkuZwFpS2rztkiUhxvsbJ59V8GwNwLcFgXST9oJ+EZXJpa8K+KqiV77is6rMBONaJoIg35wyhOOfd777R2wJgARv3iVjNF7bHJIW22feMA3gSTArkXayOyyoaab9djBk2Kuf0MHApZXSTACJvXmlVdYP7JQyS7PuUlxWyLlbl5RWgMUohrwBZF5+Tl7BX1XzGMv27s3Vkz0gHTD3HUtLM1pBRuPf9c7Dxw7NAFQMMcjwpGpHBjMih/tQNSoB0G3viNV6UIdmqofsTbPrYeczsPGl1QTLIJDyoUErODkpy8PHqzRZM2M5KGQZWus5b2m9ZKgB5t8HGai/yHuMGVT2ogbLh1DZNm9KGFMyTZQZd9YTz4OmAJrfNMzl744mRuagrlWJbqbSUIykZtz8EUyaLjU5Efcg33aaTbRsEMJFRbD8VIgIwoFIKNmEyA6sHzpiBTZ8814Ei6dtNZ06zhuVBO9pcW+ypWgECeSNiAboAxi8JABT8IC4xqMTwnBJWw61dUHWTpKjzRKJYRPY6Yi8UtyX4LIIqxIBr7TwGSc6ehFrPmzif72Eo1ZyoeoSVaseItQV5IuE12wAtN1EXRreJC2pxO60aM4y7Fdn9CEhoAy7DMqsv5D5ZfVG17T1LrsUQxO6W0VRB1s6vxuAxEAFvqy+qOtu6u5fzp2yhKs6lHwrqKQLPYttdeS2gCTjuM7W4jAJIqWAL4z8BJ57K6jllwxM4I/KEWR9nIxVc04lipur3X+sFlIIRD7wmufN//f+b4eJQ6ZzZJJ2FrBKfYxJm9fOyVfcRq/RIMxuVdStQ6nMPmsARxJSYuergkxemdMDUcyy/+v9sHilFGPNvF+OI65Yh2ZZg06emQ21OUR7eABmO59QcwYxM+Uk29KYyr64O/8oKBh1GgbQFTon9YafkbXas55cb1IPBXWWKbaaCN4I0kPYrtpEyCkctqyEZ0Ei3K1snD3ym2zBT9UQJGNAccgFgQJUrlIc1mJFqJGg2UgZE1g6K7aaUU/nJOJRYzz+AyyRpzuESLJMV5jIMPRhbGZWYhVJ2IhO7KVbvtR/9hM0a8+UV2PQvAaDSwJgrOc0MJdTiNQZSHkQBHB39nN6oHb6T/blHLq+5CTGMtSNgacIiPr52Hq/61y6oOiPyexZx0M2jL+DkvqTZwDzvQjQ5OhZJ+qgIShD/H6pcJPWNe2esSicCWhbEtAOWYmBP2n5XvjuKwElM19oSgzuarApgRuoUhqQd4Dh6bs2lwQmPr1lcje4fCMBqsF/iUEVBPYcCS8/SRMvGz/53bRLrsEBBuIw2ImE0SBXaP1Q7CwDTdTehfQTI8F3S8m54FZ+MRy5FS9ODYffM7ObeCTlP2F5l46xJXyhWvykbzkA3jbseWQ89dhJgQFXabvC7r/cyILJgKLFAjBTbXjW7lQ2TwIyUpNFx42nCrB4lgPGRaZ516Rig7zvSAVP7gEjy39IBgwwgjMLYz6+EyhSyZoL0yRTJVu0CZUIxyEn6fUyopJQz+yITULRyI0/DKwuwUrLAyxaxKUxg/OBgSoS8zIApGVDOoyXvIiT9CklDIX20DD2goRsMsspPJcxY5QqwKsT65gqoycxSV3cDShO6expQipAHQTq1Y4j4U1grADZQpwdfIBRyDhY220/uoJsoidky6QzAB+9sM3sfftVykCYc/hULqCSavEwqYJaqKGMv7cPYS/ow9tIgro1tU1HtFkoIdLXtbznPpZ9ZyMEhBRip3AKCucwqTJrlkxtHHl7tPOqC64bqHmfIbcHnurkeRAyl+XQG6UALCJG2F1PouG4hD6rWXeC9CIdipyLPxyIQLAgFz8qVaQHdLPcsrDpwcfQFNQapi6st5UR9Ghqpi7RNO1N8B/bwyCv9t2ZpNQLkUAyYiu2cNLvWEuE9fDeLz6/IUjogjNYyIi0MnxuDbMgBFQAfQ9A5wZQVv/fyPoRqSwHdCd+bSRjgiAH4qz+40hmXS1woUwL++8Zz8eoPrgTIAyxlyOXhE0PzpEFImlx/XmIglXWxWi/vArJun5FA2qUzjhlGlmXLumNg92xLDr3bW0f2jHQM0HciezMC+uFfXc6qssEEVDKcEubRCvIDm0geKyEfbkCpYTAwqJFuTZB3e/uhKD2DBRzCnLg4LBmDIthkxuwRRkgGVaQuCu2pyKrJTOrjTKmcy+VdBN1QaB5qjdFHN4CBFGpYE3iq7PL4lfavwxiFrq4mjFFoNhMOgWCbu/Y9czHx+wsDNoqPiNfffR+Yg3HfXuriSpHx+fjCwdZJy75gpM8LIAqIDdMLx7xRMhdyBunOwFZF124J5GkBSRhmgizwLbIxMMr3PQWAyB5fP4vz+kUGv4VfsPNMCrsjt5NQ8dduAZRoO0l54FQEPMXzhKmK2o+AeWpTR3idonG3ImuUvqjWUi4sv6sSGrjHccSCT/g+vGcRR3hXJg5oGsqaxdUoArm0e/Wyaiuz0+59DN7LdkDsmcrEBTWXSmjNUmuMHhiDF9VipBkQRtHdbb8IKxpGLXeqQHmPw/c62H/nJVUcd2bN/d82MrrUK0EyjWWCtF0tKf9pksLvwJ7vPFCD+0rqQDrAlecVq75LlIts7hYmAErbcjRHeP2m1J+X+fenM0LWpfCHq3px3Jk1ZvrEFkqerVXvgZiNMiXebvvMGc/6nCHz0i9WvRTDdsMAfftWgzdO/VPHAH0PSAeW7gNyzA8tkNAEyhRQNtD9Cag/RT7MQD9ZgsoUSk8mqDxScsmLZcKVoJsAOAaUBVLQBCWJdpVnPUIPP2+bgGig86pBApU4sGdpm3ITW95N0A2gtMUOPk+UAAUkj5ehhjehHmevQpUpoMug+dcuJKnB9s3dqA+U2DbJtkFrg6NvWACADSqJOHSCIQZMWhOO/M5iHl81oFODpBQgx5CNCvf5u4x3WvXeAx+f4XZxvCny34v1hDN+dJ02VIhDCe3awuB1w3Sv9tsw3QcjdOqTBM7wVQb69bOqGL+kFq34xYYK2npwanHxjjen4i2wPeFkJBNUS87A4i3atoraUcCXtHNHQArg4+vn+LhawkKsu4Ajwu8xILWohnVzq60MR3APThSze/JbaQekABuSogiMYFV9KmClBLCFW9APpO05e0jEuF4ZtKj0ig4MRWZ09YVV314gvj95x4hVcEnDhhfI+Hv0ahBw7Gd9/zi1o9QTvHMSmkBiTBmb307y3IVATOXk40DJ+6psTKeEbbBK/ZaNUgqmzMyX2EP97zenuTolFUxjVOICbErg21I/uXvOyzxAvezsGufcS30AUzGZyCv8mQ3j39y6C6q49/w9B5A78vySDpjaS/Ku35415LFSmqNSbqI0rAlVMtBbUuhBBd2fAN0ZSJNzBc56COXHU6RbEugMKG3WUBlQ2qoYSGm4FaowMCCwB15C8RPXwUQVrtytMTTZlRerBPnaMjCXtiokdf6eDLJ3IdmwC+oxNhqgEiEZ0NBPpdCjGmhsLwGDrO4jAowFdbwQ9fn2CHDpY4xNG6OU30dGYcM/z/LtbdEFhbNCm/1WDv/q8sIEy8FAHTgLGaZQD+X+575qYZdcff6ri45umzTuYjao3TCdw02E1won/rDuoy6suTooeHakeTJt8dyzEqrE1s3lOFbFyX1HphNyT64eW34o0FQEY7sipDg0RAg8QsC1o/PafZfrhyyX8+ZrB25Um9doCFEUG/qHgEHifcUnAKFBvHtHaM8mT3ZOAfaabQ3JC/e++sKqA4KRSs6WVzkznTor1A+uXzeYEUoarcciMC/HLEMk7KtLExOcm5e8mu33X+vFLddNQzrIarm0zqzRrV/txW1fZqB825ertn+VtZ9ill2YqFd9hO1SGTR50CYBNk3K4Ks+kqOaZ91sxC75/GyzMXV6DaZsGShrXyWA6rmaSTs2U/uOdMDUXpIfvPYLQx4bbJTQzBJWceUa+bAc+YuaMPs1QU2N5OABR7ubEgMasp/NEV6NV3mCGSrd9F54Iqrh9/lo3/Yg8SrMqULkXDsgclwqct5/982oOvsB3YC3uyKANKHrcYXyZgXdUMi7DVRmPfD6U6DLgJoaedPmCQSr8sQ+igCnxit67LmQCQDGfnOpm6S4gP1wYRXs+e4ew03iVwX7AMd8QQVhESIaR+GBT5zrJyUXdoLc/bObEl87BFBjL/HBBGVfFLhRE+47t9dek9sUBjAMU2SEk5QpBn9UFjAFICQENhMW+QChQ0XMDm2WQpF6ZH8EmHYyJodsh7TBtUMxcAoJRAFXExZxyIjQyF/sqtZdUI1UhSHWLdpUkfI2Xe2YJSg26A9FvPxCb78WCfovAqVtcHyxrSFw2V0R1WMEmNSO7bdCBivyNDStZaFYhRftF8bbftdNOHMCFwaE/L5QjI0cDsCpWd3iTcYdYiB00odXwqTMNN1yLYOrE0/t42TJAI7/lxoHzywBzWF2jFNwdlOkfSoYXhzypzLkzBVcdgELQvOKbwcpBlB5hTdTZlXq2gX8Dq6fxdtzITnp3d46smek05N7WSZ8fyEm/2A+XvvzGXjDL6YDAFa/az6azRR5liDpzvDAJ86F3pxCV3KowQTNbWVkww2a++XAyCbum1FFuk1h/ewqdENh1L0K5afgVT2hFEYx0tZOqkTeIDkwOhdPLLaxic9VOWDKhHEXc9b2MLFraRuQ9GtsmN6L5nCmvdOtGkm/fcW2pqx23JxCNbVPVBzM2G298gDLZHE+vqg9hXAFCEGYUUEuPsSfdtYl48FTpO4DG54XDXsUsWffkCIAzm5ja31tV+cyYG+s9mJcnwdZR67g7/ed1z5yuLP5CCdNHQMPYGhbp6LxcNQngQjICc9pUQ8G352XXhtAJfvWz+F7Wj+7Gu0DuIvHL4mBmSLPTI1fHACFoI0TFtUiVWH4GUroRSginodyPYAN+h2gUjZ2k2KgUgRUEssrbDMU204NFevJFaXW/txdce1TATAKnRHC5x6AJcn/aEpwoQ3Cdq66uBq9Inde4oGtvHv+Jv29KWGz7LVuv7zq3l8ZNwQ45WXP9ITyu6/zYoS0cqq+V5zBv5G8xHWng7z4uO1LPsSDGKhL/0oEc9IKJlVodnOjb7luWgSWTOLtnu64rIq8FACqgIVaO98nK+9IR0Q6YGovS6WUIU1ybB2s4NGtw93+e98/Bxv+eRaUNjji2mXQdYXSvd0AAJWwuizdnCCtZBjX1wdKeNLMuw3yLv6hwwDJQECjB4OmsBu8arQxp9KAUSmsEkGAbig34eiG8rmrbDBPUvZ6BlAZ0/3iIVTa7iOsc8VAsjXhdjQUsDVFNlBCY3uJsY81KAf89QGAjIZOOEyCKkRMFyP0yEYp1zY6OnzYg6C+olEwUWEf4BNBA262EOPZ0JDWRUV3gKlYUbxfmCrHWIXlAjnyopqzV4PyakQ3sAcgFgZt04mIesv1V7Dal/9lwnVldja5h6xHIDtT6YXtH7/E2yWNX1xzNlbrZ1swYPu2LfuFGICFNlaRKtPaS7n2FdPUWIkCi9r7mzjfh34Izwkjpe+ojybNjtmvUNUmaWgiZuwZgKmhVIOh6nFndWfdrOLLu4C8CxHYD8+bMqPmZoljqjUcU625d7DlPgrvU/hbefmn4zaTgkskHPY1aU6CLIxrXlGuzqRBEWi+9au99rsdx0wAohI4+yvSCkmDkHV5oJWXlMsTyOo8ZRMX+7yKzoPPBuQMGd97Z8bg+rkSAwUDvRvbHkLzHXl+ganf/OY3eOc734nDDjsMSinceOONOyx/0003QSnVsq1du3bvNLiNKEUYbJRQb5TQaKQ46ruL3bFx1y9hkLC5jOzgJpojCZUnNKipQSmh+aImp2XZrtAcaTjtwZMazWFwq0vdZBsm3bDAKOcYUcUJQIBUmNQ4KmP3hd5ieYX3Jw0443eRrIfbkNR5y7o4x59ugtWE1ktN1+3gWCLHHtW3VDDYX8ZgP7ugiaqOLDNkco08k6TG8OyT8u2EAYOo0ObJtm/Taee10irtRCbykMESo3Rl/wjjVWDRSGynFLwbuCa/H6zqI+1VfmNrnpW679wAYGmCSX38qnYgRq5FCRumi3eRgA133DKO62dXPRAL2i1lXWwoAdXk63IquDasTyg7MxKXhM7RfcGr/RygsnWFDJk8ilDVKOl3wv1SX9ww/lh3QdXd58QFtSiUQwvLBN+HaxZX45hTBeDRwkQVwJPIpFke4K5ZWm297h6Q0Pszem+UVU8tqSLnNZoDogI+7llUjUJkRGAc8EQt2SKielb+ui2qTsB6Dwf/h2o/xWDHnUuefTrh9L4oeKfICR/vA8jbW/3hK71RvYnNSSr9wSwYj0W5Db2gM0543Biu3NiZV5gly7p5PDMVIO/mPiuqgPcV6dhM7TvyvAJT27dvx7HHHosvfGFo+6N2sm7dOjz00ENuO+qoo56lFu5cRvf0I9EGzUYKMhp50z+CDR+czUzLiCY2nXoeVA409jNItnE6FwCoP9aDbBih8rgGxm1H2s+DVXkrb6HbsMqVG8icPQ8xuFIZux1HE4GAqmBQlOuaMiGp8/8m5Qm2tIVXbZUnLbjKgHSQB6TylmCwTYnjVNmEy6UtGulTCfTmFKgnwEACM5iAjEJzMEWzniJrJh7UEEdM50/tYksV7arcPYQrXcOG5r6uePCIQiK4mQUerAGAsitiUSuG10rIxp6ywFSHW9C/RQ8/MEMlE5EYpAv4ERUsn09DYkHSzGStn12NJhCXmqbNeQJq1s+uelUvAqBlzxm/tD0oke+ihhMbq7Abi+2csKiG8UtqTp0nIN2p/ZQHT+vn+H2k/P9hH4SEpMjOjNUlpMROVWyK7afC+o+e28puhW2R80JwJSxVeEy2SbN9fcJ67arsKAinACJK+Pco15ZnK0BTgPP6OdXWfJCKWat24NjI2AJ4T9Ii0Jb30O4Pn1UUviW4HskPMehTAYUSSNOkygfyBHsC/u7rvXjtey/GCR/vQ9pP7hgH5fTny/ekQWj2qAh0Cjvn4kglcMnGd/ZOHXVhjROVL6k51fPLL7x8h+d05G9Tnldg6u1vfzsWL16M97znPU/rvIMOOgiHHHKI25Jkd1O2P3ORiOdQ5GImHXHdMgDA2G8txX0fmINNp56PMV+/EJTCJRU2KYcnUMObSAaYjlaK2Ag848EiqfOgU9oOdP0VqDxhAZWBi4ukG4DzqKEgpYyVDdPYVVlsr0yF3ATBnixstDl+aQ3ZcDDgavJn2s8DeDLIA5OseLseUShtVxxOwaoDXQBSF+XYzm6KvfYksTEApJUc5e4m0kqOTR89nydEC6juP2Wmb7xiVks2r6qDPQde/QcLpIoACUFbpF3thIBN/zo9ZqmCiZQHa6+mC1kNkbGXsE3VxmpvBGrCZrjP8F7QZj+4r49axqqzo5YxwFo/q4p7Z1a9JyCxqi0ESpFqRiZGxYwXJdaeSQXHrAg4Cg3Jd0j+BWyhHHd1BxOu1CdMQ8g0RczbDkRAXvG6UD6UQzu7NCk/cZ5nbSTKfCS2P4q2VEWVrDzXNUuqrWq4wjmhREE128iOYlQp4t9hkTEL4yy5/l8cX2PNkiqgOGxDy/sXtjNkfmQBFi4A4JMRF8NvRExoICa1qWZs5HHSHJTT2VrZc3TG7NOrTunDKz/Wh+YwjXSQfBw1glPnpYPkEjRLW9MBQm5jSIndVmYBlSlb9e8O5MgVfThyeQ1HXViLgupGuTf3knQM0PcdeUH05HHHHYdDDz0Ub3zjG/GrX/3quW4ODhqxDaVSznn4jAJlGuO+vRQbPzQLR35nMY64dhkDqP2aMKObUBlgugjIFGhbyan4oBi4qJzBFKvWGKxoS3WXtsMyQswqJQPKsU2sGhJkwf+L6klWsht6e91AlFtgZSp+gIIBBg4CSluAricIjVFwaR6SQaC0lalyldk2gfel2zjPYGkLX0hUkmTDILg0MdY2Shipo767GGlXhvKwJpJyjjHfuBAyyiuZvGT1rADHxNkNAZtFASgDWgd3Zy9VVO3ZcmP+7eKgrG2GZaUAYNNnpscVB+EUQnA09pKAlSraMoUTWADWwmPKcCqaaNJTDFSOurDWElJB2KCjltW8F1Jwe1Lv+KU1ZxviyrUbMQI2IdodACTHihVZEOm7wjlFR8pQzScqSFH1hSEaBEQJAHNpa4J+lPhTEirBGaO3YWKGEomUfvQFMRiR3Idh+APAgqPZNQdWivctcvTcGgM5y07uCFDtsG1twJrrT+lju14Jjf+PnlvzDGURZMP+toM6XWDQwjsbAVULNBxgDkC5nBOyogyGlHvXJUK5lP/dN1itV9mcW7DEjBSznRwB/dav9uL31/S6WFPiMJNXlKvv2M/WYEqWkeqG887bmYhK3v1mFVpZ/r0kbDO1e1tH9oz8TYOpQw89FF/60pfwve99D9///vcxYcIEvPGNb8RvfvObIc+p1+vYsmVLtO1pyUjjwJHbcMJ/zQLVE6CfVVpHXLsM931gDlRCbHC9JQUMs0U0IkPlsQSqoVB+imNL0b3DoTMbByZnEMXRe/nz7hVVlLcAXY9z+hllxOXXG3LqegwQokmV4LzNtIRWUFbVZ1MmSDyXpGEHqi6g8hRcLKPmMF7tKQOUNyuUN/M52TA4Y/hkkEckIoBy7bz3AAY8YVwqSSeTZ5rDJaQGKjE+zUswiZEM3sHmJvdiPKkiPRAigxB0thOZIAImAgDGXOHBlgNKhbhUUd8jqKfIBDhAhvjTXjuKmO4mpNamOpZKIWKsBCw5NWM4GeuCyq9dG20XhmCpaMi9fk61hQkROykxKAcQqQ1lfzjJDcVKFY3QW44VHuGEhTUfxb3N/YjcszCoy9YRslVheybNqcXJpIeaq8gbjEv5ifNqkVct2ffp6aoBxy+uuQVN1G4BOWH9ip/BuguqkfG9Y5wUjyNShzI+eKVnYBH3G/lQA7dfUXXvIzPshT6x13MOMwHYktAGUDy2mJJCVlF45Wl9uOXaXjSCyN8qB26+fppjM088tQ8nnN7nWTKb1DgMjWDK3tZzV0BUKPfNqOK+85j1vXemB+zCxnfkhSfP23QySinccMMNOPnkk5/Wee985zuhlMJ//Md/tD0+f/58LFiwoGX/ngq3/87/Phs/fN1leMMvpuOpwW70D5TReKILpf3raGyuoDSyDpNrbPzQLIy55iI+SQNqc4r7z56GcSv7nFv9+MU1NA7MMWptAmMBSrrdB9Grj7JAp8kGloOj4RgtSSWjmlz/UF448r9fMQLpgHJeZKWt3sVZW9VCXvGT6qTZNZQ3+0B3pe3eDRkAmqM4VpYpEUxPDpUSdCmHSig2NAfiGFIAlDaOsaIicyRtb+joHBdkMwJLKmZQCuEQWhgEUQEWRZM/lqs2VBdc6pkoDlgRTMmn2LqFBrtFmy9TeHYhJUCtu+87z08azr07mOyKEZyPWsbs1FHLaq6Oe2dWHbiSqOwtEoBzpzacXW0pNn6xr7et2k0hsrNxoRLayPo51baehS4auk0v4/IMogCowG1YO4+BRbH/hrw3K/csqnrgE7y3OxNSNpXNfM8KKQNU/moLaKDZExit74JMWFRzuTQBD3gETAiznDTsCYaZmYnz+Hncs7CKSbNqPrVRGK8tuH3HCIX9YffpnH/n8o7qMNm0vSYsux2yrMoQSCkoImdLJR57JlGWVeOFU6nfAy7SvsMl/UtiPZDZ8Jx4wVdiIJWXn16f7qqMXbgM98+btVfSyXz3zonoGfHM0Vv/1hzvP3ZtJ53MHpAXHJhasmQJrr32Wtxzzz1tj9frddTrdff/li1b8JKXvGSPv2xv/83nkBmN/3tqFLI8QVZPYLaWHbuSjGy6KN9jrrkIlLHRdv6iJtKHy8iHGdx/1jS87OwaBg5i9qk5jAfHZNDaKygGLuwKDDT2t//nFtBU2DCcxHi6kH8rsrFIABhWN5Y2a+QVQmm7HegyjjOV9fj6dQPIe1i1ZxIGWpUn2YbBpArNYUBjJA/spIHGATl75FUMM3OBzRRfBNAJ2cCa/Mpybj728DO56McQgEA/uErKLygCmjpQQbSZwa06TuVSn4r2R65NO7CpameUy2pHD6qiY8WqBNTa8vfNqPpYVOf28ne5Z01xOwv3L3WFYOnIi3zKFE4cG4Otogj4CsHPkPdswVMRaAmgctHOyQNvZyvVpvnhdd13AZEUs17tDNNDtV+Y2zCsO7qP4HPtgiqrv+Seg8XFPYv42JDAqyDhaxPeT8RmBXLs53ycKMcIPQ0RgKZsBHOJoyQqdwlaKQAoVN9JyBNoX37VxVUc0+vvt7Am8Wo/8nW7vJByLXgA5q4XHgu+i4SxokjbttmpS8IrlAZ4oRTaavEYqKAzgkkUR0tH++TPe0r2Rj5Xuca375i022Dqn1+2pgOm9oC84MDU+973PjzxxBP45S9/uUvln80fxmt+dh62DlZQb6bIGimUNmhuK3MYgYSA/gSbzuS8UodftRwPnDGD1W6G05BMnM8TRM9DlpXq54FSDNEFHJkS0BhlgU7mDdazYUA6YFdx5QBQkQyknrExJULexYlJOcI6XHJkVVhxdv2VGbL+Q/malScZOIH4u86YvRo8wGKbkWQBHnHIhoSAShw2WSXkopZLvCmnCrTMFOWqvcoOAZgCApslcm2mho5CSLQwUiF6kO8KfD1n4CONlXOCOiwAk3qLyZH9jcbnKmK7tXEX9/l2AW5CEXWMbiqYEkVldmalfd+MKo68KABImvcNJUctq0XtGxI0BPe8fk4BUBUZG2oFRtF9DnEL4TnrZ1ejuFrt2hXFnmpzvPV5tzlePBawbvcsbAVVrp2FV6e81XrF2SoExDRG7dz4+emKqDCd2i61WQusMbeAGmHjODCvjWYu8eoCr0AXEsXelzYcyPPYc4K+DQB6EWxJnwjY+uMXq3j5p+L3Ss6NZAe/laKDhiIgqZOLhaUITsWnDC/68kohLtcelL0Jpr55x5TdBlMfftndHTC1B+R5ZTO1bds23HHHHbjjjjsAAPfffz/uuOMO/OlPfwIAzJw5E6eeeqorf8kll+DGG2/Evffei9WrV2PmzJn43ve+h7POGjpP3t6UkZVBjOiqI880zOMVZE92AQCSniZUOQdGNDFuZR/GXM055MZ8eQVPnJnCkRfVYFIOQbB1DIOVvMsDFbHdkWS5aT8PkLpp82lZ4/BkgG2cdBCbBfDfHcWveMJOt2um7JsMBnTdAzSxdamP4vYw8OLr6QZfrzmCJ428DJQ32xWzzSWYbtfMBjW1jV5ut0IkcyIfOV0pcgbroc2LeO1FnntDCSmoEgGVHKqcMyuWko+F1Q5IkcKmT57byk455oKw6VPTg0E+AFLFiTtqi/0M7mXcyr5o4hDAK0xAUlfR5BMBEGu5LSDpvhlVtx25vBaDlh1RKvATslTr7Gvs5uJduWujVQXY5jmQZbHCc+N7iL9LSAY5R1R4YqTezv5lR4FFRbW3o3a2tEfF5VqAlGK2ds3iKspb+d0v2fAlxSpk8VLe8+aZkUrTBXZNEdn1kEYUc8vFqHPvMu+/e3mVf44CUuy5wlQ57XLi67398ipuv7zK6r7Cu08JcNxnas6RxdlWIahLcXRzERWs/UMHBbme3GPWxSlksm5eIOmMnK0UqWcPSHXkhSvPKzD1hz/8AccddxyOO+44AEBvby+OO+44zJ07FwDw0EMPOWAFAI1GA9OnT8cxxxyD173udfjtb3+L//zP/3zaoRWeLfmv/3cpBpolJKkBDcsZnJRzmG1s3a02l5CPzkAGeODjM7Dpk+diw7ReNA5qQufMKvUfzINIY7RBYyTwxys5b159lB0UcwZXjVFwAxWzUAHQyRBNHs6jylL962dxKoi0X6G0BUgGGEiRttGT7QA2YWENeRdxUE8DdD3GLNUdX6g6bxoBgDoHmhYAKsOefc4QlQAM6GgwpzD1DNlcf6RARpbYtvECoMItuily5eAsRgsPJnTlLhtQajjZc0JA2ThANeZLQWqZIhA1CmO+GHj7FcsUpTA5u1NCA1/xVAxPy33QQacmEaCj4/hULayToqDuHQMpwKoAbV0uJ2DQXgnHUDSeb2crFd3vEKBrKJ8Ayesnnn2kfDR1YAjgNATIErAxcX6tpe/lfwnYGALHexbGsbXuWVhFup0Z2dI2Bk6K4Bkbe58uv50A61AtlrFab09KCJKEVXKeuAQPYgr3Le+TKXvmZ8q5vo+j/rDn3FXzQVGhgTs/z/d67Ge5DS2eqvA/yaIH4R+/WMVtX2KAfPy/1GxZ8p8qKK8A3SR3jT9+0YO+0nYOg5B1KRcj628pGkBOare3juwZeV69Vm94wxtARC3bNddcAwC45pprcNNNN7nyM2bMwH333YeBgQE88cQT+O///m+84x3veG4aP4Rk1oBaVzL+oQ+kzIY8UeaJMpjjxnydDdIf+PgMrJ9VRWMkA6Keh4ERGzS6H+X0D8auPCWSL4gZKN3wBpeO3ZB8fDnYNsKmkJE4LYBPsaHr3gtPgJbOYG16gPJTQGm7QnM4UB9tWaiRPLk1R4DjUgFojLAhHTIb3DNTfO0cSLYziNLNwqvpWCmADNtPAfyd8kJiZKcq4NHep5VRbuJy5aJz4oGFLCgK1TlEYEBVNoBVS7Ixf/CgBEyEIA8IVuaqUC44LwKAfgsncldf7t3HySVdbs/qjLu4z6kK3f0pz1SRKkRhH0LCuEHtwjcctazW0v7xSwtApcDMuQCiKJSx54dJnpWJY01JG0KVVUs99loOZAVtEcNzKMtOqVZV28R5HpCULFia2st5/NJtDKCm9tb8LQtACJ+FbYOAqxDXF9XDU3tr7WNbPU2ZsLDmfpuy+BGVXdLg61EaHA/YKt1k9kbZhZZ75sV31sqdl1Q51Yz9Lvd97Dk1B6oAXliF9/rHK/2x26/g73/8t7j/lQkpy/hTzjcpV3j75fI/929jhHKehQrAnZe2AfbPY8mhd3vryJ6RdOdFOvJsSv9A2doBAWp4k+1+SCF9qszMD/ExANh06nkAgLHfXAqzpYzubQnybl5F3r28iuM+U0MyCNAw9gTqPwTofswySGWgNMCUfL6f9bwrAciBXABVU2yklFPvaTvoKmIgBbBNVt5FLl+f2FIkTWCgmwfipM5ArvIkTzaN/eAGZm09iHoe4TJdf2XjeZUBVPbgCv2JM0jnmYl8XCjjgYrz5nPUDDygskwVAazqc3GlhmBiXCRme80CY8OxrPyILnn8iMDJo8nbmbnLyDmZjvcpHyahxYZqiO8y8SmpA4js4+RZtdyeLXvkij4PmtqArl0WuTYQ3W9RG+oLtbmGfU7jl9R8mbA8CkbsFhBE3ny0Yy++UMLEyPK/XE4YKm19T9bOr2LKubVWwBO0TwBUYHoXeb0pBGCqCCYL/0d2SDnHYXu6MmlWLfJOE4ZIvPbysjfOzsvek8+UbVgV642riFmdo+fWfJ5KYuClm2yEPnVaLfqdHdNbw121Kqb21tx32Ps/9hxf9mVnBd6bAI47s4bbr6zi5f9ac/n7Xv4pfh/++EVbhw5eNvBYQ+HMVXi35BoCosRS4K4+a9vV9cz6Nqn7fjBlG2ZGDRE7rSMvOOnA0udY7vvAHACwSY4JaksJEENoO+oQAWO+fiEA4IjrlmHjh2cBFtxkPYTmCB7MJJEnADSH88A58CIGLEkDqI/kASXdzmUym6OrOcJ7/clKXmc8oOuGXeVlYnTOQCoZVEgGrSF7Nyyr5VWHkr6hMZLbec/CKhvHDzJDlfWwik8GKGV8BPXyZsUr6kx5jzrABvEE7v/ITG90HoZFsJNUi32UPRbaUAFoDakQSljPELgrZKBU8N0lkg7PJ8CUDG9l+5l6NRslFJV13lSBa7rED1MCCC29QaVwNo9vZ8O0Xndsw7TeSMWxYVrARA11jwW5b0bV0yqWeYsMgKXvAmbGxTQK+63Qh+vnBOxUO+Al+0NGB96LT0BSaGsjqkCRdRdUHct09Nwa2w7aALcScXzNUk7VMvm8gE0jYNXKwoRp2xB52Nl9d15S9bg+AJfuUyF+PwDccVmc+++ZeO5Rm6Wx2DeZEo8Bop5NrBG6SeFAagjERSUPWLtL+33VxVWn7nMspX2npk6rYVVfFXfZtk8VUCUgyATn2PtXhpMgi7dwKC//11r8GyqIzggv/zQbzZNiT+GXnVXjEAyA60vp16m9NReqYVdl0qwapk5jIKUK757YoIbM5d4WQ3q3t47sGen05D4g975/Do64dhl0YkAjm475MCUgfSqJBhItIQOMwr3nV5FuV0i3se2UBKErb2Z1RLrdGpkPMjOUDberaQWX9kU3WG2hmwySZGUqbIcYq4r31Lq5VSSDygEnsXHSDWaXRjwAdD3BbNM9C1lNoOscKZpStpMCeKBO+30cmnQ715EOeuAAgONECVAiBlRjvn4hh0TIeUOuWdWXK1DGyY7DaOdRKAKCDdgZ1hn/7/pbByCpKOH+AFAJi/jAJ86NR96ias/uC+3XRV1IKcGUCXmX4W2YQd5tkA0zyHrIMVouwGOR/VAeRI3r68OGab0OOMnnuJV9vF3Mnxum97Khuz22MyGhXQIbNHlHwoCQst07szo0oLIiDJQzRlcBayX72z0LWNsgy1LJ+6Otc8PE+RxVXOyijp5bc1HC3S0ooF3EcTcRT6+1BXnH9NZikkkFdlLwoCl8zndeUm2ZmI/9rAdvYtQ95dynN0lHwUXtteV3JOFQQnEAPbfOIxLoU3l2WcCW1Dd1es2dKyrD0G5q6rS4zcf0ejsrxxTB96vkzVPGLwRBQGJtoLzTBsecIm09iMVuyng2TZIYSzRyZ6Pl11keQO5EJs2pYcqMmgszowjOUUaSycMyf89lEuS9reZbtmwZTjjhBIwYMQIHHXQQTj75ZKxbty4q88gjj+C0007DYYcdhp6eHrztbW/DvffeG5Wp1+s4++yzceCBB2LYsGH4p3/6J/z5z3/e7f54LqUDpvYBmfj9hVAJIW8kUJtL0E+WmG3QBFMhpJv9r3/DB2dj3LeXAiObOOK6Zci7CPUD/Eoz7+L0LoMHgAdFAwweCKgm0P2Ip/Z1ExgY13ADXd5NKG+xUdK7eaAyJW8gLlHOARt6wQKtdXMZMOVdQM/jDMaaw1iNcOJH+6BzoOtJTpIMeAZMAnymgz7IaNJgUJWXgdIWZdV9BDQ0KBP3RLsJcLIgSmUKqqltcmeFlpUseUZHSRiFIj1gy0Wi2gCqEHCJXZSGmx2VgvPAdGEYnKqyUNeOxKGseHfeTTBdDLhcUuQ2bdvQ2xut9l2QTsADLHuJcX3sMRh6Du6wWQoubY7Y1IQsQjiRRdcO7yX4Pn4pG6/rjMEO52+0W52B9sR5liHI4SL/T1xQi1SfocG1Az9hn9trOjbBth1gzztRk62+qOqPh+e65x50U7g/7CN4NiN8zY6p1pxdESlrqO361NencgYvk8+rtaSt2ZlMWFhzwEGcP8QAPQRVslByqlPi318xqrm0X7zyZL873i6divS9rVeYVvdaa38sZKsAIC8p149iM6UKUXyoQEH/8d+qzl40qk8x0xexbzsQCTSc1Pkd00272LOMl9iJpv1si+rs7l4A8utf/xpnnnkmbrnlFvzsZz9DlmV4y1vegu3bWd1BRDj55JOxceNG/OAHP8Dtt9+Oww8/HG9605tcGQA455xzcMMNN+Db3/42fvvb32Lbtm34x3/8R+R5PtSl93npgKl9QLQ20InhH//IDOl2xQyF4nABEj9IZMM/z/KrxRTI/24Q6y6oojGKmSjAe+FILKdsuPW8U55N6tpUdgNaMqCg6+whWNrMSYmz4eTspsQDaFxfH/r/Lsfa+VU0rUF52s9bfaRCfT+72iVg24vZQLr/YFYJJgN2ZZjwdSRaungXSnLkypPWcD6YxJQBKGMgJTGlVLAhVwwcirGmQsttggNaLn2FA0vUlnkAfBmv9lPBBBrMGAKo7KaKWC0h530kbNb9Z03b8eAe6Ydavvp2kH+uivg5jVvZF9dtzztyec0F/0z7FQOr3l6k2xT/37tjQ3Ql4FX6X/oSvl+1AJ4mXOiMe2eyV6iEwxDmSFb8AoSiRzfEpB4yHGLvtHaezbdnrBF5G0CNwqsBamV0Vl9YZTWfFZdORVl1XwgSrNxVq8asS0unBRvgjLWh+LuAKHled9WqXNSGF0kHnp46ad3cqk/8qxAF55QAnNxYC7iEnbKOIJR60KUyDirqwqQIOW6By93Lq4EHaet9SxuELZJ7dGYF0j/2u3jjhXGqwkjopHzyY23z8pFi+yvZbxI2aZDzp04PVJM7CMs0eWaN85naRWDx3U4H7XWD2FtQhXRLe1EMds+j72loPAEAP/7xj3Haaadh8uTJOPbYY3H11VfjT3/6E2677TYAwL333otbbrkFV155JU444QRMmDABV1xxBbZt24ZvfetbADibyFVXXYWVK1fiTW96E4477jhce+21WLVqFX7+85/v2Q7ai9IBU/uArDl5Pu77wByk5RxQQOOwpqfECaARGWAUxn5zKQDO4acSYtsh+znm6xehtM0PaKQ5HELlSaD7Udh4RDapZ5dffVLKwEX0/8rm+CttVi4HX3MEn5ONMEgGFboeSTBpdg26yWqY+oGEvALv5cdRHlB5ym5PWgN0G9xTVo6mxAOW0T5KugyiMhHrumaGKrNMVZPBUouRtwmAVRgjRzYBWgK2hJkqihriUy5FaFULukbEgIwI3ClhMunwuwLGXL7Sn95uEi62IQrtAPeOtPSHm4R8lnvn+ZbHyVrHL60xk7GLWe9boqRL2xXaTqjStgmLalG/ivdcCEJIoWVUigBVcEwe38QFXK9jpYL+Wjs/AD/hJ/wkefQFNcBwVOxJs2qYPJPruXs5s0eibnOG14V7b2ukDkS/xbZSeMfuvNSrQo/prXmsbuvR+c7z9IXM3L0zqw4gudhPKf/2ATsGBEzTxPk1Fwkf8M+HUqumF3V/kD5KZ+xBDCByfJhybg0gBjRebR73RfiuyH3rJlwQT4mRZ0rKpZgJ+04RgbTy65cM0Ts8tTe27ZLrrVlceH+tTD6v5uw9KbFjkl1IyruSl+N3NApa/ByIgd7tDUBLPtowC8iOZPPmzQCA0aNHA4A7r6vLW/knSYJyuYzf/va3AIDbbrsNzWYTb3nLW1yZww47DFOmTMHNN9+8+53yHEkHTO1DkqY5J+1NDf9492sgG2FAGdsEbfwwp5e5/5SZ7hx9IL+8+okSmsPZ2Ls5kn/ZOmOmauBAIOkHr0JtFPTSNrTYD0i4BDlXN8Ar4wYPIKXN2qlexHhdN4GuRxSgvHdL2m/Vd4OEgYO8qjDvsSqHFKjvx/sawxVK/ayOVDkDwOZwTo+jMlVIfmqBlGWoBESFqgSnzivsi76buKwDRyJDACkAnqFqR/nIVzvYig0VJeSKbPqXgi1V4NEXgpLwOASUhfvsit8N9HJfBo4taqnH1hGtzJUNtqkKTMEuSgt4UvH3lhAB8EySeNcVkxC3077yAbg+Wjuv1e4I8GAiYnHI2rUUQY+9xj2LrHrP/r96Gdc9ZUYtYkdagJSto2gnNSQQt3+cmrTQnGOqtej5i2qKtA2YCf6+IxZEGD5R24WqXcdCN9BiN2TS9iEhJL+feO2GKkJT8s9f6gu9SqGDPlP+vt21A5Acvd65D3ngz/GpYBQRbv1qr3sfHFAq3JPYf4kx/eqLqkPm4jt6bs39BtJ+60RT8g9QGXJhJiLwbH8zbWOpPY/kJS95CUaNGuW2ZcuW7fQcIkJvby9e+9rXYsqUKQCAiRMn4vDDD8fMmTPx5JNPotFo4MILL8TDDz+Mhx56CADw8MMPo1wuY//994/qO/jgg/Hwww/v+ZvbS9IBU/uQ3PPuebj/IzPZEF0D1J+yXYomlB/jUezI7ywGANBW/t/kCkdcuwymYpD3GDT2NzBdvIwqb2FgUtoG5N3MMMnqUuJFSdJTSYDqbCsyHiy1ZarEMDzt53N1kwextJ9BEgK7qvp+7EXYf4hCeTMDqGgQtpnjSTEoGzwAzg4mqXN7Bw/wk3vL4GUA5PBhDgTchKCk3Qa4mZoN1OHAWNtAn0NJW72csteXZTIBiQESCgCVDfRJyk+aYduDybcFTETqSk/lhEAsjl2knDqG9NAxpNwkKOyFBo66cMfsBwA2zi8AoBaxwCH0aCMVB9WcsKjmGatwa2d/E9RbTEQcHpPya+dXXcolSeArxsJh2yfNqWHS7Fp0D3cvbwV40rZVK6uxvVTx/gP2q0VUy6045imUu/qq3gBdWcN4+25KaJGiTFxQc6rLSA0FuLhxLkUMxWw0YI39bfl1F1R5PLAG4i5BuvaR0AFbj2WRSQC59IdTpRf6R54vwadECo/J1zx4Tgo4/pM1ZqJy4ITT2bbvti/zc0rq5OyxJCyDIs8y7Sih8YSFNZ8ZIrAHBfgzrwB5hVl6+Z0Yy+o/5wbopHd7A4AHH3wQmzdvdtvMmTN3cmXgrLPOwl133eXUdwBQKpXwve99D+vXr8fo0aPR09ODm266CW9/+9uRJDtOe0NEUDtMVbFvSwdM7WMy/nuLsPHDs6BH15HuV4ca1YQu58i7CUdcu8yFUtj0qekAAFNPcP8pM7Hp0/x/aatG+cABNgov2YGwDGTDCOmAH+xgbKyZulevOcpdW8Akq9IMbpAG2PbJVNhrsDmCr5E0PABafVEVlacYyA28yA+Yus5efjrj9vQfxtcV+67mcA4UmHdxAFAZvEDWRicr/NBCRga+ffxdOeaJmZpWmkAAlXj++dx+QV0h4LHAtmXiDxGfAqe2QeGYJs9QBWEFIvWYx0j2fH9DToUaBGEsSrvz2qnFAA+Y3ORn1RriCSU2VUNJCM7aMUTu/osTKVr/B1pjQrkJVgX2T8UJuU2/iVpv7fyqU/+F1y3aHYVxoYSZcKERwnIBaJo6rdYeb6vCZ1C1az75fRGALtxfxOhYhmXNkqo7p22U9/D9AD9j6R9ZMIlXX+iJJ9dJBn1VExZ5+yMBTAKWBHiKSlDeGQEvU2bU2IDftlUijysT9EXuF2RhO2S8Ou7MWO2sDAOn275Uxa1X91rGU+Hl/1qzfaRc2WM/V3PjWYtRfEHGrexzaa2ENZP7yiv+tya2nTJWKWCX1eLPphio3d4AYOTIkdFWqVR2eN2zzz4b//Ef/4Ff/epXePGLXxwdO/7443HHHXfgqaeewkMPPYQf//jH+Otf/4ojjjgCAHDIIYeg0WjgySefjM579NFHcfDBB+/B3tm70gFT+5isf+8FeNl/XoByJUM2UIJShPtPmYnSS7bBNBKM/dbSqLyu5DjiumUY19cHSgn1g5uob6mgfqDBwME8cg8eSIBRGDzAgpYR8AOMTCaK1XFu8LEDMNkBprSVwZOj040N4kl8LC+zx4sp8Qr3zkurSOp8zra/40tUnuLzuh7neipPANsPI2TdrN7TTbZzyLptG2Ti0YUI4+ECRyahwgytBCzJRC//F2d9QmSD5RyG2kzcbbewnp2Jgo9U7hopdXFD+XgrOikCEGefotpPGHIdCtup/LF7z6/G+6Sc5jx+4SQxttYeWBVt/Pmfwr4h+qt4PwIOIlBVnAQD5nDtvDjUgrR3wkKe6Nt69bVpu+sjy5SsvrC6wwlSUZuYU4CPp9Rm4laFfwhBHCl5z1XhFbInid0WYO2WxNsP/DtzzB7gbJIoAC/K2P0CVixDLCw0pb7P71kUpIOBZbOywnkJg7rVF1X9b8u+g6HnYBiLSu5NQCEQjzPSr6F9kwmBlLBsAF5xRh+O/xeJF+Xz7Zk0BuDewaT1eYhMmlNDz1+4ceJNLM9D7DadbWlhPCDwNYvOC3tb9hQztatCRDjrrLPw/e9/H7/85S8dQGono0aNwote9CLce++9+MMf/oB3vetdABhslUol/OxnP3NlH3roIdx999149atf/cw6Yh+QDpjaB6Wc5CilOXpGDQDgNDKDT3VBDbLtVAio7v/ITNz/kZkwZQJ6ciQ9GTMxBJgKYdvkBnvKHca2Vfcs4hQYpW2sutMZoGzcFFEBSDDNvGxVfQ2gbI3bsx4u5yKrVzimVd7N8aXKW9h+YMqMGvIKUD+ADeABuxq1gT/TAYX+QwnQfE66HQzoui1LIrnm5A2lYEDL4ZeH9lgoMYujvDowKMCDNkUhDbxReRuUpAr/D6ETFFZKaYqSLzv2uh2g0sQAseC5FoGAdtRPVCccMCCNyNiXlA19AEQefuMu7mMWannNMWeU+DhTAqI2VmMVodQV2oK57mvHBNj/Q7sSRW3YKBUzLgIcxDA6lBawVOwPhRbAJteVT2XYGDmse/L5QdRz2/9Fo+mpYWwpW+aYIBp6dE+IMZYclnhNqy6uxgsHBK+g4vZIX7jnaRcTzvCZPIh0gErBqd6lnS5tD7Gd3L0zq96zj3ydjpHKENnXSdlJs2uYfH7NefKRZjZamYItlgruT8CiWyDZsqIGDIBQeD4pRLacJlV2nwIl3qvPlBHHqlJc/5ol1bYG5xMW1ThJO1nvRRuvLWn4d0MM8Sm1j0j7dheTRb9Q5Mwzz8S1116Lb37zmxgxYgQefvhhPPzwwxgYGHBlvvvd7+Kmm25y4RHe/OY34+STT3YG56NGjcIZZ5yBadOm4Re/+AVuv/12nHLKKZg6dSre9KY3PVe3ttvSAVP7oPz+bUux6p8WYLC/jLScI+1qQld41CAboHLc9Uuic+4/axo2few80OMVIFcwFQKNyECZhuky6LqvgvoY76FBiffqUYZVcKUtDKIqTwIgdsdOB6zNU+JDKyQDrJIzKZfvP4QBl84JAwf6iW7YX3jQrh/A9Q0eAGRdXt2AhEHN4AGExv6sllQZAzVTsmWKvrsJPDPlcI2KJkkxVIfYRcl+EQUfpiBgcNy5vpeCTyr8j/aMBwUJmcPrSQgG3+TCxBGyVOF58T7PuClfRu6veH5wPDRud558iQAiCwADY39hKMZe0spKudAJAQgoApkhGQHFgTV3WfUXXCMCOUMxgSo4D61tuWdh1bF6axZXcfQFNT/hCmAJJnz+ElRv/K67hopSXgT3xe9BXwmocs/NAmFpews4DZ6nTPpi0B+CkpBhEvVfyGLJd0q8Qbvz6ExsHwYA3SVHBlzaGdLWlktZ1Z+AD2XBhrKefmKjJaE7iveLgJUKXm1ng2Xv6/hP1uLyIQgzfjwT7+AdsVKlrQFotJ7Owo7JuaEaT96LvMtvRYP950L2dtDOK6+8Eps3b8Yb3vAGHHrooW67/vrrXZmHHnoIH/3oRzFx4kR89rOfxUc/+tHIrgoAarUaTj75ZHzgAx/Aa17zGvT09OCHP/zhTu2q9mXpgKl9WDZ+eBb/qI2GGUyQjG5ApQa0pYRsa7kFUAEADc+Rjh4EMgX9ZAmqwuEWBg/OoZ8s4YjLVkIRMHCwtV3qYfunXFLREM8FyYBPdCr5vNYsrSLt5+vkFV6p5hVmldIBXjXm3ZyGRgzYjzuz5kBaMsj1JE17rVwxhZ8QH0tsnWVWIVLCx3jytIBJUaSaBMCsiptkApAR2jcB8cQf2D9FjnxF0LUjYFAsFz4HYcOKYKPduQXZ9OnpvH1qemsbQk/FwPZqSLY+UMUAraDFpZhxxu0egIR2ciJRdHSyYRJENanj9pC2noL2PiUw5/gltaif111QjZIXy74Ji2pYO9/HCpJ2iV2U04aGx9Ga0DhU6YUJhCfN8YyXGHhHDFg7wBb0n2OjiseGeNYRVg/xud23amU1AhMtYLr4nO35Etkd8P0eAk9FcCDJAZ427FYIHqMQDJrHAnFOoZTHAqdGs9dasyRm+cI2hGrfkH2LAKMAyeB+TcmzXWKv9McvVlufjQrecwHFQwRRmjKj5lhylcE9d2kLJUBW8X1kEmbYVq1k0H3Pwmpb9d6Ry2st+55tMaR2e3s6QkRtt9NOO82V+exnP4sHH3wQjUYDDzzwABYtWoRyuRzV09XVhcsuuwx//etf0d/fjx/+8Id4yUtesie65DkTRUTthoyOWNmyZQtGjRqFzZs3Y+TIkXv12hO+v5ADVJKCTgxMrmFyHinJKCQp79vwz7PcOZNunI81J8/H2G8tRVrK0egvISkb4M9doDJh42en+QlRAd0PKwYuynrtWbCkcgCa2SIoC7aUDQoqq0JrpAkAlc0MhAZHw6WFIQ10PUHY9mLlgomWthNMysE9Bw4lNkJNgJ4/KzT2YwP1gYP4OoMH8sTMkb7taxqsREMVIIxyXkrCMjlcFUy2pAGkftKX/VKONHFi5VD9h+A6oSg4tZ5jo4rgKZxByYKsYF8xRtGmfzkXADDm3y729eQAEnAiaonurritriliTF+YoB0zE7RLN7m/7juvyio7UYdKP0nOQFt+4znMRI3r62sJ6BmCq5acZxacRe7kYR9RnKTYsYOIyzoHCBV76K2d35rguAiM111QdRGqnXeobec9i6ouH9+k2cxQTZpVc+++YzWL7vDSv8S2Ty6kQdDvrmzwf9HuZqh2u33CjAhrY429VeE5h+ybs/8CnArN9XcRcMtPShY30jSrHozUWIa91ibPrHngVXi3xHhb1IGhMXzY7+2IW1cmAJlaUuCQZ5GSujU9aPr+Ce25xMYTmkNcFGXyzJpzqpFP1365FllVnu3LVRe31iNy1LKaY7TEDnFvzBlyjeW3vg7dw3chP84QMrAtw4wT/vs5md/+1qTDTO3Dsu49c0GkUCpl0IqgE4NSOeMJnHgiD4HUK388C0QKE7+/EJQrNAdTqM0l5JvLMBWCHuDHbSqcpkY1lWOYlB2wVDBwGc3MVXMEMHCwweDBOXu0yKrW2BQwAwCMB1LNEXyeDGzdj3LKjHQQqO+n0BzOZWRATLcr5D1sc0WabTtUDnQ/olyAwBb2Z4g3twikwlVx5MqvC/sVAzbl1CrUFjztkK0qAgaCLxjREnF7w8lwzBcvxpgvXhxchxz4cyo52R+1LWDZZIILmZaErGqT3CR55Io+P+GLqk/OC8CDqPpIsR2V2Ey5+xLGQcX9KvUJQ9Vy+4qNqNs9n7CMSa37ubLu/xZcODuhQjeEImEXnCoMvq+FfZk0237OqjlvVAdE4O9t1cUBI2I/j+mtReUi1V8ANKJmBc8H4HrvXlH17ErQxujkEJiGQK2wKJB8ddJ38luR37UwjkN5hhaBlJx39NyasxeSuFwR02bfg9UXVqP7C4F8sIZpFXkPbLR2WaiFqs68Yu9LPH0BFzzU2VdpxLZbVpwXomWkQiAlKtNQtbeqr7pDIDVxfi1SFT4XYnZTxWc6EGCPSacn93G59/1zYIxmSjbXaDZSkNHQqYHS8Sj4+7exYbpShFJ3Bp0S1AF16BGcg8+8dABHfmcxqGJAo5rIe4xLD6EbfnBJGt4o01SA5giCbiqk2xLU97fxqmzkdIAHMTFaV+SN1ynherJhTK2bEl+jOcLGlBpk5qLyJNcjNlhHz/XBAlsATbByjf4PiwSAp2XVHnrKCaukAKXBjFRoVD3UqB9cu62NVNv2hpRJ0A7x4gvBkytXaIsDLG1Qh9Sv4/v3bVBerZIS7juvClOO+4ZSgilRnGfNHg9tp8Jb2TC91xNvSXCObadjFMERud29FETUfCJFr76J82qu39fNrTpwJN217oKCisz2g9QzYWGt9bqEKN6R7Js8s+a81WTf3SuqQyY7DmVqb60VUMlHEQDZ9k6dzkl1QxVrJMFzdO0sgC0Bo+7VtoBE8siJqs+xMUBkkxTWdc/Cgqdkm35zwIQ8gIGAGcBHSw9/f7DxmQo/BTkmO1xMq6B86K2ncuD2K6rufTNpYOcUgPoWUXA5QkMQGXoSuvtR/Cwnn8dR8ScuqGHSnDhHYpgo2qmz97IY0ru9dWTPSKcnnweSJMYPOgbIGxpJaqDbLOXvefc8AIBWBJMpVLqbKHVl0PvX2Zg9NWx3szVF5QkNkPXqa8B54+iMPDuVMujpelxxss/MlivZgYnYlqE+mjeAwyFUnuRyg/srJGLEngKlbcTHcratSgYUh0IIJoryZjZWbeyPOMI3ACoHS0DZT6qFkXCgQ0u4AQQjd0ABKFHryUwU0lf+q1LkNs84qMLqu81M2A4kRftbHmE8KxZX90MUF5sl570VXEcR3IQasnYbP9cLSthuKorDZdu18Zxe30bpwyG89SJ1VADEyJ575EU1F/dIIq6H9RTVdeMXF1inwBg6CvQZnB8Z4VugNH5JXK/Ucc8iP/mtWVqNgQVZL7oA+EjKlKiPAgkJpaItlXurVPBP8Bxa7KRoCDAQVVa4KBC78KvYGw3g39K6CzwIAXyZ8Pc3YVHNM3kBGxYCL9I2lEJwD/J59FxeOOUVfx/yfkDDRVNvuR/5V5gleYfE1kvanAIvO6vmjOJlPHLATbcG0hTVsIA8l7qKfP+bkgVvAtqI25rU2YZU2eCkknYoDHra8p515AUnHTD1PJDV75qPte+Za/PCKShNyJo8Ch713cUt5dPEQGuDrmENx5qYXCNvJlj7nrkAAN3UHqAoDn0AWCapSzlWSRkgG2YcvS8DnAT+MyUGU3mFONP6IBuYdz3FdjcqZ88/932Y8oasJQ/gZIXZHA6AgOYwD+RUMY+em0yUB1LBREpi7xQM4NGERXDgIQJSboKPkUschBPB9wLgic9q/1UBQwX5jRilcHJtU77IHLjJLKUY1ADOm8v1l1GeaSLgyItquG9GlRMeT2ObqI2f68XYz690oC5izhQzVWMv7eN6HNiyfRleG4Xo68oaos+qtoCBHd1bBNKGkJAFkRAAQ13D7SOv5isyNKsvrHpAGMiqldXo0Q+Fc4e8vG2noiCJclhIQFehPUW7LSpM/PIZqmqd8bZ15Z+wqBbZguk8Pl/qnzjPlxPHFJNY1soCGzHmd/Zs8/hehOFZs6QavYuyOZCl4mdWZJSljCwGXDdRsBngjsuqUf/skChW3H152d+TMLF5he04wwcnKsSk4dn7kJGK2MLnQHKo3d46smekA6aeR2IyzaERiKN1N5uJn+gLIhP24PYy6lsrbDv1JHtUqKaCKRk0h5MzupRceyAOoFnfD6jvD1b7pDzASI4rofIFbJFm0FN5Aij1E/ISsHms4tAK4sFXB9JBQmULQTeAYQ9TpJoQZoyU9+ST1aNuMoPFufpkGancYBrZkQAeSMnk7zz32syApIYELO07Fp6lCuNFFSredOp58T4NoKCee+DjM4aeiTFEm3alnaF6sDBJhiJxpEyZosCcxcnBqRWV95pk1or7dePnej3oCQCXTLoSTV3OXT+ryu74AfPQoqYr3LMYFwOt8anCugWESGqUUH0Y2nE5dY3yXmhiSyQy+fxa8J74Y1OLXnxBkULR6FgY7FPuVUIjKONT2IjhcwT+A4DkgFNg0C35DUMbvPB34V79hPtEWJ2186rePipkiAqBcQW0HT23Fj3rEDSHiaZJ2yCjAUB0zFkRPBd2RYuKQvvlvgB/7ZedXYsM14tDorSLlAePftEFZ8OZV6wRfQBMpQ0CpBygsnZXAqiGSvHzbEtHzbfvSKcn93F52X9egGN/dAEADpWgSzmoob2dTpvJJ8u1Y7GQK2BbispfNZIBjbGX9uH+s6YhGdRshE7WPkpxDKisy6/Ssh6CKRNKmxOYikQl5gk13c5lBcyk/cD2FwONkQoSiDNpAOWtJspUP3CAQtdT7MXX/Sj8QETe7kFssUCwaScscMr9zcYraQuujILplrDtfD4EfIWrfvmqwTZSdhaJgakvOJSnHpGKA3MG6sQxX78Qm049f0ePFod/ZYVv/w6kuHov2jOFK/IdVuWADhVUeIhGAlLA2EtjABR9V4QjLlsJANj42WlDtNcDKhIgadsepjkRNdORF9Ui5tMxEiEbtYPRKmJtREwcWX2IdQcmza4xCwU2PpfvzqamyDy0eZfc8ynsdsc0vM0VPCii4F6nzAgAZniNAjNTvGboERmBx7C/7LXWz/JllWGgIYBAGCVFbQz2pV3FZxC0d+28alRGxoZiIM/iO+owLPn6hlJvu3emwAipoOPD+sNkzcLUyXtgSryIzLuAxn6EvJuixVkYq0quFTJScl2VP7f5+Tqyb0gHTO3jsm17BVs297j/N35oFtLhTaTlHOVyhp4uXhJN/P5CjP/eIgBsN9VopKj3lwDNrA4Azm1HzBRUHud9psS2Ts3hXD+VJDEyjxZsv+ANpD2wgaPfSTO46nqMgdDgaD6e1AlbX6yxelmVDc+HKze4NkYoNG06mqTOgK7nUT+YAd4mKxqcBzUb0FdMzEQpIB+W44EzZth9aP0ssBfuHzt4kwCvnYAbkRB8ucjngV3VmG9cWGiEtDVc+sYSr/o9E0QKDPxSgo9WbrcCuIrAjEZgc0LR7UnIA9cnIqImHUIiFQ2AIy5bifvPnhaDu4KVMWnYNDXE71PqUwRFtkMJq+jE5Z0Kj0TiT8n3sE2uyW2Ax4SFzDK5PH/hPZN1mSebly+Igt7CUoQbgu8B0CYUyoTXQuGe5N5FFR2OyIV620pQr7v/wKg+yj0IVrE6JqvQBpV7Vd3Rc2seyAa/F2c3VXjnwntz1wvbD682jYCZ/LblHoz1Dg7OFQNxYcVDT0UHygN1Z2gPJ2Eeor4K6s67vNeglKnvx18TYZtERRk6ZgQ2gtL4CYtqOPKiGvam5NhdVV9H9pR0wNQ+Lt1dTQwfMYgjrlvm9m344GwYo7Dm5Pm44x8YQJXSHJWST2JFRoP6U1Cm3GCUdxtAcSiCwUMMlGEPL5UxgIIGuh9hNV/XYwrZqBwoGQZQdmCmxCZEtYNh0mAgpWBjSCUcI0pnwPbDFKB4kMkrfJ28Kx6QFQGVzaz6MyWFrr/yKCdslZ8gOZGp6TZQTR69qEwwPbkDHnpAY8zlK0HdeTBoh0tIW1dxkpLJ3yhQpoLI6cqVc157QmQFdSlFQ3v1KSCaUWRSiiZkar+Fx6whPYnHoYvgDguoKJ6cpW5nNxYENlXAEV9Y6eu3+8QGStR2Q0pwO2Mv7WMgFR4O+z1oy7i+Pj+RuvZRtEmsHlMKgCp5T8ChDH0FNKyfwwzU+tkxEyXfJ87z7NCaJVXAWDd/ua+g/xRZ1dsOMLZT3RUBVkGcIXa7Y2Hd7cCabVtoLB1ew8XpEoP7NmBSjNBFhTh+qQ8x4QzVE68SC4GKU7EKAAp+O2vnVR0ock4A4XUTD0Qnz6zF9Sh/fWnXXX1V3HFZFXcvrzqPxPB+xbA9q7Ct1B1fqMKUOIxBlJ8vlMI1Q3WpmCmwilchqdsFX2CPJkBNUs202PAp7226gzXIsyIdNd++I52e3Idl/PcWod5I0d9fARmFI66NAVUoq/5pAVb90wL3f1d3A+l+dehKjryb0NifR1hTMi32IW7Ag48VlfUA6VMJ0GVAGig/xaq8dMCu9oTuVmzTZBIg6+ERrzmSU8yUtrK6b90FHDldcu6JGpENzIGmPS+3+bXS7RZM2UHOef8oQDXYdkombGdInisL0AiqoT2QCif2EIDImx8BKQ1mqGQf4ABVcRYk4P5TZvrVsyJs+qhX6zmGqt3gKm2XSaLA4rRjPpSCC99AqWWdxHg+IU6xE9g0eRuTAGjJ7VjwCbl0AOCErRpC48nnBBPqxs95dmunKsbiRFsAKJIXcFxfn3tGApLGL63593UIYAOwF2B8Ec9guWjq9nYnzeKyYoDucsAFgEpCFihiY/FVF1ejvnTpYHZ034rPbWlz4RmH6Vhayuid9C/Qqo6U/eIRK++VDYcSniP2bW3bGD6jgE0iZWMtUQBIpJwNMFp0RnD3JyBNB9+L15bz3DvL7ZWYXMf01jhgKryKVAJ4AjYOmQ7elwAUU6Fdygb9LW2Fz1cI7idhqCT5cripzHr62cVmdO5ekL2d6LgjQ0unJ/dhIaNQKTPbNGzkIMhoHH7Vcoz79tIhz5n8g/k49kcX2NAIGrSthPJh20Epx4oCKQwckjvvurQf6Hrcf9c5Dx6mBOQ9BhjULjaLbvBgQYrjT8kgm0hYhRIAzWERypvZ4Lw5zN6LZrXdiAcIg6NVBOR0xitnUwLyskJpG1DZQi78AinELv/BJKTqmsHZ8Bymp8BIWdBAGqxWsmBLgAMZALlmNioTr0Dlz9dAhABCOzWFiC0EgCOuXebYqVabtjZIAtYIfSgREBVNrgzCBEj51TF59ZyAgRBEtal7zBUXR5MNKVbZHXHZSraFosBT0l8+mrTHXL6ypd521yLFIRjk+Ibp/H3D9F6OE1RqneAYCLKdz/pZ1ZZEyRLZ3IkwA1T4HwAMswf3LKyyGihw85fFxZol1Qj0Fe996vRaK3gKGU75bAOGppxbawXJiBc1wp5E6iSC90YNVWvBOaG6MwJN9r5hf+th0mOykdQjxipoQ/E+QvuuCJwEIMqVCa4hbJHcZ6R6RKEOZftJuja8V1vOJMDk87gvpQvEESZk5I6eW4vYdAdGrfrYJD4XqOQfdaEWLMHvkq3DA13Hfsn9FVSEygCvWHw5OvLCkw6Y2ofl3vfPwfZtFZhcYWB7GdiWQNU18obG+H9fhEk3zsfRNyxw5Y/54Vysftd83PmPi9DMEhgbPqH+WA/QncMcVIcywKi1CUpbNcqbFUr93mZK2Vx9edmusEhB9WQc6dxGK1dNC34Sz2CZlAc0ydPXGMGGnVm3cis1sdvJehTbSNkYLSblLS8BlaeIr98FkFaAsW7UEnE9gxutZeC+/6xpoK489pRTAesSirA0Gm5GoFw8BG2ZMJ2M2FO1k2CiJVIu7Q8IkbovNFCPQjDY9o65enlhFvLgqQVoBecqLd6E5FfaLiwC+fhB7lz7EU5mSvqksEonb4AugCrUPIay6cxp0XkhexQCu41VZrDCdDSOibF2YG7StOfcdy7nDRy/tMbbkoIqJQQVQdvWza2yYbV1Qpg4r4a1C6pYu6CKSXM4+GJk90es6ps0y6uhQjbENxj++gVQ1NKOIthoA7CKwMMdNojAS3TNoF65XjFGFwDPPgXXcqpGCXZZitsWelS2sIYWQIRgzXkLFn8jITgMUuKEfeiM6gvvDKXMFE6aU3Nslfv9F9c1KnjnCqyci0wuzyzzRuKmbO89AfJuuMTrusnXN2XeL/ct9yDJmyPAa0U8j0nF7NizLQQFsxsbDTnAdeTpSgdM7eMiudxMpoHhGXRdQ20uofFYN/qfZMP0I7+zGEd9dzHueudCd57WBkklhxrehGooYCCBfqSC8pMa9dFA16MMfMTLThlWz0X5qqwtkOTVU7nP0Qdi2ypdhxtEdB0YPBBs9D4IlwgZ4Drlu1sBErNhWQ/Q/VdCXvbBN7cfamNZ2cHafdoBWAb6w69aznWGk1s0C6iWUbjFlkYGcwFSDj20fx4CnARERROpglfx2fZEkeqVLRgAKiWMklRjv465ejk2nR4AqtBmS6qL4mRRpPILJ98iUPGeaioCWIrYQ2/j53r9hGz8iRHY2MHoIfXIdSQNzbi+PpDmOFWRATzQMhqNW9nXAlbWz/HqMsfIBEySeKiJIbUAkaMv4Ak6nMQl7cnqC6tO5RfdI3y3hp5mYYqRVRdX434OwUhRTdUGREF7cFNUMYohdRHshvZG7d7RYnBNIAZrRRstATvjl9bcoicMu0Dt7im8D/f7Qfv3IgAg7UBlse/COqPn3+Z3G7JiIbCTkC/hUCB5F3XGgMmFNWgi8tAToCTjlAN1YEDVonKlgMUqgNBnWzpqvn1HOj35PBAJ1AkFDH9QofyURrpNQ5VzNBoplALyjB/l2G8txYTvL4RSgE4M2wHt30A6epANye0KLBtuo5g3gOEPkjMsL233KzSVMwhrjrDsUZcdiCpsW5Bu9wO9SQFt2IC98gTXA/DnxPk1H0ZBKPQ0jtmSVxSaIwAQUHmSMPzP5GyxQEBejpPvOpFJwwSghdAKmlKK9umuLDYmTYnLhLGjwgHc1RUAmiLlMMQgGkZP9x6A9joWDKl2K3cAY665qPAytF5EFScj5RkqN4EXGBKVK7jk0C5mV1y3sEkR2xQ2o0BVFY+P/XysAiyCgrGfX4mxn7eegKTg41mFJ8HbaFFsExVF6kZ8Tph+BrapaxZX3ffVF1Yx+Xy2qZl8fi0qV/zuAJOVqdNrDlAV1X4OaBVAiNQV2QjZZ6JCFongbBhdTKfAAHztvGrbOFvu1lV8DblmaHAtoENUWu43HHrKldHKCLUBgxFADPqu6GlJwT1HKsSwveEx5dsVslA6YxY8jOhvSh4M3bPQX9eFM7AAKhm0nsMNXsSRTczsyjX9WGbKHHsK4W0FvyUV/CZCr9OwXEdeWNIBU/u4RLGMAGyZkKOxn0Har9C1tgv4v25OhJzIUlISJHMaGmiCeqyCbDDlgTq1K7GMqexkgGNDpdutcbldjdUPyUAjMwzbwOfBAKUtfInSVr/6lWTFpsxeL6VtQeNloLGDYi7R0rvAk33gfZN1w60aGyMVBg5UzttPVvDR5FgPRjQZgGXWCsGQqPyagf0PAdSfuvpUEgCptg8hBFDhBcP/24gUETus6EDhnBBQtdRTYK3a6WHaVa/gvADb6elcVHQDjkcWsEhDNmNHK29FEVgiVUhJY//fWO3l/bYiUSkqsuULgLIoEktJJuzo1mwbRa0n+8I2r15WxeSZARMVMia2rtXLqpGhvYCkoUCU3K/YRrlXMQSi4WMP1GXCBknfKeM93Fx/2t/QhEU1jF9cw7oLqkOr5QKmzjE1aWBALcBHkcvP6ICMDsJnKH9dAWIt8boKwEi28Ytrrrxrv9QXGnKrwvXD+xA2C/G9qZwXbtIOk7CZginHz8Opcu14pwCXHkbboJvGxsAzKS8So3yVrk+saUPwfEL7L3qOWCkAnLN1N7eO7Blpk1u7I/uUEECwgGoggRreRHljF0wJaI4bBGUaa06ej6O+uxhjv7kUGz88C5NunA8AfE5/CjO6ifShiluVkQK6HweUIWs4rhwDIB56SAldm8rMDlUY+CR1AANAWvcD/aq+KiafV+O6LUArbSMw9a2QDFp1Yg8zVnnZJkSWKA4pAwQCD5Di4VfeQtj+d4oD/qXglagGe90l4SzF7VUCBmQWs4OEsC2k+FxeylpwUzQGkrqsejMGTG0+YYuQ/ywmnx7yoUazt3KTm9KKDePdYT/YifqP7Cm+DQFakO+KAK1aLtVOQjUWkYqWWBurvQyuwnt0330jxlx5MUDKBYCVepmd8v3o0thIv7nCYYN42zCtF0cur/GlNZxdzPjFNShYW6Hg/hTZOFLFe1M86U2azeUdkFJ+sr5nEdtTCdCYPNPX7fLyyXcd9IN0bQgoED8GXwjxgiAIaKlyQGI3SbBI57YfqPPktQztx9yrKn0hACrxdUSquLBJwfvq2qztbwTxuWKf5Ziiovege6b2WYiq1b6GOnjPwr4qvrqyz/0sJf1U8LON1KaWYcqtrdKEhTVoy/aFZgJueACcYb4YySsD5AmYoVZe9Z318HhkyoW+C/q6CAz3puTQyHeDE9mdczsSS6cnnweiNOH+j8yE6slARqH+0gZUDphGApUaHPmdxU7Nd/QNC0CkYGxwFDW8CWxPbIBHoLKZN5NynjyVW8+5lPPhkQa2jeFRcvClTZgyDyYqs4Mz+eB56SBPLqV+uAFLZQAphbyiOLaUuAzXuW63wrPlkzocfZ8MMv0OBTRGKQz7P0LPw+JtqKJBXRkF1dBQkmPQKDcBOCZJ9snER2AGRgxfwfVSZj36cs1gzWgfa0omjGD5L3ZTzOoUZgb4f0Wld/9HZvLzsypE1Y4pcqt62qUBmVxfcDuc15+CN7IPYzgFx8L6OXYVnCrJqfbCW7HX2vjZaV4VWAAGIF7tu9V72D4rjnWy5SMWyrJjRVuq+2ZUcd95VQcwwgjfCLpRJu+JC2qYOL/mPgUciYovbBIlDKLuWVTFxPk1LlMALXI/dy+vtoQ32BlBGPZf8XE72yRJyWRZ2hBIudRNQZui+5f22eNyLPSwi9LC6EIjgnrCe3X3Lpv27TXWZkjYvhBEOI9Le97EeZyQWtip0LuPd8QgtGgDFrF5smkbA8p+F29ElxgZvv+cHWAI+gScam94LqFGTIkbFKodQzMGaIBKQfvDvtHxNTrywpPOY9/HRacGle6mjzFlR5/6SxsYNrofUEDeTNDV3cDGD89qOb+rpwHd1G7QGTwAqI/iVDBJAxg4UKExnJdr6SCvxEgBPRtK6PpTCaLKA9jOCvADTNblc1qJug/wE4B4lKWD1t7KGnrqIEFo1xOGPftyzuunM4Ju8oCvDNAYaQ3jC3PA/WdNY4CVK1b5WTsK9ynlnS4gBAECqJS7jsrZs48yBWoqoKF5a2reTwxgSOo2lkFyddqvEZPEjKKEUAjDJShNkfq2KEMlQx7yeAswK9AmRfATSAiwHAsVyIbeXkBTpI4L5cjlNejMN+j+s6f5NDOhKtZ+bjyH1XxFdaKo/8b1taoZ7zuvCrGZWj/H2w2FQGbi/FrU9nASDZMZr1laZTVecK4wWjJJi6y+kMtNPq+GyefVsPqiqgMREu8o2gIJjaRJ2QCgxbYpP6mHnnKk4/Y7RmppraVv5LrjlwRxlUKVlCZ2KgkaJoyUe25B+5nN4XfivvOqTvUXgS4LOIrBUSUemCIPdIohLJx9VuLrC9mdkI1zwC7x/Uip/x/wpgSOlQzfdfldKh7vInAk9WrAlIk9+Sr2t2CfmwvtEIJAAXLBFtqh7U12qqPm23dEEdEQQ2xHAGDLli0YNWoUNm/ejJEjR+7160/8/kI0GylMMOhxkl3A2Fx18v+Gf57lziEA9W1lYFsKjMicmg+WBdINoPIUoDNCYySr0/IKDwr9f5ej/NcE2XBC9yM2SnrO6r7yFlbVkeJwCVmXJDH2g5oDVsRMU3M4h18ob2a7LGPjuyQNvv7g/nwfwx42gFJojFDIuu25w7ju7X/HK0dTkdAGzE5BtcZS8nYmnpHxDIhykxaVZekKe48yOsMxYaQBlAyrFklFk6CAECXgRfOnqAlVEUi0+aVR4CnH1w6+t9UjtZHAMIcKk4gyDDjdPgGThfN8Ulw+FgbjPOrCGrJhpi2p4dQxEWUDG+pAYePnelnVZwGd9J+ESBjX1xepdDb09rIXX0iikMJ9M6o48qKaT/EBm1pmYWyEPnF+LVL1TZxXixiKNUuqmDS7xjGlpEzo/Qew1x88mxUaqEf3GEjxUUXhJ4LuoaIKz/5OnCrLTtzFZL5kJ/4WtWHUCEQhMRSB31u5vv0dFO24VK5cah+npssVoAn3nduLcRf3Oa/P6NWh4DoW/K2fVWU1bOH4jvrGqZhVXK8cc/nyCosXiSFlyt7wfOJ8flbK8BgnfeoC/wb9lHfzWJR3MZASY3xx1HHPTvO4J0DPqSMDMBU+g7x/EBuXzHpW5wyZl8767btRGf7MYzHUtzXxhdfe8JzNb39L0mGm9nFJEoOenrpXESlC97AGurobUIqg7WC54Z/ZVmrSjfOx9j1z7TjAf/WT/GNTxnrj2VVWOuBHLUkRY0pAz/8laBycgRLCwMGE/pfkLh6LG9zsp6kgWv0BPn4UIDGj4NQt4cCTdQN5SfkIwyUFEAHWAFdnhMpThO1/xxHYxQPNqXdyQDWVHfyUU0HpzIKegnca0MqquNW4Y5xg64LzcmOwYeuUNgTijMLd/xaIuRkUaAekXAOoUKbFcrldw9vcUMH2y50eqvbkf23Bn1UHSo4/sgbrYy/pw4SFNUxYyEAqbIr7h3yfy3VJ6raFx17a523V5PkTPPtk4lsYt5L3b5jeG6lpw9sTVqolaKe9P5lQJ84rpDcJ+mDSnBrnnwMiIAV4EDVpTo1DJoS3KMyD3bf6ovhcIGaUnCqr8J4VVWpFZitiawK1uFOJFl8HCp6PsDnh8wqOqVxZ+8igb/PCuQkvUgRIubaiUKeKAYUDUvBjhLzbRZWeME1r51dj1VoS33fIJlGB0SoGAXWMnmXGXNmCdXBYhzC5AmgBZqryCm+Uctw2U4ILLhyp9opMWDHGW0deENIBU/uwnPBfs1Cvp+gfKGPEyAGMHNWP7mENaEUY6C/7mEgFGXf9Egw+1gO1OQUScJwpxSBF0sDkXZw7b/thCvX9OWYULEABAd1/StH1qEblCYWuRxMX/dy5Ads3J7U5/dyAnzObJMavEn+l5xGuN68AkhxZGW5HaRsxY5Vw1PTyNgMotulqjFQobQbq+/trqlxxfj4DqEz5rPAZbJR3D4hQmIDEnsjYNDkAAhATfA9F6hCGRyaqQH0W2zDt+Lm6WFVRjKri7CdtagVL7lpt1IRxzj8u4+2nZB/agqowebIpEeoHGDRGm2iib51QKdqpMuU9A+228Zxe3ieshC0eAipQENCTOBl3KEddyMBHQLok6pUAnbLJ5DxxXs3VBdiYTcSxhtYsrrrcc0U5em4NR18Qn1u0n3Lvv7Ks1U4enVP3tZtklV/cyGRdPB6K2CTtSJV034wq7ptR9eo54gWHbvCiw5Tte5SSVcf5Z+gYmfCZi0foEM4VZBnZFgPt8HsbRkw2MWqPfgJhn7dT+4ndU9EwvAh87fXduia0d5K65P4t6DIVQt5tYHoMg6ouEz2X0MZQZWyrJkGIlZga7CXJSe321pE9Ix0wtQ9L0yS47wNzMGrEALZu6cbWLRyWd/u2CoYPH8SGD84GGdViKyXqJUoJyVYNZRS6H+HBIu9iA/SkzgMnJcDg3zUx8He5i9w7cIhB/UV2O9Cgsb/xMaYCG4KQVWjJ5i4DDuDAk5wfujyLHYOz6SAfe0pUfZWngBF/4oEq7VfQdZ4YkoZy9k5+84BQCajKFLNVAXsl5yFTwcBOUXwmN4kAbrCNJrEikHX/+kJtkx9LGce82JV/qP5ow1a4CU/a2kbaKu2tKpS9IAv1uvu2x4KVenjZ0K5qyFuywKyoihIPPiXBYMW1PGcGasP0XgegVIGpEtAXApjxi2tR1O+186qccDdo19oFbMtzzyL+nDSn5tLFTJrDqkAXOiEQUReR8ullwva4pMiu7wr9aVlBRT6MgrRrzdKqB2SBF1kI4kNAEbK5jvmRRM9FsFKw1WFPR4UN03udJxwAp6pzrJeLYcUVClh1wLcohWfv3o1oZ7tnWABRCNpR6McIWLUBqmHOP1KII44H1w2PieNMEmRdcKDMMqcqg2NpUbK/CfubqR+YR3Zd7rdiRYBUNoyQD9vJamoPygvVZirLMvz85z/HF7/4RWzdylGl//KXv2Dbtm07OfPZkw6Y2oel3khx9A0LsK2/4gagNMlhco3caEy6cT42fsir90TyRsIJgXMFUyGndku3MzgZOJAH0dJ2HhiGbSih+y8JoICBF2dQhu2kNn52GkgB5Sc06i9pwpSAgYPZvqC0DY7ydhOkU8/BM1R2MEsafgAzgd3BH6+sghIFnRGSBqegEc8wCbXQHAE0exgAVv7KNlQS5kFnsIyUXNfbNclkFK1MxU6qqT2QEiHFA2jK1D6lZKOJw02SjtEJzwkYKi+q8H98SGyXnGF7Xpg1ioAH8N5Ywki5CTxcjvt2xCwVnyfMU6QSlDoioFiomlSkcTQpOTsyV4+ogywrGbJQ3iYLfqK25x55Uc0CKuWu6dg0568Px36EDM+EhZ6VWje3inVzq079d8/CqlPlgQIjdDADNXEB/z9hUc2dM3EeM00Sfbz4DEXtt2Zpm8TFIvacKefWvHGy9iyW627yIGnd3GrUv8K8tUulwjv4I/SeEzlyOXvQaas+v3dmldkoBeQV8ucrf30XoqEdiyO3JaArBDvCbJJqBcKFtrbUFR4P26Pic1qAmVw/QWQYLrGtXFH7PWSvMmt24FhDiYI+oN31W55rQvxu62AxqWE9AbmILAZJIc4j+iwLkYbZjY2KD/l5IA888ACmTp2Kd73rXTjzzDPx2GOPAQCWL1+O6dOnP2ft2qU4U5///OefdsWnn346RowY8bTP64iXNDFQipBlCYYPH8TWzd3OsFkYiEk3zsfgQBld3Q2fZHd7icciy8zkXWSZGQ5RIAPJwEFAY7RBz/9p5F02J98A00nKsJt61xMa9dEE/VSKexZWMeZLK7Cmei4mn19zoAlkjcpFraYY3DS7gFKdY1EdU7XGw4pDMWw/lBMaH/vZGhJn+0CgRIGI0P04of9FyjEYEh096+FQCSD29Atzf3k1jIIiQrJNoznS2MB6BPTYBFoAXKypHLbBdiUq9j1JMOmIELwhOgGS18p9J8AFzQIgLnfR/FKcbOwzcpNscVVfPGfICbwAxIJmxOfwXtKqlXmgYJMbC+p3HkuwXmAUnBdcVyYlB6aculVBIehjMJAKr3/fjN62t3fkRTUH8gWUSTiEkKWasMgDlonzOR4VqeBW2jAd6y6oOjsrSgDklslaXMWapdUoLpV8Tppdc30Reu25PrKbi/Nk+8L9r3wYBCBgnOx545fU3HcF+BAd0g7j75dSxPdFDKhQZpsnKH4V8wrFWlnFCxFXX2Fe3TCNjc/biSlT/P7IjUv7Cu9E0cutoB2OJHp37LkKAIRhC0Cg2LtFQErOCYGhZdIhYCcw8E8HbDw7eU8FPMlvwcWn434UECwLxSMvqsEc5seLFlVtR/aofO5zn8MrXvEK3HnnnTjggAPc/ne/+934xCc+8Zy1a5ce+znnnIMXv/jFSJJds6x78MEH8Y//+I97HEz95je/wYoVK3DbbbfhoYcewg033ICTTz55h+f8+te/Rm9vL1avXo3DDjsMM2bMwKc+9ak92q5nS5Qi5EZDJwbbtnaBSGHb1i50D69jcKCM7p4GiOCAVH2ghHwwRTKgQQnZFTFBD2qsnVfFmMtXAopQfoKf4+DhDegtKZrDgLyHkB/QRPpIGdnwHGpkE7SlhMEX8Wikmwyu0K0wcV4NCTHASbcxe6SbNqJ6P3hQNsyCiapDbDEkPEJ5C6vxSjYxsiQ/blaArKLRtPuyLvYALG3jia45jM/jNgHKqgnzLsSMTM7ef7rBKsFsRM6ejSkPlFQyrPITNqpEQFNFK28oH5WcBPSImMBbD/ATRcEgm1msEGX4f8mC1lBFpHLFRYYK/ikoOboo/MwRXCqSIaqLmCX5DNFH0La4HfYiBWPrkIkSY3OA1XlHXlRrAUvjLu6DzhRP2gn/v2F6r7OjWT+niiOX1/zthaCozW1IO4R1ErWdgB+AWaeJ87h+8QaMEg3LQsXm65Oq1yypOnsq9xiCR+oYlXAyF9tBq9JbvYy9CR17Grj4hyCheL9Sjytr66OwgaG0eQekTt1gxhrEgGlsrc8BNmeErdkZYMP0Xhy5ou//z96fh1tWVefC+DvmWms3p6lTVUDRCNSpAgEBmwS9PyVq5OrFqPfGxNxEDYrYI41YDQgoivRd1UFFRIOAYpR8+WGiMX651wg2xCY3BsI1IF3VQZCmqP40e+/VzPn9McaYc659TkEVVUVRwnyeXafOPmuvNddca6/5zne84x3+uAwg3Oz3WHx4ufYeY8Vfiyf5HIB61p4erl/sLWOlQNrv0uniJgAvICTP/PozPP6mJ2E/qS1qnGQzS9Z00FY5/50uRiyyTSZc40QyBgmwrfgEnvz8dmSrQKi244Db89ld1W677Tb8y7/8CxqNuuX9woUL8dvf/nYX9Wobwnz/9m//htWrV2/Vq91u75TOTk1N4aUvfSmuuuqqrdp+9erVePOb34zXvOY1uP3223H22Wfjox/9KG6++ead0r8d2V72j+fgzv9xHsrKeMbJJBbtwRxEQHsgR2e6gcQ4dKcbyPMUtpeCOgln7RWiFeoamAJY9PkVQOpAIwWaGyTkt6YBO7dEOceinFMJM7AENFKwcaVqdDR12gHt3yYwYpNgeuI95RjMpFP1SaZqsannS5aMobMgTA5VkzP40mkGRI3N/GCyGVA1CPkcZslKBWlNoDcXaG7i2UNF9N7wUCh3TYXW80+6hKTH55B0DExPQnvGgUoT2Cl9ujctn2fKBY/JAEgskFgW+6fOa7B8AWB5kQOcRQjb6e/eJDRe6YLF59Gh/cRhKXhe9dsm9DcJrfodkWP/KgNv4un9qIQqof59xkyUByoRkOoDKTVRtkxccfJhHFalEvXaZ33hjxdeMoYkpwD8weDy4MvGUDX5fnjhJWMBJNtw3QEOjcWmkDqxqlXCr8/lMN+LPjVWY0sO/ySDM1OKgF38qfpr/cX6qP+8WBzSY4aF+l5ALQvND5sJfT78k6EvM/RC0dDHYUAfSY5DYC7sGwDuOzP4PQUA44JGUEBC/3VSr6+4wHFcC/CgFSuDtipDLTO03xbAe0dp0+0ItdI3WwL6/YA4Bs5+HFVvZ1FngPrvw76mIcgXncPauaoVxkrLWKUdfmaYgjWWpuJnnxFvPL9+EE2ohk7LIRf0lVvqwE5q1m2vbuoZ7e4OadZaVNXMWOrDDz+8S6NhWwWmPv3pT2NoaGird3r22Wdj/vz5T7tTW2pvetObcMEFF+Btb3vbVm1/zTXX4MADD8SVV16JF73oRfjABz6A973vfbjiiit2eN92dLvjLeezm7kl2Cpkf3WmGnAO/LMiTG5ueUCgISLSzB0JxdgMaGw0PImXBvlcNsJsbAbGj/84U/YlAdMJRr96KWxXnojDZXgwRwyGr7Cuk0T/hAsOx6WdsJrOJvk9fnCxoDgpePskdygGCVWD+1sOcJ+THrwmIu0w0CIArY2u/szSlaqEO7RwLAnwMpLlRw4whQl6qSjF3HmgE52MsEokIUDTKkEDJWioYO1V08Jl/PKt345Bl8hR5p6LQFhtm9oY89+97YKfhKKZJ/4Mwr5niND1vhAA6LMh+7LuZm1P9rDtn/yiMScJG+m9ctCKlbj37ABODj1vDPeduUQMK2Wil/G4/4wlDJoicKBg4d5PLEHcHIXixzoUh32GwZFm9JGNHND72I7DzmVwo6G6Q89jwHTXBUsC8EHEUs02VsJSgMJPAN5DSu/P/7xkSQBRJgKifeFWfd9r/mSs40seM1r3nbkkhEsp+lxkSQEwI7XFRn39V8CXOQ6Rxzo7CYP7hIZoHzVRu14TYqDqwY6MRw0s2XDeoD6n96hpxmPVQP06yHnX2DtE4y//J8cspXrt6eJL/aj0+angd/Wpy8KJWA4Husz5xWU54GrbOQPYRt8Ffb7t0Pbf/tt/w5VXXul/JyJMTk7i05/+NN785jfvsn5tNZgaGBjY6p2eddZZmDt37tPt0w5rP/vZz3DsscfW3nvjG9+If/u3f0NRFLuoV1vXXvydT8PIKjBNLUxm4azxjEazzeyRm8pgi8Q7czvjMPgoh7h0xW9Tx6G1Dez611vYQ+/gLrp7OIzeeAmDgoYFzSmYtcnkqRM9mGxm0VpHfrXsM4QcML0/P3mqFlAOsuAznea/px3eVTbFn8mHRWQOfiCSA2xGfrt8BAJ6+PN3rlzCTFgDyIcJ7bUOvRHyD+10CiGzJ3qI1577vWAk6oxoPXSS8b5IgIb8XPwsJAenIT0HkHFwRQLTrIDEgTJmrZwyQomyWs7/v197FIMbdXGfDdB4LU7tferbAJ4J8+xX3995I/BxKgClsmuzgKnZ5tu+ebQ2KerfbZiUSL3AosWj1tkDRGOSQcJ+DDDuP32p78cLLx7z+7rvzCV+P1SJt5QTw85IKwXMnIB//RlmQ2zKjEQMEuJJPQ6zKaDQMKAChFoWH6LPROfuAUSctBA9YX0f4uP3XXPXd3nVgVzDzzGzxPe8Y28usfzwwEwZJMsZfS5xsA0Oe6s1whbF4vJ6YNnSOsbvA3QzdkK8SLr37CVhXGe5n/x9HYWB+4F5/7XtPz4AX5kh7nucjdi/33js0mkxDRaZQHxsf+0ssX2H3s+ivewni0mYf5cy8PzV+z8686R3Utse8bm+dre2cuVK/OhHP8Lhhx+ObreLv/zLv8To6Ch++9vf4tJLL91l/dptHdCJ6Ck1U4cccghOOOEEnH12sA746U9/ij/4gz/AI488gn333XfGZ3q9Hnq9nv998+bNOOCAA3aZQ+whN5+PopOiNZijM9kEHNAaYsNOIofpiRbIONhOKkJmXtKaDof3ki7BJUC1uIMqNzCpFfaCfEkTW6kwSMCCNTzx9oz4OPF+m0+YwETJZOlSBkDN9TyJJB0GVUkXXjuV5AKcwKxTNin1/jRNOwGyKYdiiHzmoW3AWzdoth6I95NNOUzvQ36y8lYM4fQBCDVf8bGcAaYOkJkm4ZXlltzMfSFhcjIZOiSy2rSSAUjkYEuJu0i5GR9Si4Xs+jsIZKxnpZxYOfgagNFE7ydgct7DhxIX3vcTcTjh/m8xUdQPBU4x0JFxqmlDtP9x31H/TL8mzLuLR1mUscZFwbce8P4zGJQcctGYn/zV6V7PPxE9y72fXOK1U57BcaFsiA/rxcCqH6jomOqlqcL7dWsA+bhh9ks1V97+w4VtauMs3wdlNtRZXYsq15zMo0yxmUkT4e88zvJ+bC6J+rnUrC7i6+/HgPw99MAyLtNDBc0KCPhk2BNs8WdXBiuMLQEup+dNNUG3HteHd13Un75WA7Hxz76swNp839/v/gzCaMyB8IyJv+vKlmqGsTfijJ4lAHw9U0A89hqA6bLezCUSQhUAyZm/DuMfOv0ZqZqhx3j3re9EY6jx1B/YQssnc9x4zDd3Owf0TqeDm266Cb/85S9hrcXv//7v47jjjttpEqOtadsMS9etW4eTTz4Zhx9+OPbcc0/Mnz+/9nq2NeorYqbYsf99bRdffDFGRkb864ADDtjpfZytveL/PRsv/e45aDUKDAz3GEhJ60420JloYnpzmx8e5DBnwSQXNbaE5l7TAAAqCTYLqzWTWv8wMollPQ8AVxjvsA4ALud6dEicN8eEJfT2cOjsG/bhpKZYa60AqS6/n3Th9QwuEaNOudOyCaBsoqatGHjCIh8mJF2HJGc27T+u5BBQ0uWHXsyMVE2m222T962+MbYhpW50AiIWIOvffB2ySNvg0shLSpqG9UAAGSsAFKgk/Kmu83Bcx88JCNXmyn7NE88+zgr46tPU8EHhbRm0f/UVs14HBEATMVO15uQ9rR8okzNpiE/65dkxB4yftDxiCRxUX1UDUrFYPZoga5OX6tkssypxqCrerrGRWaekE0JwXgMXl01xEePUd541rVTM8ijgku7++jPiKUV9up4YtChg0c+od1VUnNeH1xK+r/Te8uduORyo5Wj4TXhmS48xKxlAco0U7MlluO+sJTyWwuBpc6mreS3FuqsHli/1CRSx9skfZzZwI9st/uxKD6x9fzWkBwlnuSj8pfepCefqao76qM8y4atTb/H1o7CN9sGmDHLjMezfh4v64MOUERCvhVRlYabPDwXWcV98wol8l9IJCt9TYrbepiEMOv6h0/F827mtKAosXrwYq1evxnvf+15cddVVuPrqq/GBD3xglwIpYCuz+eL2rne9Cw888ADe//73Y++9994iKHk2tH322QePPfZY7b01a9YgTdNaSmXczjrrLCxVJ2YEZuqZbolxyLspqsrg3v95DkZvvMQXxh0Y7mF6oskTJQF2KsO0UuYE5L8dFGEvP9jowGnA8hPNiejaWZIQFECpY6YkcVh93FkY/dolcCWHFGvajcSh9YThB5SuqMXrBY6z+e66gEW/2QTQ2Zvr8VHOf2dTPN6ONvEDrBgAWhsZ7JRgZkonm6oFH/JLpx1sJjUEB/ihWDWjh72s7P0EKaGzw84dAwRgUcH9dgC8DknPUWuYOYBALDwHj2dcoNj5ZS7BZBVbORSJdzNXwAIBoy51AlQjtqeieqFiF/0Ncg6OQFYmNRCc5X3EgvJQaDm6ThAsZJwPCc9gL/yh2KrAAVh01YowfjFoQh+Qwiz7irVe0fsvvCRYE9x/ej2LT4v+egZLQ3mzALXDPjPmJ0JHHIKbYbjpx4V/+KLHJnhH+eGlcM/6id5weEqd1g+5aIzBDVATpfc3lwLQcJPsz4fAdWJ3UYgPDO7UikH7U2PR5P+OxCLBsS7MCICwmaudT6wXAhg4aW09v3+t/ZdG78Vj1zc+ADB+8jKMXn0Fxk9ajtEvXoHVpy7D6BdWYNzriPqOH/fHyQYR8xpYyvpnYzbRxc8VirYhsdFIFeiHfVLJ10G1n8qU6frGFNG+hQ31wCsuzo6on9qvqAA1J8nwH52y1mbXgqjtdTHf3RzQsyxDr9d7VuKObQ7zDQ8P47bbbsNLX/rSndWnrWpbE+b7+Mc/jn/4h3/AXXfd5d/7yEc+gjvuuAM/+9nPtuo4u6LQ8X/5p7Mx2W2gsga2MiimM4AcTGbRanO4zzkCJlO4hkXzsQz5XAtkFmY6AZVAew2huydPqtWCAibjbD1bGQnliV+VJWZeHMGVBpRaBlIlIZlMQwgK8Bqs1uOmlu7tDGuiqmZ4CLaf4JVfd0+pq4cQvqmaQGMC6I1wyM+U7Bk1sMahO5+QTnMmXznAIvnmJg7J9eYQG/AR76e7Z5gcYu2LZvMplQ9wH6sGUA7xOPGbvI0TNohEVKoaKpNZCeUxk0cGIGNhKwPbkxNNLDNApQlh1jh0J8wXZU7CfCZk95UUQnA6ySUurIij0JsyDb5FQFDbrDoWnXgkC7EWqou2j1f6sR5KQxk+8xHhb0A02SDqjwtZmDpZ3v/xmYBkNl2Mej5pSRgFHt4UsY+JcaYe5otDjbWCxwquSMrNiPDcMx0pM2WHXDQGm8ze3y21wz49BlPAe1L56KtO2AqqUO+39kcZtpq7eQyw5D3dpxpvPrCcQ3cPRIu/g1aurANdZdQkExUOWLWE7RDisB6Pbfgu1X7XpuNeEcZPXoZFn18RgecYjSHcPxW8x53fR995xWFnGAT/LX2TuOCyLzGk97QTs0zZX9UAf48r8o7kmoBSA1NaiN2IHYLICWwKVIMWyZSRbZ0vyg6SZwr4PgGA0b+6HOMfnAmknskw3zt+8K7tDvPd9Pqv71ZhvksuuQS//vWvce211yJNnz2mXtsc5jvssMPQ6XR2Rl+esk1OTuKOO+7AHXfcAYCtD+644w785je/AcCs0vHHH++3P/HEE/Hggw9i6dKluPvuu3HdddfhK1/5yi51Sd2aNtltIBVmpOwlfuKEA7qdRqjp5gAznSDfq2SA4Ai2yZ/r7gGAHKoFObJ24RkNk9gam2AyBgeuNCAJ/TkJh1WDlazIhCEZqjyQsVmdTSjbooMqWXQ+tR8Aw6Aqyfn9sq1eLryP5gZ4obFNgbLJ5/Xv1yxBNiXZfCShGVnxW/lZCaObdKk2uQOySk0dTBlNllGWVZgUEB76qQUl8lKxLyF4SclqmwgcAiVwhl9mWYyuAwGgVgdPj6dhv9jpXHQW3iDUxJ+PAVFgh7y1gfw5lLuBL6kTh+g8qxSxHb5FYUMvII8yHD3DJRNLTYekzU+KVGOVNMwbWyMcclEAT7MBKThmodKpwEa96FMMrPyxY6Ag945m7/ndUKjPd9i5YzUWyAOsvnNQsHPv2Uu2CUgB4VyPOJOB1F0XLamFD/V+01BjfFyAx0VNOiGAIg6J3vsJzmRUV3SqeKwPvnwlYJmJOuiKlfVQHlDTZHnQ0/cdWHylhvVmX1N7HzTfN75fR794RQCKxPfJqtOWhhCf3NscFnVek7TFMdR+qQZKAX5UcDkAaRd9J+ABWpIj3OvCWMX6ubsu4vvINuCvudYP1b6ZjiyeKt4XSVWFB5YthU0dbOo8qJsNSD3fdn77xS9+gW9961s48MAD8cY3vhFve9vbaq9d1baZmfo//+f/4Mwzz8SnPvUpHHnkkciyrPb3nYluf/jDH+KYY46Z8f573vMe3HDDDTjhhBMwPj6OH/7wh/5vP/rRj7BkyRJv2vnxj398m0w7dwUzdfjfn4uiSGEtoerJk9oCSBxMImwJAegkMMMF7ETGK8+chePtxwy6CyzsILNRpiWTvQMocbB5Ako4hsG+RA5VJ4VpVLA5My6qp0o3Jz5c6HUIkg1kugbNdeQBkTOsicpHGETZDKgyIWg6UsqBgHwu0F4DFOK20VrH/49dj9trLaYXGJiSQZq6DZcD4acP86XOl6qBPNjJag0/nuwccRjAZY5tDQTgUMGZgRgqYbIKJhXmqZsCaZzWBz+GPnZFzmulnCW4PJotXGCNNNPPr7Rjca/6Tbm+Y8jsEpdd8U0ZK2XlVAumWYFJtH/pCzRz0GGG55Cf8GfUWJP9SW088oyW839TGwq/PxexEHGXI4aTSgRTS5plUuwFIfeLzhnzoRwIkK+xkI71S2q+eeh5weBTw3MqJo+HUf92yIVjuPcTS3ymoQrkt7Uddu6YL2+kTbV6INZgaSFmPfah54/NBBgyBrWSSHKe95yzBC+8eMwvcDxQsiGMetDKlbWoccySrfrYUgFPwKrTlrL33GwtBt1+gQAB1ITxDy/H6DVX+Ovef3/WmM2KPKipJSlo6wPoXg+VavIF6sBJzldZVkf1MVewZAr44uz9TNh/Xsrmq8pGKaUQyRvDAsJK9qMRcFYSqgGLpEszQtfanklm6i9+8G40BreDmZrK8f+8/sbdipl673vf+6R/v/7665+hntTbNoOp++67D+985ztx++231953zoGIZjXT2p3bMw2mfv97n8Rkp4mqSFAVUexFJqP2nC46E82gb/rSFUhGclQTGbMfqUP7oRTdfSuYroEdqICGFaYkesJGK1VmpIz/CRWmi44KHcOai0KfePI5CzTWGT/ZNSb4by5hQNXYzGAqyRn4+Krqjh9ipgQakw5Vk8uEVC15tibAvPsrbF6YIOkCjQmL3lzjrRVsxuJzK0afINEymAj0gTNvauEWAYVOM+MojCuaFtSoAuMjBQSVpeLx4NiMAlBbJmEb/YxeKxlnZ8FAyqeqg8GOC093BXDqPVXTQqmdQcwOiPGoyzjLT4GvD+Fpn10ALT69u4jCfdE94DVn/feIgrP+MI5+VMBUHD6Ma7TFWh5tvsAvop+aFWcZeBxxJht3ajKDaun+85I62HnRp8Z832ONzT3nLKkzVlRnRpStvO9M1kndd+YSHHLB2Bb9jZ6qHXpe8C4C9F4L9ye/GfpQq1/o6uBOwUMcvvTaHj0PXTTIdynWHMX6uTistupjS7H4cyv8frbY5H4YP3mZr5qAWJwtoKqWhap/k0SHGpsqmjJTBjB179k83l6np98xOT+XOR++XHzlylr41vulicRAF3Pou9dMLg7n8kxSz7q7z5s5rkAAcgzIHFYt4XI6tumw+tRlbGCasS7LGaCaU+LB950xY/ieSTD15z84Htl2gKliKsffvv5ruxWYera2bQ7zHXfccWg0GvjGN76BH/zgB7jllltwyy234NZbb8Utt9yyM/r4nGrtrBCRePREJAcYh/acLpwjNMUaYfE3L4JLLcrpFCi5RAqMQ3e0AAgwPULr0RSYTkCbmZ4hcjBpVWMunJW0/dKwtqog0RBZnkiHSqBVMVCJVofKvvTm8+SdD8vEV3KZGStZWVay/lwS3tOXZvGB+OFnG7yPfMj44+RDBtmkQzblkE3zNspQmBIeHGlIyotstTo8BAjGTA3JuGqoDYArRKRf8TiQcTDK/oBBp0lteM+plsqJSF1OKnE+VBeAlMx2OhHJ75pFSXERY+kfVcSeUJHhJ8SZ2RQE6hmgCAVmXcxYyESmp6tgzsVhRSBMhP0tCvtQbHAaveKQYPyxWIReS4+34Wcc/tPJDuDrdcgFY2zwaplFuOvCUAT4iDN5EtSixTEgoWiYD/vMWAC1iI6joDoJ2hf1K3q6QApgMGRTXhBUbblHo3CSS3ibez+5xGcrkmXApON16PnMkql9g5/wTei7/+5YydqLQ4IUxmLVkqXhOy7ZeKNfWOHDclu87lEbvfqKAKQEKCmbOv7hWaQSes/F37N+oCT/j2sPKojxWqmIIV18JYfUbOZ4wYSo//o1Iv6uz7BEUHAUMU4zxhUiI/DjIs+igtgiIgVMzqW0XAqgIt+P2YDUM922z/2cX8+3HdO2mZkaGBjA7bffjkMPPXRn9elZ1XYFM7Vx0wCvjgp+6g6OdGGjWnDWGuRdRgmanWd7CbNIDgwscoPWoymSDj/Ie3tyvB/DJZJGBeeAqpMGPyIC9MnncsP7UqBgOQXOFSJQr4jLsRgH6nIdwIFHEmQTzEA1N3AYziUc3nPEPkJa8wuWBets7umQFIApmKHqzeEv98iDJSZekHL9qwJobraY3sugajADNvUCHi+byYO2EWl7IiaFxAk+6fJD0LZcYK9iB+c0QgEEJM0KSVqh6KWAA7JWCecIRUdjhvwkT1oVj2Oj8uweHBhcaSgwAibx+7Umk5RTTZURV/pCxRwKOAnppJHJBd4o0KUskOf6gmF/auYIoC5EF5H8DBZDJxTw52O3+1pfo5+xLssbd/afXnTKcTglbv0gTAXEAOtdjjyDWaj/vDQIvUEhJAjAi9df9Kkx73wes1c2CRNv7Mi+o5q6sXtGFMG1/YUXj+G+s1jk7vWGGqLSMYlAprJanjVEyDhUgFwDFlU4pjKxOqi6XS3BAfBgZ/UpLCifGXZ04drr9aFZfpe+K2MEIISVBYgpe2mqcD/0M221vuuvFWClSLMyXf5esczGJ70ovOzgEyPS6SgxJmHNnIIpZfSYQZTvG/Gx2B2di8THjJ7VkjuGmbvZ2jPJTP3ZP79nu5mpm9/w1d2KmVq0aNGTZvOtWrXqGexNaNsshX/5y1+Ohx566DkDpp7J9rofLMemzfMZRIkRZNKqvJ6m123ggXecjcP//lw0WiV60xmcIxhjQ4HcVAAQDGwKZFIMmB4nkCNMLTKoELEhQGAbErCv0mDFgElCWZQwa0UNCzIWcImI0h0vIi3T3uUAPxx780JIL/Zw0Yk26UEy7gCbEbKOhUsIpmD7g/Y6h6phkOQOzhCaGy2qFntmNTcBnb2k20m0+tTmV6Oii4IRwEEhvCerdQCcbafMCYL5ZpUbVKqBIqDopWyUmjjWRgnQrPKEJ7XC8LFjU0sBUp65cpCwIf+u2ZQAQoZdvFJUoKt9lbDvvWdr+RCZTCW0UjMO1c8LY6YreDj2CFr8uRUA8T0zKz8d9YMcvA1HDKD6MaEyJgBmsFYUsRI6gQVNWZ1V8J+x8OD7iDPZZuE/LxUAJJP0f16yhEu96KSs2FO0cod/Ygx3XxisCEwlhNU2c/Jb17bEbh18+Urcf9bSGpDy4fK+TDeyDBAPO3fMZ53pthqSfOElY2LTEYGlKBRIFf++6qNhwh/9wgqMf2S5tztYdNUKD4zi/9daP+idDUgBnrWK7zMP3JQ9Aj9zLOpWHgr4/fdYw82VGIxmsu9SaoSi/h2hki1TkngcISWoWgjaKAo6NQ01Vy3HxsaG71HbcByWtMRJLDlx5qORhZEcfktA6plu2+tivjs6oH/sYx+r/V4UBW6//Xb80z/9E04/fdclBWzzSJ566qk47bTTcMMNN+CXv/wl7rzzztrr+fb0G5FDlRsGLOQwMK+DRquEtVzsuNnKcfjfnwuA6V0SQToIQMOiMZzDrG/APNYENSvkCwoWajfCA9tMJzDrG6KhkQyzaea51RGdCCxUF42Qq4yn+V2RMNBykDIqwMDDxpdrMVKXzWa8vWqjsimxQSiApOeQdh2yaf58d65BPsS1+dprHdKOQ9kiNCYcTOG8gLy50YEqN8NdecY4OnCZFwLXzmtauDkFaLjgcKXYFbg43KVgJHEevKo2SkvJqGu8Ml+uMnXdiAPG330mxt99pnyGvNu8NucoAKkarYAQ3oX0o589k2Kqi8dWMhOnbBqBGScFJFV9Vuwfq0VXrQiZUlJ2aNVpS/3f43BHLRNSu6oMwYz6gvy695NLar8rw+QZq4iV8J9FtK2yW8KKuSTcv0eeMYYjzxiboZ3y192KjipFcM7XY8QTfl/zafc7qzni0JaG9qpwXcgBd5+/pFbA+4izxmp147T/950ZxPJwHOrT6/7A0ugapsz0LLpqBUa/sIIB1MnLMHpNAFJx2E26CCAaH7nvZ3zH9F6QPoTrHN0L0bY1zWIC/v4lfQCK+H0tdeMIsC0r27kZi6ZYIO+kXFbtfjKS4NJ3jlb8qFzqUA3ywJWDzssEYqbQZdFgUGB4V5/y7ABSwDMf5rv44ovxile8AsPDw1iwYAH+5E/+BPfcc09tm8nJSZxyyinYf//90W638aIXvQhf/OIXa9v0ej2ceuqp2HPPPTE4OIg//uM/xsMPP7xVfTjttNNqr+XLl+Ov//qvcd55583oyzPZtjnMZ8xM/EVEzwvQt7Md8e1zUZQJik7qJ1+TWDRapQ8TGeNgLSHvZajyBGZjCjuvADZnQOqQjORI0gplkaCaZtLRdBJQRWiuJXQOLGGmElRDFaghT/JeEt7LLEyj8iVV1GMpLiHiy6BUBNNjkNV+jNDZzwKW0H6M6+xVTRae60OwsYkf8EmX06WTnCnzYohYZCyrx8akQ2t9hXzYoGwFobTN2MSyN4eQdYDOnqJNkYneNiWMKRoPp7olMDAxWcUeWxSBQwmneQG3gggDINIz8YnDM0w+3Fr1fRcsYfw9H8fo1y4JWX4KwGTsQIgE630zma7gtWRNKYA3tbXSMxqmqVkWAEFU7/R9CpOdhj4jBmj8I2zGGAvHgQCW/HnbPhbKRtsoOIpAEFw9wypmqXwaOs1ktrzuSUFEweek+6wBMGm/upxDfv95MRcm1r+bgj/3q8sZdKnWyorrdVwwWdmeHdEOvnQM5YIC4++t62kOuWBsxjjdfR6HIO8+bwkO/8RMxkr9r0KIDp5VUT8lAMFwNgK+QZweDfBs4WUwCNJxGz95mQda/Me+7SPBNqL7gcF12NwRfCi5xngRopBfAGAuZU2UspYxaxVrsMhyqLsfsBnRDmr5KtOra9ZI6nuW7VAiRgFc7Vyi01710WWcHSn366rTls4Yu9naMxnme+v/ft92h/m+fex1W93XP/qjP8I73vEOvOIVr0BZlvjEJz6B//t//y/uuusuDA4OAgA++MEP4tZbb8W1116L0dFR/O///b9x0kkn4eabb8Zb3/pWAOz3+A//8A+44YYbsMcee2DZsmVYv349fvnLXyJJkifrwhbbqlWr8LKXvQybN29+Wp/f3rbNYOrBBx980r8vXLhwuzr0bGvPFJg6/O/PRVkmKPME7cEc1qfM60TPDEl3mn2mWoM5OmsHvA0ADZTAhgYwL0fWLFH0UrjJDGhYDhdOpLzKG6w45d8SjGSvVd0U1EmAwRLjJ3wci795ER+7VhIF/MDpJKwvElF0bAaYbkrQ3MATqYrOkxzIJoXlIAJpOR/JvilbEaMiD77GhONMvZQBVDnAJnxlO0wmOinaZqgzVg3aAPzIAVKDjDLLei8FkJWUyyHnndz9Z5wwVKmikECjqPEpGXB4T8Zk/D0f97sY/eqlDKhuvCTsNq6BKKAMUDAl6EdBkOixtBxMrCMCsbfN6BdWeE1VjV0TcOjDguqHFX/DpezF6JeuCPv1r7pXVF1MXB8mEh8e/VtNK6Wft4Et0kk11jfF9fR0v4Dsp2Sd1IuXjeH/rliClywdiyZ4eG8yZTtioXO8P2Wm9L6p2sEkEwAOvmzsadshbEtTQ84a60YBwMYAoz/c5hkdqidfAPA6qfs/voQn/iSyPZCvrjqZ15redpa8Xir+20yNm/zSP8/p9VZ9VEVBY6TfRa0RqT8RAXQZB9uQZ0TikHQMqqEqKgAu31UthYQAsBUYqV2CkdJTSZf3a/Jgp1I1WRvlstB3KzU3TUnSn+i55uC/Qy5xoYTOU7RnEkz9j//9/u0GU/9w7Feedl+feOIJLFiwAD/60Y/w2te+FgBw5JFH4u1vfzvOOeccv91RRx2FN7/5zTj//POxadMm7LXXXrjxxhvx9re/HQDwyCOP4IADDsD3vvc9vPGNb3xa53LZZZfh6quvxvj4+NP6/Pa2bdZM/a6BpWdDe/U/nwHnBlH0UiRZhanNLbSHerASEjISEnKOkDYr5FMNTK9ve0M9M5XAOgBNC0MOZZEwA9MueUJOACzoYvU7z8bo1y7lGn3CPJFxMM0KqyUzZfRrl4KSmdSv2ZBxGMKKkHvAsl+TA6cL94x3Mwd4Rd2Y4IdePodDdgBClk3CoMkRUA6QOCWzlULVYCAFB1QtQjbJRZDJst6qGOR9mBKAIREVOyTTxhdxJWvgrINrc+YiNSsReEvx5pIAYk0Gac1ChwCoSmKRY+KCzqmSEJ11/HdxUh/92qXwIRECRm+4lBmVRJzmZXVN5ODikN6WmvSBcmb/bNuGh7u08Y9wqIYq8uEHzyrMAiz05/iHTsfoly+H11MZJyFC8uELP7F6hfDMLupk60Ounq2KyAz9qKzs7z5fxODyO0X78RmI+lELvHg5A5CXLBnz+qk7xxhgbaksiQcoyu4IXrWNUAMwbs8EkAICE+brCIL72A9aKGZlpN114RJfjkb3c/Cl7Kd131nsPXXwpWMMdAyw+HMrsPqjfC+EjMlokeEI4yfVBeckyQa+BJUeXK8n0UxHdG0RyHWp80AOiQB+4gVE/FPFfQ68ncvC96catAFI+X5Eg+LgWSwAnrFV4KxaTS2Crs0nqUTfD5NzMocyaVoA3Yj/3KolzEZt0ZNrF7ftzcjTz/azOc1mE81mc7aP1NqmTZsAoFaX99WvfjW+853v4H3vex/2228//PCHP8S9996Lz372swCAX/7ylyiKAscee6z/zH777YcjjzwSP/3pT58STP3e7/1eTYDunMNjjz2GJ554AldfffVT9nlnta1ipr7zne/gTW960wyDzi21733vezjmmGN2eeHBHdGeiVXGy/7xHPTyFMY4FGWCNKlQWa6NlyRS6gXMUuWbmyF1eFoK74p3UDVoYYZz3n5zBrQrFi1nAhZ0hVkFIADA63fcxgZMSbDzCi86BwEuN5jz69SvgtWAc+KQYAY6+GDigZQCJpsCg49ylp4pnXzWwSXEZp6WQZOK03ViSXKHqsGC83SaH5pli3zoMB8OD8tKvu86aVZtPo7J+ctWzqngMs50c6orcsTeTQb8IDeBoYq/DQxUuBSMnicI3iU91kORDxeSZxdITD+DPor34TP6/IGi/QPQ8jTJZMJlWVoOrsXAVSeO8ZOWY/QLK3xmVNznIOiNGC/p2viJYrgYN4IP/41/JKS8L75ypWed+rUn6sGjkzBVLO7210JPS/Yb19KL6+bVIk/KKFkg6cgYloCRe+POMd7Hi5eO+XtG74MYjPW7uGsdwGdL00xDAIHZkbHyIai+DDof8jPw4T4oCNVbS20xRMC9SgCVU7PNkwOAIg2xKXCPmR7jZgA6AKLRi98I/dNEATa3pHBOFdVsSyj+DLjvzjgBgi6AKH1eqa4ssgcxRbAnIAfvf0clM9ggIJ0CbJM9y170qTH09gh6qBoQFwDoPavKAKhWfXSZz+KLhfxP1Z5JZuot/+sD281M/eMbr53x/qc//Wmce+65T/pZ5xze+ta3YsOGDfjJT37i38/zHB/84Afxta99DWmawhiDa6+9Fu9+97sBAN/4xjfw3ve+F71er7a/Y489FosWLcKXvvSlJz3uueeeWwNTxhjstddeeN3rXofDDjvsqU55p7WtYqb+9E//FI899hj22muvrdrpO97xDtxxxx1YvHjxdnXuudI0pFcUCawldLpNtAZyVMSTtXWEfKoRMvw2ZsBeXVjh3G3qOPTWEPPHiRQ0UsBNZPxwaNqglVFRdC+RUBYAY0FPNNFex/2w6xvo7lMB7Qo0kWLwIePBztSBDsMPEDr7Ooz8OsHUCxwGHhWn8ejBbqWQ7PQCQjbNq0YO/xHKtqxKRctgCscgaQ6haAFph9gAseD3UqlelHb4M+21Dt15xCVlHOtwlNWiktkmI2JeN2XgUhM0VJHgVcEJAQyuSgpjUgtRIKJQwBNG6oJmysHrrmpMiQ55X8iW/y4hj5hd8bEbPq5L+rL9dCKKBe39kx6BwTIcnDBrvmwOAaNfuiKwXGqjgLDfRVfx5MGTfX3nsWbpoJUrPTh3iZ5ffC4yZLK9AggrISsFD/fERX8VAAlop5jlAjjUB/hr6A0qXQTGZVIEwmT6bGvK5Jky9FXBw10XCQul70lzep8oQCXUw3sKSk2fu3l0vyy6agVWnyo19XRhYSmA2riPEWv2ZMSH1zw5+IvlhJFivV94zzOV2iIA5r8PEC3fly/n62u4jw5BI2YbgcVSQKnMtg/tDTKLrUxoOsUArGqxLMKp5owQrCKceFkZDgWOfmEFxrcBRO2KtqOYqYceeqgG/LaGlTrllFNw55134rbbbqu9/7nPfQ4///nP8Z3vfAcLFy7Ej3/8Y5x00knYd9998YY3vGGL+1Pd9VO1pwJ5u6ptFZhyzuGEE07YqgEGgG63u12dei61o/7fT6CVOfSKFEU37ZtcA9DCVAKTGy9StY6F4C4JTz1XESgFaE7hncxd5oCJlFPC5+jSTFelgJlIQDmhuVEAUcITYOuxBC5JUAzzQ9CKC/XQg4RiGCgHHDa9yAIlobmBBeL5kIYEGOBkE4hWzUDZ4HBf2nUom4S06zC9F2HwcbC4fIQk8y84Oyc93m9jkvtdNTkz0BQcujFR9k2SQx6WMklZ/ryVydllfaEKAhc9JYIpCFWLz4dXxDymJKE9GAcC+ew6W5hInyWDqvoqks/q5CIANha0q2YrTGF9YAyAa1pUqfSnCptECUb9eIcniZhFilf5An7CTCnbxA7q+jEC97dPd1U7nBzngdM5w8xpyE/vsb79QZkJZe4cT3b6f5NLFqgL+3YJ/ELgzpVL8OLlXIg47kONNSNmcO4+b/tA1MGXrxRN2o4NBS6+ciVaok3TLEW9V10CHP7JsVqOdZzBph5Jyu444zyQUnAFcJjPJRyaYrAT7jsFUgpCTAW2vUjqx5oBpOL7CX3/d/A+aBBmlJ8BFqYwgXkCbzf+QQ41+5Az4HV84ycGIMXnryFH8veBAiEqyAvP1SE/Lkllhf0uhuR7LONkWxZm2vjvg00DsELKnm0Pvv8MjP7V5dtwZXdN21Fgas6cOdvEop166qn4zne+gx//+MfYf//9/fudTgdnn302/u7v/g5vectbAAAveclLcMcdd+CKK67AG97wBuyzzz7I8xwbNmzAvHnz/GfXrFmDo48++imPnSQJHn30USxYsKD2/rp167BgwYJdlgQ3MzVvlvae97wHCxYswMjIyFa9jjvuuN3GAGxXt4QcJruNwF5YgrOGwZKkp1tLwEAFOy/n+L4B6ImmhEMMF/tNEB6S1rDruYV3zAaAZH0GszlFuiHF0H0phu7KMPigwcAjxNkvacQaEBvetR8jX3PM+0R1gZF7DYbvTTByn0FvLmHd71f8DJNVrgKzsgUBQYSkJ+DCAEnB/x9YwyGFzaMGVRtobgxjQxWnN7uEf5YD/NAsBglplzN2qmYoiOyzgBxQNZ0vxpz0gNY6QraZzTtr5VTUxLKCF7hqIdmQGiYr4cQFU05rPIMUkEZANz50askbq3qdRtKXKRhDlBo9gKAlkbDO+EeWe8FwnKLtJDSz+tRlPiQRa4c8kAKCpYGCM4taaMyDbYTfa6xIH0OitgK1LCwdvujlh7OsH+vXn1mCdDrcW7ovnfCVeXjxsrEwNPF5RaDSZtsPpF548RhMzqzKjtZUNTYIuyJZerWQKMLv/e7dzqBWAkXHWkFqsBBwtf0BfE/4LELF/MpuafZf6sJ17bfW0H1FoUfPPGn/JcvXs12ORd0g0UMZh/EPL4czDguvuwzOwP+EJQZSH17OAEYPr679co2VedTjmZz3r7Ys+nxSxtKmrL/Uk3AZj1O2QVXrzJTqotRJ1YIH338GFl57+fOFjGdpzjmccsop+Na3voVbbrkFixYtqv29KAoURTEj6z9JEljLF++oo45ClmX4/ve/7//+6KOP4le/+tVWgaktKZN6vR4ajacf8tzets3ZfM+1trPj30d8+1wURYJ8bRtoWrRGupz55YIep7ehBc08o6kEmjUT1zUr5oVafNQz3uW6GirZHkHqubUf4eLBXjAMefAkIW2dKmZ/gPCwBUKdKx9ak4yqKguO5lVT/p4C2TR/ZmpfYPARIJu2KAYNyhbX7ht8hFmkJHfYvIjfb6/lMJ62fJiBjs0EpFVcBNkZYHovg+n96qtossyaQah9OPhipzoJVS3HjsolyViQhNV0Gy2y6nwxYZc6r4GSUZOfMSjS8SFQamESB6sZkYD3rfI6GEfBpkF3qaxDabz+SQEfgJq2LHY2t5HbNYkL9aqPShZXpHXx4SAn510J2FZ20wQ3bNW8BLBVn/n5XqFwXD+ZRsdA+IiyB7FOiiwDKL1vEklp10NlU6jXnhPmyREbeGpZGb2+d5+/nUDqkjEP4u7/+I4FUv3tReeMBa1OnNGqAEoy+LSAs+qhvEeY6Ke2pHEC6uxSfzba4itXYtXHOCRIZah1Z0p4VrA/TAcESw3V141+8YpogUKwLQvKKVh3pAHkgRDMggHRMVIta44cwvdO7lMtaaSgzRTwNfIUDCYdvcn5PVNKcfUkWC7EoN7bIuj/5fftBVHPpGbqv33vw9utmfr+m7+01X096aST8I1vfAPf/va3a8bdIyMjXiP9ute9DmvXrsVVV12FhQsX4kc/+hE+8pGPYOXKlfjIRz4CgK0Rvvvd7+KGG27A/PnzsXz5cqxbt+5JrRE+97nPAQCWLFmC888/H0NDQ/5vVVXhxz/+McbHx2fUDX6m2jZn8z3fdlw7/O/PRVmxToqGODTXm87QHCh4Xo0nI0tATqD5PdjN/OVJujwRF/OqkElVmPBgIwcznUhIwWHgEROYIwdf3sVRABxGxL9VC7xyMwxk1BdKwY9LeVWadhyqjFAOaj/5lU0CjUkGTwNrAHIOnT0Nkh4DoqQrE2wFVA0GPYOPsuC8GCAvYG9MyIMwZ0aKtSY8kWRTDu3HCfkcAXJth3SaAZLNJDSZB4DIfeexLDIWqSe5H2HPzFUDjoXp4ltFlkT7I09hBTmWomw/BKuDmGiKbBFcXGMPur0Dx+UQvQIo8RYUuip34dr6cFi8CHQhnLH4cyuQFAbVcCjg3D/nepCk7I4LmUs+uwzSTfA5ez2TRQBWwpBA3+oHiIj6KYdLeqFw8eFni6YqC/twhhlJU0Am0rA/AntHJaWmvM9yctvYDrlozB93ZwOpQy4aQ6MXbA40vBlrlX796SW1OnL3flKczxMXstQicABiIDz6hRVRKBC1e07boqtWACmw+LMrsfo0BlkHrViJVUuWsikoOXk+UNBb6mc/vwIEktp9DK4OWrmSM+wsQLmuvuKbnU+KFJRF4HH8g6fXQmpOdYqEYKlABNdwoA75e962nM9ATHqEcsCJBpP8AoN00aDo3cLPeq7hfNHw8Y8sx8KvXLbd99Az3RwAux2d3lYmRc03X/e619Xev/7663HCCScAAG666SacddZZOO6447B+/XosXLgQF154IU488US//djYGNI0xV/8xV+g0+ng9a9/PW644YYn9ZgaG5PvgnO45pprats2Gg2Mjo7immuu2cYz2nHteWbqKdrOXGW89LvnoNNrAA6oxPuoNZCz4zmYucindNXhgMnUh6HggGyCkM+zaK0x6Bwssa7pxNeYggOaa40HQ6YXQizkOIxnKi7hQiX/3xnAJuRZnHyEwVXWYaF42QoZM6qlcgRsfEmJBf+SoDePXczzIULacWxxQOx6zmJPzszrzeUQX2tDhem9EthGABTMLvG2zU0MpooBBjuDj1VIuhZV2yAfNujMFxPPvYBimFenLmH2CQ5obCZULQZVynwUwyxi1RVuvGJ1CVAOV3ANW/OgchWBGpYNNS15gEoELi0jdRGd5Q+RlJuBA5uf6gwpAMxIliZ/Rg5uSXRHFNiovm8n9f2u4U0NRaoBo2ckInatP728xkopmIrBEeCNF2ertzejyX40JBwfS3/PJtna4tefkfp5EoJubgB6c/Uk5WMK2sooNEjA/71iCY74+Fj9Hky3T2z+wovHPFhzhi0HdnY77NwxXlz0eBHT3YM9sA77zJg/l0PPD3UFnX+J8WRSZ6T6K4N4qwwN/VVUA2uALqTCPUMl4f4zluCQC8c883X/GUuk0K/z11HNQNVSQ4GV3t8xiPb9VGYWfM97rbEuTMRGAUa/VwKqjPNMrZlMfAIF5cQ6vCiRwjvLUzjPSl3V1Z9LcVXb+u/k+InLMXrDpXClwYMf2H2Yqf/6jyciHdw6LfNsrZzq4Za3XLNb1eY75phj8K1vfaumt3o2tK3STD3fdnx7/a1LMdAo0MxKGOOQJGHypr5ZyxX6pOAJnI3tCOkk4BoW3QU8mdPm1IeDBh4yaD1h0NvTes1U7HDNDI2s9i186MQm5I0BPTvVZDBkEwkFqEmiPJhbGxxG7uKixI1NzpeLcYkANAohRFM5FMPA0CMWzc02YqfYlDObdjCVQzbp0NzM41BKfS2Ahe7lYIKqSSibhME1OlEA95/OpTXaa3iCYMsIZsFsg8+xasM/9L3uRCep1KFq2wA+dLD0JeFTGF7RUm58YWKvjUIYGzhIxp+AlRnZe6j5TTnHEx4KmuGzMyuQ0Zk0jQwNBbjMFA5rH8BidtWF2aiYseX3uVhtxIABM3Q6tbEjhJkrGk/fRd8HKfEB4LBPjwEumHj6GnQG/v7TMJeylLrfI85ia4T/vGSJD0Nvb9ZeXN5lRwOpwz4zhkPPG6u9d+j5Y7AZA8t8btD2HHLRmP//wZev9Ma0lTj8+/qStc7zD18vjhyQOM7cjENqRrIpo+tYK3oMBk4vvJj7qkzTQStXssecLCRg2f9MdXU1DyZlo2JmEgh2Lj7Gxvf7+HvPEJDMoL8eSgfGT/g4xo8/M4TH9X5yxCWDCvJ6L+8gDwhDFYZDNVUxA2u6BqZrvLXC+Akf324g9Xzb+e3WW2991gEp4Pkw3y5r3TKDIYdWVrC3VFqFzD0Avc1NnzJM1oA2Z14zpJXSp0atZ1VoAz+BfVZKxEzpalQtBMiFcArAfk6mCKEbqnilDCNJZBWQdh0am7kg8dTeBkYmOVNy2E1ZlMakMEJiyOkSBmiAaGYIGHjcMvvUIjQ2WT9xWi1I6oBE9ptNWeTDCbotEZobDvdlkw7FoOgi2vz5Qy4YAyXMcCj9X4rBp4JAnVDUi6mc42rAw6VqLog6gtHJBwDFmXypZFEijDkIooeisJ2jYB1AUQaOhiD0sxEoqoXIYrZJr7N2Ma8XjuVQVZTBFNMXCpIEH9a089EEyAwB+ezAWAgcC9f92HrdVPxeGEKfYSm/x75TtsEMKJSFsgzgNUxVyypDuI4v+hSDqnhfT6cdcsFYEGZL/154Mb+ner1tKTfjjTkJITTZ13SfB1++ElQRevPl3KQPB12xEg+cvhQHrYjKmXxsKRZ/dmVNf6TNGQ7djZ+yjEsE6XVS4BWFZP0zwoG/BxI6ppLYOywh3HcWs1NVk4v9MgBznslB4mB65I+9+lRmp3wxYn0GUfh+kfhduZKfSeMfPB2j11/GDK0w7i61AfjLeS7+xkVCK/EzpMx4wckCdA7XKwNlhKVqbAB6e/QBe3GHX/zZlf78bYvZL80u3N3ajsrm293aww8/jO985zv4zW9+gzzPa39buXLlLunT88zULmivv3UpAKCyBoVN4ACUZYJGo8RgU26MeCXXquBGCmC45IdtCam3pyE9WZkJ8+FNFEugu8Cis0+FfG40YTtgYqHDxIH8jPL2Ag7s7m1YC5VOcfgl6ckxLZBNVl4X1djs0Jh0mNjfoL3eIZ+jYmUuSJxNVWhsrtCYski7DJTKdgit2YwwtV+KqklobnBsfwDRRgGwKaE3ksAm3B+bAT/75jIkop9qr3fo7sHhP5vBT35K5ysrohYNVsN/EVPiw2QEn80TEAD8Kph/76OKZBXuBbWq89Ad2/ByDiGsYQmuMHCFAXJ+uZJC/b2YhYqYHbUE0BCjgi+1x1C9jxXm0E+6uj8l2SSUWDMijLaZISDX/fTVKownKW8oOctEr9sAwQvosHPHcOj5Y97Ak6QEUTXAQCr2LFNNVNVk4AWETK1qFl/gw84dw2GfHsNhnxmb+ceoHXo+90ELMcfjbgoODatAXsvBPFk77NwxvOicsZD9qvuU+0LZqUMu4FqAB186hvtPX8oZuonWloRnnxg4iQs3MQO06jT+v4rJV5+yDKtPWeYB9OgXr5gZZutjiVafuqwG0rX+oYuSLQ6+dMxvr9eVJFnD9ChICcD3yuLProQpifctoeH4mBDm1qneEAxgIIbD1OOV24PvP4OZopKrEADAqr88OyDqKFFCwX3VDhoy2+DsvnyeAHG537S4+eLPreDPJ45LyYj33O4IpAA8rcLG21Po+NnQfvCDH+DQQw/F1VdfjRUrVuDWW2/F9ddfj+uuuw533HHHLuvX09JM/eAHP8APfvADrFmzxqc7arvuuut2WOeeDW1nxL+PuWUZumWGyhpsmm6hKg2cNcgaJXqdDM12ge6kz+mFK4hduB1AEymGVhn09gTyeVwihUZyOEswGzMMrTbeDLAYAjr7WLQf41IvcR0rpcXJcfFhneTizKKyTSgGOLvOlBy+45IuFr25bEiVdiyyiQobX9hA+wmLif0NWhtYK1W1gIE1zDwVgwaNCeuPaQqLsm0wvbdBc6NDkjsUbUIiQKtsEbJpXUnz/vI5rIdKOgAMh//yOVJQmVhnlU3yBOtEOG+KwJIUI4E90fDAA8uWhsKuiQCk1AU7hJgdivRq2lwqzE3Nv0o+GGXAuYpYV5WLojtxzEIVzERZcaSvhV0I6H/WKRByxnknaD+xkWhZtD5frIWy8BmegKzQx1bWnbgRsUA6WUWsnd9Gwbeu+oWBUIsJZb986EyGQdnPu8/j7DQQa4QOPX/M/wwDG322r/YeVRyCdmamB9TBl475ELYz9Tp82g779FgoICznrJOuH6vo2BwC5u23FAI87NP1zDzNkI3BMKCsKAJrGzl5P7B06az7jlvMoCy6agVc6jB+4vJZt1143WUMUrS54JyvIUGftSn3ipaMcmmo/fjAMrlXIt2cZx/j3auwW6QI6PteaIYsiT4KAFzTch8dYArjmSzbtnxfD5QYP/5MLtnUM0jXpyhHKiSTBqYklEMWJg/fg8YmCqy7A8pB8Z1LAduyGP/wcvbhEkA6+lc73gLhmdRMvfYfTtpuzdSP/8fVu5Vm6r/8l/+CP/qjP8J5552H4eFh/Md//AcWLFiA4447Dn/0R3/kMwaf6bbNzNRnPvMZHHvssfjBD36AtWvXYsOGDbXX8+3J2+tvXYpO0UBZGfTKBM4SbGVQFXwpWgM5AylZhbmSYDoJG2+uz0AWSLsMKFpruDgxAC7eS8DkqPMPOvaJMqHEwjQwtb9D0uXiw0YmO5sRZ+jJ3VA1WDxeNTisWA5w1lvac2huKFAOqPM60JtjYPIKzY0WSeEw74ESrY0Wg48ziza1r0GSA60NFsUAecBWNQ2zRpOcgdOdZzxD1p3PQEzF7b0Rw5l5Zcg07M1lpkIZAFPwuHiGhPjcqhYzWlULsJmFbXCdO00tX/zZlSGkIADKWfgiz64ir4sChHmRCTJkp8VASv8TWJx4ueJSWxPk+o/ZqIhr//Im6WfL1MUZXiPn9+PA3+qKGc0ZnxXGafGVK2eE+cixPmcGK0XhvJUVNQX5fanHFY8rPAiMdVNOrDeqhhh1SlP26MjTx/z+YpsAHUoXFTWumsxGzABSl415MPjrTy+ZHUidO+Y9u/x1lJ9aYDn2Y1IgpcL6gy/l/irwO/S8MW9xEC5CnVnzYxC/pwwUMfO0tQRBjUFxUh5oC+aSD77vDLYvIM64Gz9pea3g8aLPr/BMkjJezOo6XmxI/xaPrWQAKAXG9Rqrjg3g96iMmEll5PS744KVixO7BKSOQ+YU3tdxooKApgXiKgNyndIJBlK8IGTgp6xa1YrGN0Uw8SQOSy7+3ArYlvUFwnd3L6nnIjN199134z3veQ8AIE1TdDodDA0N4bzzzsOll166y/q1zZqpa665BjfccIOvs/N827bWq1JUltArU3TzjG0RCCARoU9tbDMlrv49juCGSn4gbMhgOgZJ7tDcSMhHAJpM4eYUnAUGYOBh8rojIxYFmnK+6RCHoXF2Hq8kg48clx0pBhkwVZlooFSs6XgCLAYIVcPA5AamdKiaBtMLCIOPOeTzGigGDBoTjIaqjJDlFkOPWkztY0DWIR9incTECwza65iJ0uw6H55LgN5QWCHbhGAci9k7exKfC/hciiEuL6PmoECYtKkEkNTFtswG6TlR7QHeL9L2hpUKTIzzmiAPLCTcoHqi0PpCLIDXTflrKoJZnogsi9Bj24OoO0zjOYAIsE6AGQHO1Y01o8NDa+SVouWS83UErP5YYD+0tl58UNMjP17qvuB81hiXe/CafCtZkUqCib7p/jOWSHp9EFYb0R4lvVivFybjYg4CkIq65DOzZLz85C2T9kErV3Kig1hexOOujBeAeska0r7LMWJWKsKems1mM+cZSVOxniqpeJ/G+q9pdE+FnwFAyHmoqD4CnouvXOkL6s7WFn92JVadthQLr70cyTTvXEO0bHb5FIDAsBjdh6FdYKRUP7To8yu8RcLBlwvQrgKg0u8nwP1ftWRpzX191cf4d/07XzupOCDAavykqMg24Nkp/U7qMZOcUM6pgJ6Ba1hmpQCA2B/OiBKiHLLe3sA1rIRJEzHqJa5pGYU8Xer4+dU1sC2LhddevtsLzp2jepmqp/H53a0NDg76un777bcfHnjgARxxxBEAgLVr1+6yfm0zM5Xn+Va5lD7fZrY3/uhjKCt+IlXWoMwTZFkFK6Gdqc2twDwkDpQ6UGZBkyln6lk2MezNZcDks7AmMpjpBM4AifpFVdED3rFuaM79nAFTDPDx0q7j1OySAZXqDsgC+RCH2bTGXTFIKFuEzl4ZOnsYVBmDGX0/7fKk+uPvnA5T8QN084EGg49WfpJMuw7DD1t09iC4hF+dvQj5MEnpGOcn6bTjWHslIRebAr15QHcvYOpAi8ZGLmaqE78v/goABmhsghf/2qZDYzOvdr3dgAIlhIc/KmZ6dDsqiR/4qn0CAnjSGVc1Vv6ZpBO6AKiIsfCYhUKKeL+2iKKJxa+qISyGaloobLzqY0trDE7YEUJIMrJYWPT5FVh85UpmG/SAqu+KH6xRxlfcN2aIXHSvxPRLHex4ywaS9HQS3ZO6f5vwOYDNKT3bpedN8GG3wII4L5Z2OtGbwPSAmPGiko0xNXNQ70NnIiBl+85VfmoNQf97wwnL6cL3LgJ4HuhRAGEKnmwGYXWEEU3ZFVx1PC5xPiNOfy7+LF+fhddeDmccFl21goFUdFHIAeMfXu7rKW6p9bNZvlleUK06bSmoJCy+ciUOumKlZPJGzB9FIUj5vL9/5D11wU+6Wt7FhIWLfAdGv3hFyFKNak2awiDp8T2YdnhRl21K5LtofIYpHAmrJGWjKtl3ys9KCEtVDVmUgw62aWvMrWdTwddodwdSz9X2yle+Ev/yL/8CAHjLW96CZcuW4cILL8T73vc+vPKVr9xl/dpmzdTHP/5xDA0N4ZxzztlZfXpWtR0V/z7mlmUw5PDE5BB6RepDe84RGu0CibGYnmjxw0cZDGI2g4xDsjZDJo7ejU2A1qMq28DkqPUP/aRHqPYoMHxnQwoLRyaZFU8iZIWBqlgvlRTR5BatzstWYDSAaGKQ31vrHYohrrfX2ZMw/BsO9dmU0NnTYODxCjYjTO9l4BJ2LgeAqb0NmpscenO5LEzVBLrzgTmrGTwVg4RsyoWJLCV09hYB+yDbQgw9LOd+IBdato36hJZt5gyxckgASBxisfxgtS0rhU3BVgdeeE2ewfBlJtIADkivi4bQNGwkn/EidBtChF5PExkZeisEmWAU/KhlQTzxAuF9dYL2LFr8DY5CJfqhmr+QTKChE9E+IpAWrCiinRMLng9auTIIjGNtlTJ2qjnSfbpoXIEg+BaG6J5zluCQC8Y47KyLgFiLoyAnskrQ0DV7TLmw3yqcn2amkmVn9MM/GbyTPODxYxA+Ewu2OTTpfH+oYG8uKiNwHI2di8ZjNr8qZYRWbWcB3UVXrYB3uY/cyJ+sjV7Dte8WXbVCQAzVAS1FP5Vd0tqB/QSGnPsqYToXX7kSMA6rPrrMhw8Xfy6Yv/oMPx0zcelffeoyHHQFhxEfWLqUS/mUzGiaAiiHHexA5dlg02F7Etuy9XtOsgxdZkG5ASx5XdjoF68I3xdh2+xghQffd8bTGfqnbM+kZupV3z51uzVTP3vr53crzdSqVaswOTmJl7zkJZiensby5ctx22234eCDD8bY2BgWLly4S/q1zcxUt9vFypUr8Yd/+Ic49dRTsXTp0trr+TZ7q5xBI+krwEiskQKYqWoP9eRhpqyFA3UNzIYMaYe8d4raCFRNmctlxWVywuDDhOE7GwBJXTzItlLqpWqwc3hro5aj4BBfMRgm/KpFrJvqOj9pOsn4qcRpevAx9q/SyWPwMYdygFAMGkzvZdDcaP0DePBxi8FHLab2NujNNRh61Hp7BnVVr1r1kg+9ucxYgVhYrtlcKrbWSYCrwSNMoDIZlwO8HyooTJYSbiAnLAFBhNryWausFHxGpAcbailgiTOQYi2VD4mG1TZAwYxTrjXIsR7LItgk6N8QgZLo/qgBHArvuz4tU62OGVADht4E1Ia+1jU+ERhR0bxnckKHqCRmJGz0fm1so3MF8MDypTPOwZ+nXOd7zuEU/JpObDZWzIZrov5B+n7SIz/+um+ywQYExAyVBzqIrq+Mwz3nLKkvKCh4V3kxvYZPKdz3MZvlGSqx+LDNmevU1acu84aX29NWnxJqMM4AOlto4ydyGRhtLmVms+ZdZQQgEX/3nQmASS/SqtPCc37x2EoG1wKkFo9xgeiDVqz0/k36jBo/cbkkKQT9lAIpR+zArhrIxma9fwHkBloiycg+k454RPVMeF4aB+omGP/IcpAFRq+/jF3NEwfXVLTMr3hRszu355pmqqoqPPTQQzjggAMAAAMDA7j66qtx55134lvf+tYuA1IAtp2ZOuaYY7a8MyLccsst292pZ1PbEauMt/z4o9iUtzCdN9DOCqydGGThuSVkWYWyTFB0JPahD3sjWprJFI0NibcTSHphtZ10ARCw+WAGJ8P3G7/ad4aBEzn4WnxpFyDLqcOmZDfztAcM/raHTYubbDkwRDVtSmBo+HjdPdkUMx9md/LufEJzA9CYsujONWhudjAFv4pB1lepV082ZbFpUYrmJnZIV92KI2DqQIc59xOSLntDNTY7dPZgyr83VzL0oom5uY7PqzeP+6Pp82kHvpyMI/EvojDBcaYR/CrZG/45+Dp0GgKMV9Quc+GhLROCk7ANAC9er7mmxwBDW59YvWaHoCAlWkFrzTBdmfsJZgs6K/BbM8K8tYytmH1B9HcbTFn1vDx7QwAVoc8h2y0wfzU/pL5MQdVmKRiekUVogcZGvl567/lzpfq2MfiMsw/9ezZkcdYHRvscnZf+ycCPTeygrWxsLNTX8aK+tZEjLvmyOzT1q1p96jLPcul4Asx4KbME6LhS8GmKroUzmhDhvGXD4s+tYHAr4V6j4TZPkbpgHAtmpdgclJB2wjGrJnzoTo+ZThhUbef7bNsW3l09N57Bsk0LtCxbj6Q2lNYyqBUJ39HtmWSm/n9//9HtZqZ+8Sef262YqVarhbvvvntGkeVd3bZZgH7rrbfujH78zra3/+xEdKsBDDd6mM4bSAyXEWk1C0xOtlAl/BBoD/fQmWiGicIamI18eTQVnCphZyxntSW5/C6Tm1oibD7YYeg3gTmwCZCKlsqmnLnns/dTYHqfhhcIayMpYmwkJFg12K25uSEAk84efIxiGGhMctitMcl9KNuE5uYKZVME6HMSFAOG9VhzCNmEQ9UiLoS8H5BOcImZ9hrJ2Gsw41S1JRNPXL6zSSCf69BdAKTTJPoqHpNKys+Ube5Xbw9g7j0Onb2kn0OcmWgb1k/oWooiNlf0YMszFS5M6jHT4sLk6lmRmoI5mp30dxdPKno8LdNBcAo4+oBDvAsQQHDgeCObhgIBPMwQsRvH3Y8YtBpQEcDF24UJcFYQ45lTBZ5xrT7e8KArVmLVchEkR8MR1/WLWTb9PZ8brAwOuXBsBpCK+6z7UeCrGkIPcGbru/Y/AkIaOqyl+et1V3BV9b0PwPTq53DvJ4Jz+FO1uMSLXoudObnP1vT4cR3G+Oeiz6+Yee+pTxPfgIEdTRwgYdtFn1/hixG7TJMkXP2iS0gOicMDH+Uw30ErVvpjFIPwx7YNh6RLrPsTFrkctKCKYJMA0qgivjUarDEFAJMbVKKbMkUSsv7ybQ7IPGvbc1GA/uIXvxirVq161oGp7bqrHn74Yfz2t7/dUX35nWzWEYayHN0yxVCzh6m8gTSpMN1pwCS82iq6KawjtId7QEUYGOYqwHZewSyDrrIppCa7FOiNAJuO5Ew/KgkTixwmF/LEPHmgw/QBkUN6xdYGCpiqjGBTEgaLv1BVg1CpK4Os3osBnqg0LJMPA915gMvklbLlQjFIaEwAsQgZDpheYFA1yYt+02l2QDcVC851ImturI9bPgeBUWryQ9kIwGPdGHkvKdvgnwRwaBAS5gOXp5nzoEV7rUN7DeqMDPi5nnQJSU/MCL0WSNggDYHUfKTgTTPjME/NaNVJlmYU+vJZcMrUOM2W4klJ/aG8Vir2u9LOGrUuIM7as/BoZQaI6n8vFr0Lm+NF056JCXXfgMDU9NsVxOylZ2tUtE8SvpF7QBkvz0j5MUDYBtF9E7X+UJoPo9aYEXirCw3t1UKE2j85nlqCAKq5CuyTPy8Xjhn3U2sEOiMslGEgdchFY1v0oBr9akjXVmsCrbHJIM5h9OorvOj86bRFf30xRr90Rc364MmaSwOLtPrUZf7/T/k5AVEKuP33IHM1cOUyDvtpSJCvodxTGqqbNuE+AQDiBZLam6hTu82kVE7C2XgK1JSxpZ6BMw5mKgFNpL4f1WAo8O0y+S5bCiG/34H2XAvzAcCFF16I5cuX47vf/S4effRRbN68ufbaVW2bw3zWWlxwwQVYsWIFJifZsnp4eBjLli3DJz7xCRjzu4P6ge2nbF/3AxaGNtMSnTJDXqbolimmppsYHuxiqttA0Uu9rxEIwEQK13BIN3MsIp0KVdBV7Jx2AvGheqHpF1gfHiIHUM6hqMEH2cMpmwqWB6qN0s+6lJknKuE1J2RFd6XgSiYaL2wvGKQ1NvPP3jxgZDVn26QddkF3Ca8gp/ZJuPRM4XzJmXKA6+vZjNmtTFgtK2CxagUmzqfVC8hrP8H/L4c45OcZu5z7QRXQWgs0prgkzfReCcoWs2e9PR2vbi3B5ISkQyFkkPFEo5lX0NIznoVwoJJpkZrIW8NMQhjp/2tNCySraLYvNKifdX6SRUAGcgwnoEVDg/0+UwBqKfkAalluynr5zCZleVSU7oH0zELQNZEy+GeSz358mzkP4mHlXG0Q+XsmRO8117f/GMhE4KumW5JJ16bwIv10KvSnxiopjnTAXRewGF19r3wfqrBNLXswfqQJE+bMtpWY0Tb6hRUhGUHvBQMfYo5Jza0FOLX9f5k9p57K0buWATjLDNAPSFefusyzVTNAuf7fwWvQxk/i597oF1aEawsRvSe8nTLper2TrizuBgQklcSsY8ZfTteu5P4lb+HhWrwgNV0zI6ztDGAHqpCJW7JAHY52aibfMxnmO+rmJdsd5vvln43tVmG+GGMQhZvUObZuqapqto/t9LbNyOcTn/gErrrqKlxyySW4/fbb8e///u+46KKL8PnPf/45k+G3LW0wy5EYi16ZorIGeZWgqgxsZbB5soUyT9FolqDEIWlYjvsPl8g2JEg6hAeWLuVMvBJ1INTkUjHTB1RwqQApBWMyQdoWg4CJxZJO3BCx+RAxW0TM4JSDkhm30GLqQIfJhRaTo+xcPnlwiekX8P87e1t0Fxa1SUZDYqZ0aD/hUAwQkq4DHHtROcNMwPDDJcgC7fUWpnTo7GXQG+GaZImETIohAXwAGhMc7tNJToGWhjOLIfj6bUnBL1PyfpIOMPwbh7TnYHKH7lyDgScqwADz7qvQWsNibNe0NRZNQ5++yWraefsDnRGcZ1lYO0NAyr+osDUGUv77rvuS//tjiPO6ZgdSowKaFpRy8WtSMFTrV7gG/X/z7JfWYJPzi5sCFdXfxZlppgigK7aciAXWPvXfhHvSH0ePrcBAs+10CCNWCYaBq41KACmgtplmUNbP4e7zloRrZsN5PLC0bn7pCMFYMmKYXnTOmP980pOi31U0bhaIXdBrYxcxeE+njZ/MPtxKOgABAABJREFULJD226gVh45ZlCxQKyC8tfv/0OlARTWheX/ztfuipsAt1kzVPnP1Fd7sVgtS18Lewq6OnyTmoF++nGv1RWAYkHtBtlWmMSQQyJgT192zyiA5AZrGhc87gmtZ7/Bum652jR0FgB2XQyIF9s+33bbdeuut/nXLLbf4l/6+q9o2a6a++tWv4tprr8Uf//Ef+/de+tKX4gUveAFOOukkXHjhhTu0g7t7M+RgHWEwy7G+y7GnyhIazQK9TgbnCGVpkDVLlHkKkgdN1eKV2WHnjtVFzTK5lZouXxA6+/ATxKYuCD0jYGBK8qnczok9gjx4HAFTC2WSHyp5Edc1QM9wpl3OD7piDu/bdkww79OJlViLBQBJ4dCba5B2HKYXGAw/xKuEqX1TDD5Wia6Gty2GWdTe3GRhKkJnT0JvDsHYaFUsD1ibwYvuG5s43Jh22Owx7Ug9rjmExibef9qxABGKAcKcB3soB1PMGS/RnZ9wmKcguEyLsgbhddJjoOYlTQQE88FIa+S4KCuVBmjw+DsxYAUCgHKim9UirxyqC+fmJyJt5P+RH7w9AV5w7oyT36n+OT2E5etGDrAGWH2KsARfuqK2vQ8FVvDnpuEbz0xE7JUHlzImMShSAOL/r+cRUS3KetZCc1EJEhW3+/Mh1syYnGrLvsM+PebBnAIpl4oJaUY+FFdjTSJGzddv1Mk7ul7eQ4rgMy79R03Yx/2nh4y2bWmjV1/B38dIfA1hamDgs023Z7p3DctVE7bQ1EZBwZr2w7NP8jcXg/h+AjJaIAC60Am9VmbMM1MlBXsRB1++Co6fdcFkU84hAZKuQTlSggojzvwkf2O7hGRzgmqALyB5R/7onrNgrz5jYfMETu5H6j+X3bi57QzV7Y6aqT/8wz/c1V2YtW0zM7V+/XocdthhM94/7LDDsH79+h3Sqd+V9u5ffAC5TTC32cWcRhcbJgcw1W2grBJU1rAxp6ySyjzFwEAPNk/4iy/hNIAf/C4FevuUyPcqYDN2ArZt68WeXtcSiaqDFoW1VFUTvs6ZD3Gk/Her+gJ58LnMSR08nsmreSWq4RIYKtHZv+ASLuJfVUkoEAboziNfw49F7Gzq2Zhg/ymbkJ/Em+t5m6l9jWQYSmhPPaMSYZukz1QygFI9lU5u2aSFI8LAGgfbYI+qzQcmqJoEUzp052dA5ZBOWww9XGDvf53G/F8BzccTBlVyLF1FZ5MkXl+IVsxUn+UEgMCwK7krDK+cIw0TAGaWdDKXVT2pbTYBlDAbSRGr5TVUCgj6Z1bHDIbPqnP1bWJNFoThGL36Cukzgo6rj9XyITQDXyg7BiVa7oP1PqiBKF+3LWapIKCD5B7LArsFIxOnmFbGRqBxGDH2f1JGTAtZ1wBcyc7ZGt5RHZQvQ6MsKgKQ+vVnlvh9c+1CBAZYj69jS2Ef7mlaG4xecwUD85hZjK6zjrmaeT7d9uD7z6h9/slMPf19ErWaASpCX30NQF0ARNUDHvzA6bNq3sZPlqLKCbNCqpdyYuKqM1DVkIWg6vCEZaZuIt8b5w1wKTegLj+XTNcwcHQ8brYdhXgc4NSeIXUsTo+yckdv2HWlR3ZUc2DQ/7Rfu/oEnmb7yU9+gne96104+uijvW77xhtvxG233bbL+rTNYOqlL30prrrqqhnvX3XVVXjpS1+6Qzr1u9KmqwYMOfxm81ys7Q4CAKqSh3yozXb4JuEnRJJVMMYiaZdIBws2lZSHftVk7VI6txdCPgS05nfY5beAlFkQhkWKIrcfZbGmyRkYTB7IE5Z/NYDp/TnUlUwmQGE400U+313AzAEVBGeBZFMKdBNQN0F3gUXSEVF5R8qGODbynNzPwGaE1gaLckCczvckTO3DYnRyEdOU87kkPYfmBv5q25TDjxxu4p9aJLcYDJOlgojuvARJwave9hMVh/1yFqNXDUI2ZWEq/ns5YEB5hdYGi7n3OxayU8hkbG5kZ3VT8nlTbnhVXWmR4wBEqMcPdeoZUGHgSgOvmJYJwL98KITPkWSWdjbSykUgAnAwzSp8LnrskUUARuofFf8NCGajyjQp6BbXaB9+EbZLQ3qAACM5V9VPqQZK++eTFMyT2wEctHIlHli6lD2nPBiTY+pwiXjcpXwc2wjjxOcCD7Ri41gnk3HsGRVrsjwpFj/lKIQJfbhP3o9bDHjq5xzYk61t8aStNgJxKFFBnL8Glmpk5dNqFDFPlv8fv0a/IACLXM03Kg7Z1d9jMBi/F2czPllpFi1HxB5h/DzScC7A/nhJj4sVw4G1nso8OhmP1DIgUga2ZUXKYDkcqN+fSENIFTuouyIJzuuIgNTvlrz3OdNuvvlmvPGNb0S73ca///u/+9IyExMTuOiii3ZZv7Y5zHfZZZfhLW95C/75n/8Zr3rVq0BE+OlPf4qHHnoI3/ve93ZGH3fb1i1TT8Fu7LSRJFZq8XHoj8jBGIdmowSRQ6KhJGNhE4dyyKGUkFM1WMHkCZyIgi0I5aohYMii2qPEwH0ZevMdXAYRbjp09g3lFFwCUAFMHFQh6RpULRGr6wOlIv8gUmdkrRwPA6QbU67D1jMs+uwalAP8QO3uwQCkNx9or2E38s0LCe01hGKIgU1jk0M+h2AzwtSIgcl5gmxtdOjOI7YsSNlnykYMmgcOgH9gamixN49BlkuBf/2rpXjZKWOoGgaOCO11FqZwKAcMiqEEpnRoPdHD9N5tJL0WBh7tYM1RQ6zXkmOZXHyOSB76Amh9GZCW86G2uHFatoQhhIFyJfVpnZh9cjZKZXbCgCnoqaWgQSwPlBaB1PALn6UyMDG1yc2CAXHcRyfgME5kilP+CB48MQvkPAvjvaRIGbrQR6q4Bp4HH34C1LOWosq2D6/EGjTA2zLYpquJ6pm5cT7858vYRGCJNXsyBi78Xf/m+w4eq8M+PcYgzNUBgTIl8bn0n5ezhAdO3zJ4nK2pdcX4ictFxM3X1LOhMZCWsQDgdVNPR4iu573o8yu4+5KYYgoJbctxHYIruxWmcEZIz58IeHwSNwM4jV5/2Ra74hoO1FXhuasxqryQUZYSbBSa8ILQZwDqeKkNQiILmRIwztQKHZOw6sqA+esvjCxlrEVc9Zdnb9t4PkubBYG2eMG27vO7W7vgggtwzTXX4Pjjj8dNN93k3z/66KNx3nnn7bJ+bTM2/8M//EPce++9+NM//VNs3LgR69evx9ve9jbcc889eM1rXrMz+rjbttwmyKsEZWVQOYM0qTgU5MhnbimQqqzB5HQTZCyKCS4c5loWtEcPbo8c1GATT5KHjCk4HDX0QAKICLO5gWpshDPgiV2obdUhVC3rZxcvPlY9SBSmaT9i0HpCJjEBFGTZEM+lIWzYfoJDfq11/LnWWvaL6s4HBp5wSLoO+QihtcF5EbltACAgHyQGMcOc1Zfk4Ad9pL/RdHe2d2DzUS2PYwq2iPi9k5llcIaBoNYfbG6q4AzQ2FRg8sAWyhZh88IMnb1bKIYEZEp4Rf27gJCt2NzAWUYmJ2btIsBSEyiriaYFm3oWJgJDPEG5CAgxiyVUe0VwhRGgpLM4PMCBDROyX6krqyEhXacids9ukX+Nn7yMC8h2iM+loLCPKmJ5Iv0LW07IvZOAX6nD6lOWhRBSDMyk21UjynKUU1/1saU1sGCjsjC1kJnosWoTugC4mg+Ujo383xR6DeCPExtq+hCkNhFQx2FDDbdpcexYJ1YzsY2aeiM9VXvw/Wdg9EtXsDlmxSBYWTUvjo9YSafXHXj6DFWcfCBNAamC8Pia1NYHOr7+GgigSR3GP7x8VgZq/L1PUpqFGOysOm2pr+1IBQKgzZQJDtIGOA0RSp+NJGNEhbmpIskQJn9uvuZhGt1DHbl4YtuxG+KHLTb1mdqe1+7W7rnnHrz2ta+d8f6cOXOwcePGZ75D0raZmQK4UvPzQvOnbgNpgU29FhLjUFYGJtIx9PJMQBSBiGDIeSNPKmTSrojT4VWfAwAWKOezKDOdTNDZJ4T99OFo9unAPjLAQu4EvnwFiebH5AarPraUH+6ORcouE+pAhMXtx7kP3b0ZeGk4qRqsmHKfTJHkDGpiyr67B4Mp7+Xj1B2ZM/4m92Nhu6kAyGSW9NgY1LXZh0of9KnsuxzgAs/FEACxYyDiY6vTt82AbNLBZqzZ4vI4BlWLYAoHZxpoTFiYgmsDbjwoRcmRVyTMEjOwKvn3bIL1W8312gexp2gygKlacdiNQI6LRfOqXyYAAmpLY/B1dEWgRVhnRR5okaTKk3G8neMQa1y+Jc6O6s9McgSYOBuNmBnyk5TcQ0a2ve+sJThopRQMljI63gFdJ1wKxxm95gpORzaOC8tGmX5aPqVqM/NhhAk76IqVwRsLARCuPmVpLd3ei89FV0SOQ0BUcijx4MtXAuI3hrAe8MyiFzbLe4pN+32yfDp+fHlMCD3XmL7o3lYxurYHlj25CH3hdZcJ++tAzkTAT3ySomtkU4gpJQV7k373/K1so391Od98TzZRxnFQIGQnxpkfEagd/+DTtxJQNnPRVSsYlAutGGsVXSKLNkJ9USAhYExmcGq26wDXtLCqDYXuQ/7fY3Ng17TMrqt4vWHZdmS7Y6jPt13Z9t13X9x///0YHR2tvX/bbbdh8eLFu6ZT2Epm6s4774S11v//yV7Pt9C+/eqrUNgEzZSf8NPdBmdfVIQksciyikN7AKY7DUxNN2FLA9Njz5TxE5d70SUqAm3iJXQ6WMDMyQHDD3SXWe8Wzhl7fcVsyWHwIeMnCD/BFSqGdSHdOXFoP258IVqbOdiUxe7VYMX1sCZSaLhNa+Z15zOQsg2gswCY3odZKSNC9fZatk2AA5qbuA9Vm01B0w6PgU05zKZ9txn3Ke3ydgC8V1TVYpDVnc/HN5E1QjHIAul8mFmdqsFZfVXGpqRph7VjxYhFMRwyjFjEKhmDk8DwQw4DT1Ri+skMFeXEmh6gXrzV176TiSKNaRu9hobDfzmBSsPX1of8EGUZObiKv5pOdU4VAQUBhQmrcKOp/9IPr4WK9lkpM0RB3KuMlAEDFAUtXlfFv5uC+HorK5cboKLg1m3k/shQA1XeO4kiUTmA+89Y4oHN/WcswQsvGeMaazmxGaMVywqdTClck0PPGwumqhFz4pkk1M+NSr4f7j17iddUafYqb4jAOiV6LjKeSfjp3fDlM+otdfClYzOvb39TFrE0XJeuIs+AzfDAUnSLAGxs6p4UD22xFVsAUjGGiG7Pms1D4oDMigieQdTTBVKjX7qCbRhK8uDXpY51Tgl8QgNnxrJezmWOa4kOWNZo6a0sixSq5DvQM9xXvQ9a1ocJkVnRjcYMMfx94yxh8TcvwqKvX4zF35ipsTnopl2nu9nW9lw07fzwhz+M0047Db/4xS9ARHjkkUfw13/911i+fDlOOumkXdavrWKmXvayl+Gxxx7DggUL8LKXvQxEhNm8PnelYdazsb36n89AUaVoZQWKkjNOqjKBs4DNCHsMT2HNxmFUlUGzWaA73RA2giczAHDrmnANh2RuD2VFoMSi6iVoPNwEHHD4J8dALzDo7mXZR6Uk4PEWBh4nTB0o3lMDFUAJ2o8atlGwIlgXMBVS/4HWo4kXfVciXG5s4Nmqt3cJN6cAbcqQTrKHlG0AvSakrh+zUlWT7Qum9iUMPRwmPFMC2bT8vwgT2dQ+vMJMeqF4MzMbDJ5iPyu1eDA5YId5nKs24Dbz/huTPIH/n+uYNfi9k8eQTjv05nJcxRnO8LNNeKFrMeyQTkamiXKcKiOYyqG52aE3YpitaspsqG7lju97KuVZbRnMhl/kZrBGwn9BBM4DoUBWwnRSbkhDe6wZIx+WAxBAsQAX15D+CBhR5koZoBdeMgajk7cALB9iEeCtjA65MC5OBeI2jH9/lplLAZTColjAti3fG6TXOZSneeElYx4MHXr+GJNdBNhKj+fwwPKlOPiyMcBB0uH5XvBu65HGqDYPRO/5ty3wok+NBcAbsVCxf5YX7UvYrRZSVB2jfXomndoP1iUFsKhj7YCwpKVwAkocPV12Km61MUEYN5ptDAWY7xBTy2jMYThM6FvGzCYSxyVfXHRvOfLjDgIoswzkmxUnwOgYOvL3B/UMZzeXBuMfYp8rzy46nq/IgBc7Wo9zC/qwB96x++ipNCtvez6/u7UzzjgDmzZtwjHHHINut4vXvva1aDabWL58OU455ZRd1q+tYqZWr16Nvfbay/9/1apVWL169YzXqlWrdmpnd7dWWQPngM3dFoxxqMoEScYZWlVlsGbTMKwloZ4BWyRIJlKoiBkA3FAFl1lUeYLGSA+NgQJZu0Rv78JPAs21CRqbDMY/styLxjv7CLCywMC9jSB2lUYlobGBMPCQQftRg4GHEz8J64q8s6/FwG+NX+ln61O4XLl0/qEgqRjmB1RjIjAmg484zvITNmxyf0LVlN8js0iXMjiKwzGse4JfeQL8Ga3DlxTsvJ7krGsiC2/QaBPCEWeN4cXLxmBTZqaSHOjsSZjeB9h0EKFqwWs1YCn4HQnbYTOAnEN3XgJUDoOPVWhukDCNv8DytJYHUi305lPJZP+aPScMFmcakeg4HEyjgklZU0ee2dEOcWhLd0lR2E9tBfh98in+iICX1xPJGMYTCAlo9ddDmR3RoxnJ7Fv1saUgMfPkQrcUGBbHJ0+WkG1KGEA1BCmQlr8RMKJAr+o7pvTv4MtXsqWGhAytZvJR3+diHZTsv1/fVMvqi8ka4nGzDdHX9P9Nx944KTcj2YzStrYGnw9r+iK/CKybg/fz4hPl7W1mJeOPP7etFgkLr708nEx8X+pbMXiISh0hKiG0PSE9bQpmoKWRksCyOYqObbmsDPXY4oBKZl6pKxrCkoBuAqgMIQv3uhYpB+R7JRm0C6+9PGynCxL1RSPAlQZWsqqdJRxy8/kz+r87sVPPxXbhhRdi7dq1+Nd//Vf8/Oc/xxNPPIHzz595HZ/JtlXM1MKFC/3/H3zwQRx99NFI0/pHy7LET3/609q2z/XWK9mEsygTdDsNOAc0sxKJsaisQdENY+gcQImFnZ/zl74yWHjdZUhaJUxqkaQWvUlGJiarQEnkGp0AxTDPRs21CXp7VMEUsCL09mRmoLWWWAslLZlmfU1JzAgBCMLYBBj4rfEsEgDQFFCM8Kqw2KNEY03qQyfpJAOS7vwwwU7uT2ithdczpFOSMeQYFCUiJM9H2IVd08UVgNWys+SnMleVhACb68PfVIvF+inerxVvKmuA5mY2CJ3c13AmYM4TlikDyNCfWkA67ViQdUgKh8HHS5BNsPkgg3LA+VR/vQYMDPsmP2F2WHglQEp1PQ3ANS3732hop4zWNzLpmorZIhhIDTSAbAiRkHU+/Keu2kDErlA4N83+syK8B0S/5iL2Sf2Yoon3oBUr/TlqUVsgAAUPbgQUGRH9ekBjHF54yRhP2nJeNaZMGD6v0/EggjyLGgvm+SDRfSL7TXpB+1Q7fthdALWJq4EyF22v4UUFQDqWi8dWwhiqh8ZmaQuvu8yDW+1HDdCYWVghvU/Iic+b82VZtrZ5kXk/wJ+xIfj+TV1gRndAW/iVy/heI4IT2xcyCJYF6lGWykBXzGZycodjVjQVthWO76OCYBPDmYAS2ou/Zy4VXaYDVw5QgT8h6KP6f0Y6xapIsPibF2HVO5mRmi3092xtz8VCx9oGBgaw9957g4gwNDS0q7uz7dl8xxxzzKzmnEq77ex29dVXY9GiRWi1WjjqqKPwk5/8ZIvb/vCHP+QQTN/r17/+9U7vJ8D1+Cpr0GoUGBrqoD2Qg8ghTSwSY9Ee7KE1kPsMv+ZAgUa7YGYisWjN7SLJGEgRgMZggaxdIEl5ldbdvwirvdTh0PPHeKIe4tm6ZotQAr25kgnYY2CTFEDZDAwBLKG7T4XphWUQh1YcyiMBKaaQQqEleYsClyKsthPg7vOXAMQgLB9hgKUryHyE/18MAbDwGXXOMLgDwRdz5s4jMCuOw4R8cvyjasFn/DnDtf5U0NvYyMJ1OBant9Zb9OYY2AYwZ5w9plRnBUTjIPstBoF8yKA3L0XziQ6SrkV7XYX24wwekykD05PJL8ogimvh8QOd92mEKYyzJiljJkr9xnxmoDZlTSgwGY5ETyMhKdNJuCSHDZOpo0iMTQFAKXunZpa1MXZhe201QKaMj+iqFIgqs6Xu3SQAMC7TEpei8QxB7GKuLFdFuO/MJTyujmBbjmsnxqArZnMigHLPp5agbEfHiM5Fx1DP874zl4Qahwj79durAF/HOuNixDoGDyx/cvE51ELCgIGBgugYs2i4MRoD08ccbmsb//ByZoPiffgbPBwXhrVJfI8KO5e4rWKlRr96aXiJJcLC6y7zQAoI3wGtJ1k7bwJ72lmELGLNJJWCxOQCIIfjxYSWKHING669gEBl8MioBlKYKk3siE14AR4ja7D6XWf5zOrF37yIgRRht7FOeC5m85VliXPOOQcjIyMYHR3FwoULMTIygk9+8pMoiuKpd7CT2jZn82kxwf62bt06DA4O7pBOban9zd/8DT72sY/h6quvxh/8wR/gS1/6Et70pjfhrrvuwoEHHrjFz91zzz21Io4astzZbSDLAQCJsVgzPYzhgS4qa9DtpTDGotdtoNnK0Wrzdr1uBmcJabNCKeE0k1jk0+wombVL3Pfnn8Qh///zgdyg9ViK7r4lYBwaazLYDCjnWSRrGxh4hDC9n5P0awekIZ0+6fGru6ewThRNmoYfYgpwSABVNsWfyefxg8k1LIq54Ida6tB6NPWeT4edOwYaYtBmSnl2DvPnqQLyuXyo1lrA5fw7lUEADMCzVLH4Fw7Ih2TCQZgg82Fmony4qASMsBZlm/c5sIZDJ0nuMPd+Fk2bHnEhZ53oDWrhJyP4phgk9PZqo7EhR9IFhg2hNzdBtgHIRwiFRGadGnVqi+qAecZAJkuXgEMX8nR31vBKuWJhOunKXcZA64z5hIEEPEtFZV1qVg2GxdcAh85sxuPpWSvxHKqFgkRL5Vkn2VUt1OSBF4dOPbOEiNmSD9oUNf2R7scl5JmYmJ1SDdULLxnj2c05r9+LrQ70XDU0WzUAGMchwlTYjkYY6zhzTzVXh1w4BqN91VPzYCNQVc44DhllFphOZGyfmsWhxHH4XsK4MVitjaOMvTdFdWDWZhaX9YXXXu4TDMY//CSMlYKMfr2VB+Va89D59ym1GD/h41vc5ehXL/X99pmnBDgroUWDUJcyOm4Qf0cLCbU30PtCKwMUxKFGS4As2sx0wsWK5VoREPRWsl+Xsfg8roEJgrdCcGr2aUmyCQXcJhajN14CMoRVx52Fg/7mQjzw9k9seVyfhc06Am0HINodBeinnHIK/u7v/g6XXXYZXvWqVwEAfvazn+Hcc8/F2rVrcc011+ySfm01mHrb294GACAinHDCCWg2Q6Xqqqpw55134uijj97xPYzaypUr8f73vx8f+MAHAABXXnkl/tf/+l/44he/iIsvvniLn1uwYAHmzp27U/s2WxtICxQ2wZpNw0iTChs3DcKKmePgYA/OAt1OA1mzZHlBalFMNoBGhUa78ELmrF36B+8hN5+Popdy1OiQaaROPKvKzD+MqWAgpaJeP2lSYAdsgycpn4mlrIM8xGxqfDkR/alaHde0MKllQSgBrjDo7lWh9UQCIzYDml2nzI9tsAbKFPDhot48BH2PAgzw/1Vo7k38lOWxIZwHBPBlMy6SbJPIeJIYZLXXWWTTFkm3wuBDOSYWDSIfNDDiL6UTryk49Ocf8tKnKiXkQwaNDUD28AZ099oHA2vY3yrtcDJBNRDKooSsIfgZ2gMdCe/YtvUPeVcYVMoiKUFVGM/UxJMw+0nBT5bKTgXdkIMz4QH5wkvGgo9SAq/dgiMeRwE7cTmiX5+/hI0tSSaovjIvJMzOYZ8Z82yUAjgn108BUuwW7sOHjgcoDsUh2odRV/ycPGuj10O1UyBh2hqoheGIHIzquaQfNXYtbo77FNeJ4/7xQRSscTaadN44n8b/ZM0Le5NgIKlMr2ctlQ1TKwrD2yNldmb8+ABuRq8X1of43Ea/fLmvfzejiXjbKTCRzqhwe0YSgTBIs7XRr10KHUwnTJ4yeLWi3U53JPe0hFGd0oilAVIH0zXBEDZhXSflJpw3+HCmAlAZr1Vzxvk+Ogsgc952wpsMt+U8Ewt0E7Gk6ANZFoAhjL+Hx3bRX1+M1cedBQC7HZB6rrZvfvObuOmmm/CmN73Jv/eSl7wEBx54IN7xjnfsMjC11WG+kZERjIyMwDmH4eFh//vIyAj22WcffOhDH8LXv/71ndbRPM/xy1/+Escee2zt/WOPPRY//elPn/Szv/d7v4d9990Xr3/963Hrrbc+6ba9Xg+bN2+uvZ5O+/OffgSlM5jKGzDGIksrpA2maWxpMD3dRHswR7NVIDGWPacKA2pUMIlF0WO9FRlX01YBYMNH41B1UwZnBBRzLfK5Fo0NBtWA9Q87KsnX8nMUmKjJA4QJythLqrugChqgSHOjYKsY5Pkk28SrPROvQglecFwO8Gd8jb3I2RhALVyjAIpDdAj11KIJuMZMCWviw0YpM2YastLSNF5XI+erIS5nGB2kHYvhhwvP0pmCQZGagyZdeb/kbMJigMN9xVAKO38IzXU5Bh6vfAjRsyuaTTfLpI3EyeTvuPxFi3VvrhCriZ4BphMW4RYmZOeVoYyNI/CEE09iIu6tlZUxQZQe+hUYtwDsnB9Tnz1WAUecNRaE4Y5Du1RGRqFWXM8NomOE6+QzCWcZA5eKqFvHKJBzITNL7w/dbzyemmGo/dbyLgJGXBbuuf4yMi56+d0piI2lapEeypfgEa+3/s8/ZesbFx8Gi0O2mYVrOGZYUgcktg6kvhbVkIuMX7fYIiau9nbERMV6M5g6cNO26OsXhwtZu0aakcr3OiWuxkppfcrx954hJqVyP1eAbVmv0yLv/h+dm35/tIYhwGALAFIbngGJY98oLSszUMlYS0czNvlEw9YTQvxJAKNfu8TXRj3oJrZK2N3adtXlcxHo341aq9Wa4TEFAKOjo2g0Gs98h6RtNTN1/fXXA+AOn3766RgYGNhpnZqtrV27FlVVYe+99669v/fee+Oxxx6b9TP77rsvvvzlL+Ooo45Cr9fDjTfeiNe//vX44Q9/OKuDKgBcfPHF+MxnPrNdff3zn34E3YpLyWTGokvAxEQbcEB7sIfpzS1/E+e9DM1WzoaeBMAC+XSGxkCI/WYtfuLf+2fn4JCbz0djKGc3dHKoqmgWIIfeAQVoMgEkjGOzaNUOBjudfdmBuLOvq+l7XOJAPZ6Uu/uVaD2S+kw+kBQ0BoCugcsk8wxsVonpBL09RXBaEZrrmCEq2/CCa5IvrwdDiZyyCM51gjG5sEXKbsTzR8ROpB14fUxrPTutT+9FyCbDJJl2nTAkBFNYtkYoHKqWQXODQ9UgrsVXBKDAjJpD2WJRvU353PORFLYxiGyCd14zwlRmRScDDTUImGHRm+VHvfpTVQQzlcD0CK5MvEll1XQ8L1gARpgNByAhuJTCCl6ZFwEpniUCn8chF45xVywYIEegxwqQdQp0Exbpw4Wx8CaINoyzAlPjovHSMByh5jkV2xrEVgTsD9Q/04fr6qKfet395sJe/frTS3DwZWMiEq9PlC7h8EWMpVT07UF8xA4BCs6cB0/9tQhrpZe2Ekwpk+vxCNXH1TvAC0AmvW/6DjB+/Mex8CuXBVNTHYcttBpb2f+3GjB1HpiM3ngJn2d/CFMZJwVQauvhmcDwf0Sh2Afffwb3mWR7De2JHYKCawBwqQ0MrIZF9TwcQAXBuERMO5mh8qFGhxDGi9hJvlbO61E1zOjECJnH9UwALDjfXTRS/Y0B0bag+5mf393aySefjPPPPx/XX3+9j5D1ej1ceOGFz35rhLgdf/zxvkpz3O677z6Mj4/viD49aevXa21JwwUAhx56KD74wQ/i93//9/GqV70KV199Nd7ylrfgiiuumHV7ADjrrLOwadMm/3rooYe2uY8WhFZSopWU/FCXh0OSWXSmmmgMFmgP5NE5AYYc0qyScyLknYzDedEX5YV/e4H/f1UalHmCB97+CVTdFI31RtKbbQArOmmTAwZLDq3tVcEOVKgGrC+ATAWvvE3H+PBZ+6EU3RcU/rmedgN703okRTXF+i7NPqPhAnag8q/enha2yVlxWmvPZx+mqN156mfk2RMn24tFgWZVJd3ob1JYWdmWdNqhamk2m5OwnZhzDrG3VNlOUA5lyCYKn6GnRZRVSA3IxE/kxwLELFs+xIORz82QDxvvn6XsDX8Y3h/IF0ZWoAVhB3TCKrlMTdKVV4dqPkpkgy9VkhPSjmhwVDgdiad9Or+LWAMXjamcn2ZQmhzeZ8yl8KygsoVqZBrrsB5YtjSwQX3AghxCyDZilby4PD7/uFH46aJ9+SLAGuKLmRQAh1wwxoakpy3tY7kk5JOoqBo+jK2Mlv+p4Sav3Qnv6zmvOm2pz4xlnZZjE9QnaQuvu4zHvy9E6+/9+JwlNByAFGaAoNHrNTNQ9idjXCs8XBvTOhCMj+//Fi2geL/8htaOdE6y3Vz9PgMguiPZl7+ejrV+FMaAchMWa/o5KXvktVG6bx0rCVHaBl94lzrYoQp2sPJMfQzk/H2RK1Lm56dajFDiWJIgGi1SIBe13RVIPVfb7bffju9+97vYf//98YY3vAFveMMbsP/+++Mf/uEf8B//8R9429ve5l/PZNtmAfoJJ5yA973vfXjhC19Ye/8Xv/gFrr32Wvzwhz/cUX2rtT333BNJksxgodasWTODrXqy9spXvvJJw5HNZrOmB3s6LSWL6TJDbhM4B3S6WW3FV3RSVCkvT23FYCsvE+QbWmFiLAnUMyj36iJrlTNWH2mDHy6H3Hw+knWD6L6g4PCQamEqQI0eXQYOC84vgF7iV/rVcMV0euZCWKkgIAG6CyxMJ/HApUjhy43YVFbqnZQflhKWIgd2JgaQThg/IfqHl2hqlG1S9skIZqOKQYsXohPq6fMZaqVk8hE2B22tYzNNLiHDx+zuwbULybFovRhMkXSZqRr6rQVZoDfMHlpJIcArY/1Z2QKMHN+ItQIcUAwTOjaBTdkvK2bPGLwRz3PC9Kj3kk4SMbPmyhDCM2VYIZbtMKEy48TWB6qDMoVMeBrKq9EvEQAxYW7Wa2BKqT0on7EWQENCoGp7EIcBAaCC1EQTt3TiTLZDzx/zujQFYR58qaBfJzuAM/8AuIRqHmNeKxfm5DoxE4iKethOzmvxZ1fyBO5L0chnrBbWnblPBYoq5vf13iyCOBuIkgdk/ylCRYInaQ++j2vxKVCoMWt6jl4EPvN8QRLac8ykwEopW2XSIkZttkbCssFQsBbp7/csYS/fARe9pzjKgoXOujAQYGKyCjZP4Eq+gZwDKOVC30gczHQSni+lZAKDz1/vS6ooFFXXZ1astTMhjEjk4OBAqXyHLH9PSEw843MhMSJWQGVLXnCOv/vMLQ/ebtaei9YIc+fOxZ/92Z/V3jvggAN2UW9C22Ywdfvtt+MP/uAPZrz/yle+cqdSbI1GA0cddRS+//3v40//9E/9+9///vfx1re+dav3c/vtt2PffffdGV30rZUUyG2C6TKDBaHZLFGUCaoiARmHRrNEd3NTjBotksSiZSzMns77T5FxaLYKzvBzHNIriwRpo/J6KpsncJbQGp2EqQyKdS1A61IRA6pqgfhWgQDj0FyTIJ+r5RaA5poEZVtSkXuEclgeWrIKT7ohdGMihqX1aILuC0oBcAFEucxJeRBZhZfRc7lQ1gf8MO4Tl1uZ0L2fXwpAtVBgQ9BigD9TDrD1AcKCFM2NlgXlGZBNEab2BwYekc8N6uROqBoG+bAJEzrgwYpquGwm75OAKQuUoscp26hrcgSouBRsv+EQXMNjRiViHoxmhsml8d5IxKE+l7DxJTMXYfaMPZmcAgJEx9Bf+yZPHzKNmBifMZlEoFABlTIg0i9TAs4S7v3EEhx63hju+dQSdheHsjnweicdO98viHbNEmwamVbKfaB96c/Ym9Gi8VL2FRJKU+CtCQmhtiDVsIJmGsYgDcTZnUHHp2Md7gntn9laR/KI1fTgRLM7Jey0+pSlDLoAn54fgB//x78Xffe2pIny5xiDaRkHpyec1LclvW9q+3QzAMfoly+vn1Ml17NMoFYLVBFrlRILVyYY/9DpGL36Ch+mdoljN3NB0a4U4FWIrkq+I07SLE3OHmNUGCCt/PkmDYsqN6KJih8YJFUEuN6lB9YOMIlFmlW493+e86SXbXdr8W3xdD+/uzWVHD3b2jaDKSLCxMTEjPc3bdq000vJLF26FO9+97vx8pe/HK961avw5S9/Gb/5zW9w4oknAuAQ3W9/+1t87WtfA8DZfqOjozjiiCOQ5zm+/vWv4+abb8bNN9+80/r47l98ABYGeZWgW2ZopSXX5LOEoaEOijJBZ7IJ0+SxInLITIXKGTQyBl1ogZmQIvEr2qLHl0pXW7ZiFJI9kaFol/ywmN8FAFSPt4P0wv/kr01vTzb0bD2eoNLwm5gi2gZC+nrm0FibeF8iEO9C0927+5WeyXINK15Wwmz5HGYO8VkFG8IoVe0IFES6o5hJcUkIu2n5k3yOvGd5wk4KBmDdPYCsA0wvMBh8zKJqkN/OJQyCWusd1+ozQHdPnu2dEZuI3KFsEhuByjnCQXy1wvlTBZ8tqM2HiAiA5XCiqwjIAvPhWSn9TEkw6pljHKom1cxRbSOqFwh4zYnXE2ko0IK/wboCjwBUzZNJ/qb2D3ddtAQAl1ohuTZxxpyyhE7O2ch5OgJedA5bCrzoU4GZ8hgxysb0vlIRQ6YsBLn68dRviQxqXl/9YMHrqOSetmkAVcHJPnzYj6fon0hS5ZURcYaZjarpwlhHIm3vem5YF6hZhk/VfKFhOBlDqrNTcj943yplxhxFYbNZjtUPemao/INpZs2OQfcbn2MEJHV/s4nQdZ8ECsfXkiwAJ0446aqwTjZnMeTCay8Hmg40nbDkoCVAy/KOahmEauWQyk0rDLlriqGtno9hsEjRd4rUU0NYKGfJPydNwh5u9/35J2c9t+fb821HtW0GU695zWtw8cUX45vf/CaShJ+eVVXh4osvxqtf/eod3sG4vf3tb8e6detw3nnn4dFHH8WRRx6J733ve951/dFHH8VvfvMbv32e51i+fDl++9vfot1u44gjjsA//uM/4s1vfvMO79tpt78TPZsiNSkmixYsRCBujY/hd7oNVJXBwHAPRSmsUrMAEdAwFSoiWGtgxd3aEABTwVaErFmiN9FET1dwIk62LQdbGtheglRE68neHZRPtEHze4A1IMNWBq4iVJlD6/HET3Qh9Zj3l202tUm5t6dFtskgn2fR2GQ8e9B6JPUr9t58nbTJP6TzeZyCnU2E/ZmShdwmF4ZEfYj4NH32edIJbICGirQwr07YpgB6c+FBiDNAY4JF48UAobXRghw/6E0BDKytkE0Z5HPIh7VggEqz/JyAsxTeLsEZ/lkJa9Na79AbEbaCAsgCAnsD4v1DUrmdTpZa461CYPE0NBGba4qgmiIApdmQSnDwxvD3gXPkNVseKEQghwQgKrB50TljuPv8JSHMItenlu3nAGMlQUoASCIWGT6sF36Ee2g2sKH9kHBoDRQY7ZuDkVDgjFBf1PRcPOgqOARmKqASEOrDhwYgOA/gVGRetWWMpQah/xuAVR9dhkWfXyFWEg6j11zBmkzZ6VbXypPvEwQDkCWsOm0pFl21QsbKIb534AwLsT3TGL5LADjMqABbx4cY6Dz4/jMAiE7J+HWTz/J0qa2B8RhAEcHbBMzWvJO7IpeohAt8TU/yzuSoyDNDVHICh3qkcRhQLBNyyWKIs1D1GSLjZ9tKsVsuKTOomSwMmlABq991lmThuSBKN46dz83uVWfv6bTnYphv3bp1+NSnPoVbb70Va9asgbV1Gn42U/FnopGbrWLxk7S77roLr33tazF37ly85jWvAQD85Cc/webNm3HLLbfgyCOP3Ckd3VVt8+bNGBkZwaZNm2rGn/3tuF98EKVNkJoKpYT4HpscRmIc1k/WMx9tRTCJQ6tRYLjVQ7dMMdjIYR1hottEXjDGraxBIoVve9MZXJEEQ0cww+FLNaQOSC0S0VIpO2XncpzNpBZubRO0Zw/Nu9oohuGFxC51sIMVsnUpp8FHBKNOMvm8CtnmpJZi7wwXP249miIfcbVJMpsg5PMs0gmDpBf2QxWC75GybnO4OK43y5Qwm2b1NTYChbBSd13A4SUFZK11vJ+0w8WMBx+x6M43SLssPrcJoTHlkHYsGhtLdPfMUDVIbBsohKQcM1TsY8Xv2wb3M+0CJncMBhuEfBjQ0Jx6ESlA8z5eakchnkEQ5orZOP5peuSL+SZTPEDVgLBMOk5GM8wQSrfoZGnCL94UtF8A7uAZOu2rCtFtGq6FB1LRT95hNL8pmGowu5h06iG9UAw5ur4U9SUSkyvYs5kwQwmDm6RLdVPWWZpPsCDMYAltg5MPlG2tGZUawLYCnabXoabZkjFlYKvXgnxWGVng/tOfXIAOiMml2ARoKDwGQTNYJgeopUVN/1Nw0Wif0aksE4XtH3z/Gd6JvPY0F6Ym+F4ggFTpz5MZdQLCsjnwM8ZAQJ2TzDrZSEFMZFrrpHSSgkZSEKZ/zw0oc4DU4GPg5WpjwfeS4+1UfK7d98ahmq0H3wciN0NUfvD/cwHu/4tnhp3a2jljRxxj8VfPRjLQeuoPbKFV012ses9FO7WvO7q96U1vwgMPPID3v//9vpxM3N7znvfskn5tMzN1+OGH484778RVV12F//iP/0C73cbxxx+PU045BfPnz98Zfdwt2mCS44lyCA1TIrcJcpugW2TeYdZZwuBAjwXpvQb7TiUWc5pdzGkCE3kTmalgrfEPCENsfaC2CbG4kyyhsTaFzRyqYQukFVwvATVLOGtgFnRR9XimCeJLx4vHFlAOsclmPuKAeTmoYtfzihySbpi0izmSVdPgYq9kASTkdUxwhHzEeXAVh2+aT5h62RKIaNuGbDytsVXMrZB0jOiFBEjJRF21eduqCRz+yTHPPCiQKgZYF+XNP2WiLYYI6TSQ9BySrkXSLdF+wmHigHqCgYaabEb49y8uwSvetxJKEahretphGwXbEMZGNV8CEowFUAVvraDH4QOYToh32ZZl80LRolFBqNrOhybDJIXAcJShP3V2JzK/VCCFvt81TKsEgIAQsmAdm4n268I+NETo+6NsHPj6VM0A0PobRfuZAaZkUvf6LekbRf2j+Li1ixWdh1o36Hs6UTdcFDIOlgaqheJCwvK9zFw4nmaUOdEqxdYXKoze2oW8MCOQgrz+fvDFhV1IHpDr6PurHXKG8U8Z/U2vu9xXVEk4jRA650uryHaaThndM3gKRgpgnRT1TEh0qLRf0pe+zDhnAVR8n1P0GUqUAoVn2JhZmo3eRMj0k1CgKwiUCIDyIUrC+PEfx+jXLgn7cITVx9W1Xlpzz9m+7IXflbadzNS2maY9O9ptt92G2267DS996Ut3dVdqbZvBFADst99+uOii3acY5M5ub73tFAxlDVhH2Ji3MafRRbdKUVnCYDPHRNVCayBHt5fBAWg1Chjj0M4KDKU5JssGBrMcGzoDUpiTkKUVysrAuoSfnZrRMpXwSk0eqNVIxaUuOglI0olNYuEcCzWdg3irONC8HERAvkcFOM5asyMlIFl56tSs4YTeXhWyDQmKfXJOc47Ewio4bkrIMJ9fIZ1MYDMpShtNpD4jSJkEYnbENuKZH6haFlQmni0gx6ClirCPCut9+M8DCYckCnVVTdbMVA3WUo2sqmAzg6l9G56x0Zphd3xhCX7/I5xq/4r3rkRS8ISbdsMxbUYo22EyI8BnvpEV8Kd1Dg04a805MTAErJa8KAjeuVzE+cpCqXja5BF9YAlU8DVxJNfIRMCHUGMSYxDjw7UV91WnE90+6QT9mg+bzQJiFKzEbJCaq/YL2n2/tC861spWyfv3fHIJl40B3wskJYxUT/Xrc5fgkAvGZvRD75UYUMVsjMkJtqWAKTofcj7Zgb9iQehMqm3ygnbUwQkQtH1bOfeMH38mRr92qWShOe9v5Dzj5zw4EljnwQ73L7AtPqzvN4k31LEPHfOgQ4FHMlNQ/lRt4VcugxHtExzxPaSADAih65hhQ9iGffDgQRUZB1fpTcDvuYL7pguxmDVzUp/PO6mrDgqyOKyMFCQOIGk2zdeqd54tLue/2+G+51I77LDD0Ol0dnU3ZrSnBdd/8pOf4F3veheOPvpo7zl144034rbbbtuhndtd2rdffRVSmblym2BtdxDrpgfhHGGy28Rwu1sz10wTizvecj7mt6aRmsp/tlukPgbezTO2ADBc5NiqVmooCGxMAX7wlEyVax0sKw8ykEPz7jZMxoIbNrADkrm5f2ChZ4DMItnEM7nXLhGACigHGaiZKaYBlNGIi9qSA5pruXxDcz2vWMsBh3y+QznED8CkB58xVbVc0PCUBNMTvyUpbKqshLq1+4ctUGO6qOIsveYmh+kFBgOPV0i7fK6mcF4w3Nxo5WFNGB7vIJuWbSpmg37/xDFZbXNfK7VgsPAGlsUAefAQhL0RCCGecE3JY2gKcHFW8dIxueFwm4Y75BwT8Y5SwKTgypQ8NtVghaQXbBS8l5OMU9ILAMRn5Kk2SZvjPiUd8ZgqACoiE1ZgVgAF8Pjq7zEYdqJ1qhqOTUZFr+QtLQRYmWh8NNRoE3FQjzLuag7khv8eM2Jyy88EMzqRRyVUQu053V8EOiJma4aIuy8UtupjS2eO5TYt5KVPyoJVxNlsyjQn8bFnPz8fyo1YwRqo6TsFAPAGoLLfbQZS110G6iaBBVNReJwUIewUKVsF+V29o/R5JOjelRLqTEWIZxF0Vg4+vKp9js8FAIcJlemz5AuD6yKz/xwXff1iNiIFfLmY38X2TDugX3zxxXjFK16B4eFhLFiwAH/yJ3+Ce+65p7YNEc36uvzyy/02vV4Pp556Kvbcc08MDg7ij//4j/Hwww9vVR+uvvpqfOITn8CPfvQjrFu3bodULNkRbZvB1M0334w3vvGNaLfb+Pd//3f0elyMbWJi4jnNVk2WTQykORoi+MiSCkOtHogcukWGvEww2O6h1SjQSCr8+U8/ggMGN6BbZewzVSUoygS9gm0PlJnK8xQOQKNdgIzlh1LOD6bYw8elIXShs0XVTZEf3vEgSx9CzgJmbo5qQYHGXh0k6zIRXTtULV7RloOs1Uk6Bsl0ADnxCt3pBCBMUjVgUQwD2Wbxe5KJv7EJSKeB5kYGE1QBzfVAYxPBtvg4zbUGSZdqoapiEH4SibPRkmn4NH6yrJca+i2blU7tncJUzDq4lFmtfMhgekEgYcsW+UneVGLwKUaf+iA3FYf3TOk8E2fTAAh0G1NGfREQxYaYgCkYJJIHUVF5GAj4yomLSOcCqBTAyb4bT4jQXyd14+cnP+6+KcBzYWx0PyYX49XpUCpHNVAaOvOar+jaJt0w7jET5V8pnxuPj06qYb+IkggUCCtDZHo0IxzoWS8N/0XJArV7jqJtUgfbYJ2UD53qcSWTz0oxZO4fhfFS7U0kstZjHLRyZY0x0XPe2jZ+/JkhS43gQRTFhXfjrDQ/DtIPYW2gJqyGgeL4Scv9mI1/6HTAAeMfPD2MjTZ66lBef1t47eUwU4lnXGuhPIdgreDC3/x4+mLeojGTYs9KvzlLcLkU9C5MFOYk//3QfWsGpA/7AexdJRKIVX95NmxpQMbVwNLib+6eZWGebvMGq9vx2pb2ox/9CCeffDJ+/vOf4/vf/z7KssSxxx6Lqakpv82jjz5ae1133XUgopo31Mc+9jH83d/9HW666SbcdtttmJycxH//7/99qxwB5s6di02bNuG//tf/igULFmDevHmYN28e5s6di3nz5m3T+ezIts1hvgsuuADXXHMNjj/+eNx0003+/aOPPhrnnXfeDu3c7tRuPvpqvPYHp+OwkTW4d9NeyEyFyaqBRlahqlj74Bxh/sA0DDlYkNdT5TZBp+AwYW9DC3lqkQ0WsBVn4pV5iiSt+MaP6PV8T7nxLOoLbMOrtqRZMQCzBiZ1/n0rLFnSLKF6FvuCLvBEy3vJOOMYRMWrZQskPaqBmyTnUBpZoLE+QWMzT34FwYMGX+w4gwA0oLuXE7ARJl+1Q7DRXanJPGULPtW9Eo+p3ggDmu58g6FHKjgCBh8vMblP6j+bTQGNKV6CFcMpsgkpMWMd8mEGpQau1gdyQNJ1SHILl7AZqE1DtiEhABUfmdCISMQOhdU7T/Q1QbaybyUiNqmflpDjxeAE8NfMd0Z/upmfVUBDlbBYVhklzGhOLjdr2RCE67qBTH4qXK+diw3nWhO/K4iietYeOeCec5bgkIvGfBjQh2xdDNYEAJUMgGularTfKbxjtmatqREkZ4vxcfsZHA0lxVmoNQ2QgjYK7Nq2NlcYn9XPrtzWu4wD0k/joiK/BKd+XyEGKDoi/u/oNVfU+jL+odNZ3xRhRNDs9faerI3+1eWhDh4QmDMtASOMkvdzKgTZx6aicbgx0lg5Na+Nx7oSBl1qiNZsISRM6Wv+FcTyBhBMUuGgv7kQSRT+P+imi6SIfABxv0vmnM+W9k//9E+136+//nosWLAAv/zlL32Jtn322ae2zbe//W0cc8wxWLx4MQC2UfrKV76CG2+8EW94wxsAAF//+tdxwAEH4J//+Z/xxje+8Un7cNxxx6HRaOAb3/jGrAL0XdW2GUzdc889s9a1mzNnDjZu3Lgj+rTbtkNGnoAhi3mtDp7oDCJNLGfkJRZFmYDIoZFUGEgZFazrDWGP5hQqR3h0Yg5sZZAMFrDdFNaKG/dkA6ZRwZYp0maJojCAIWCg5Ad1xeaOAFjI/HgbtEfPl1BgWwae5NUmgaIwgXOEYn6JBEA1WCHdlAj7I5OA4YcogbOikh6bViqAKobYGLOQRJByULLFRPdjegxCrGiCmut5gq7U86cKJVRiH5+4pEnVCCG/1hp2Pi+Gmdlpr3WgymF6zwRzHswxcUADpnSwDZ5UsyknmXgOVdPAFAmSLoMktVzwYSgFN8JYmZyZDg2nmhI10XBs+omqzpgo82UroHQUNDng7DV2e4bYU0CE7vBhNG2xcFuBi/egmgVAKbABAoOlLJVnrhQ4+rBRtAudvxVQIWJkovPTci1UAVq3jcct9M0BNQBjmzIxCmA/9PwxP55Bp4QaG1Q7b2WjjPPzMvfPAQMV6wblnnUZ0NhkUA664BcVMR+gCLD0gbgQOuQfq05bikWfX8Fatj5AtlWtCmDDyULGl/wBg1CnXzI9ZQqf9ddaHd3lHMY/fHr4gAIZRW7b2Eb/6nJeAQGhBIyOj1gY6HH9IfQ5omRCJPT3EbskWBaA+BkFAruhJ5VnnvypK+MV/V5b0JGUhwFgjMO9//McHHTTRQxSXQqCw6p3Pof0UTPoyKfxeWBGeGxrK4Fs2rQJALaYfPb444/jH//xH/HVr37Vv/fLX/4SRVHg2GOP9e/tt99+OPLII/HTn/70KcHUr371K9x+++049NBDn7J/z2Tb5jDfvvvui/vvv3/G+7fddptHns/VVjnCRNnytfgaSeX/78DAJSWLvZqTSMmikZSYKhuYLpsYavZgEgt6tAUUhGptC9V0ymGhxInlAdAYzpHN78IkFkm7BBoW1LAyiRJoz55Q6vLQJinxIHopZ5kaN6mFkfcac3IPvsqRKuhvLKTcCXkgpZopZQk4hMXhtHIAtVBIOsXblYNAbw+gajuUA7ydTR1syqndzfX8nj4wvf9RJe7nhFAMWRiRxmY+ztTeBGcIA09UmDigAXKultqv4amqyQLysm1AFQOwbMoJ8OHZwVQcMkw7FqZwQBJq/SW5gKkodBZrlLS/Wusv6UkdvA47qGdThHSK9WHppGGdWEnBFFUnnz6W29tQUDiWMkxxSLQGuhCBqpjRIh6L2MYB4NBf+CBq5pseQEntPhuH4YSYMGIZoF5gqq1RDZVN+Np7PVPmvIA9Bmj+mPqFAXxY1M8XJujt1OwTADCV1MJMANt52IatT856DNs3CWmx6GisbOpQDVYY/dIVHMqMix9vZXvwAwJ4VENkCa4w3NcyvKibgGRxpMyaL/4LBFZI7xVbP874B0+v9X1bnuwLv3JZAEuAD6kCqGdVkgtg2SL034+nbFaE6+WUfdK+iX2Ca/HzTC0TAjDmRYevoWcAwPF25JBkVipCcL8O/dZ5Il0wMIl9bgEpYIdppg444ACMjIz418UXP3Wo1DmHpUuX4tWvfvUWLZG++tWvYnh4uFYn77HHHkOj0ZgRktt7771nlIubrb385S9/WjVzd3bbZmbqwx/+ME477TQfB33kkUfws5/9DMuXL8enPvWpndHH3aaVNkFepSitwV7tKazeOB+Jseh0G7CVQaeXIZ1j8URvCK2kgIHDYJrj0c6cYIXQtuJNVPGqzhGqTgoaKEGJ9bYJWmImbbPpZ1E1QFI82ckKldQEU7JfktSyOD0JIMtWHOqylfi+9MgXwAWY/YnFzXAiA5G6dFXDobOA2DahIhjLRp/tR3i/VVvKr5BDOqkrXw4X2gywmUNvPrM11YBDY0OkByO1GuBJjHrEC9UK6M4PbBXX8iO0NlTozku4FqELr1jnkg/zL+l0hWxSESGBSsdsVOlARViZu5SQTTO7UWV1TRc57gezY4CWpGENFY9HJdtr+NKox5aGsQg+ZKru8jxIEatjgSRyNJ+xEI0Alf9cPztBIUxZK7YLAbK6nwgIAfwZBXO+5I1uHrFYCorU9BR93k2hjJDcdzpOykyijxWiAOh9BmHD+QxQEg8p0s9UFJgmTd/vGu8rRVF5kRmsnoIBROyUjqeEqqhivyc18hw/cTm2qblwneMEjrgvXPePRfSkFzq+1hT9dMDoF68AWpyxq+E5Z7g24Na2hdddxqVc/Fg4318kgCPnvaXQf+8ZBBuDNNxwrmnDPanfXfW7ik0+o+8SyAGFlIiRkjRIIjbMWJ/NR3EfiX//XTfn3NntoYceqvlMbQ0rdcopp+DOO+980sSz6667Dscddxxaraf2wnLObVXI7tRTT8Vpp52G008/HS9+8YuRZVnt7y95yUuech87o20zmDrjjDOwadMmHHPMMeh2u3jta1+LZrOJ5cuX79TafLtDS00FVMFbao+BKUwXDSTGIk0ssrRCw1RoJQVSUyEji6mqwSDKcjkZu/d0qNguzRcrVWdfCyRZxSwT8d+TdskPYwUQ4JRv/TvIwVpCkthov4Q0Yy2WLRKgw67EGm7TyS3JGVSpELqMwIopCdWA5edkDpRDQDrJNgoqcnaJQzbBE4NO+GkHqGRyyedaDotFppTkhEFJIx8g7bcJP52BmGw6dOcxWlDjTyOgqGpEDtiObQ7IAaZbwpQGVYN3aEoHKh2osgARqqaBI0LZ4gk/KRyQqxCdkOQOe9xdIR+W/HziTEDuBF84Iyt3BQ9O3NVRijZMRdk+RIIw8YL1Yj5Mp+GoaFIlyLhLvcAZ+iodM5Jjad8Q9jFDa+XCftT82wuSDRAXA1adlSkE9GRcrDnp8hhzySIpyqz6FwWTJOcnoEjDeB5H1BgLF9y0hanylkOOtVouYy2chrts0/p7qnZ++nMWUOoz6oSVRQG4yKYgPo+tbnE2YV9/Yq2Y9psirZEXsAP1a2XAIGc68WH78Y9sPcBb9PWL4SoTgJQCIgWcelw911TH3dX7oUCrpFDcu2c47JobBkaGDTdtKcJCsoD43jFYZYbKIZSO0aoRTv8eOcb7sXOEe992zlaf8+9km23htK2fB8t0tsW089RTT8V3vvMd/PjHP8b+++8/6zY/+clPcM899+Bv/uZvau/vs88+yPMcGzZsqLFTa9aswdFHH/2Ux377298OAHjf+97n3+NapQzGdnZZuy21bQ7zAcCFF16ItWvX4l//9V/x85//HE888QTOP//8Hd233a51qwy5TWDIYSBlR3NDDtYazBucxt5DExhpdDCY9pCRhQWhnRSY35xCYiwaSYVWo0CaVLjvzz+JJLFI0wrGOKQps1IE+IeKCspN7AzsCCazPoynzQgQs7aewVGJlgsO7GqM+uQOwHvvaJaZn9wJXjujoZ6kGwTqNmPNVOsJnljz+daDst5ch7LtUElY0WeQyXHLAWbp4MAmlzlh8BEGa3efv4TBlui2enOBzp7G64441BYJjgnMKml4zgKmVyHplkg6FUzhkHYqpFMlkl4FU1iQdZK9yM7ncQYbueCWDgcMPtJDc7MFVRwG8XYAAFRrZQp5XzLr4iw71omEca8BR7lUyhDVjDnlQVo1EcIxMoZ+f0l93zVrB9mHgs/YI8oZhMzCIlx7vpmi/imLI5YQPpTYYFbRZm7mOQnr6N8zdcaj9n/ts97zRfijD/EpyCz1JuLfx09aXjfMpOgl2qtaU+DYbytRShamJWEUt3H20ps7sg2onafe96JPhDJiupFeV3UYp3DO/XYOW9NGv3aJt1PxwEnDarpvCds5Aw+kAAQ2Kt7eMZDypqiZA8Ts05UmKvNiPUKmrGJwpou/kjjLUfRQnoWS2npkokUEAGvp+Xp7wDOezeecwymnnIJvfetbuOWWW7Bo0aItbvuVr3wFRx111AxzzaOOOgpZluH73/++f+/RRx/Fr371q60CU6tXr57xWrVqlf+5q9rTMu0EgIGBAbz85S/fkX3Z7VtpE0wWDVTWYEOvjcoaWMf193pFCkMOm/I2RhodFDaBIYumKZHK/ZwmFr0yRWIcXvrdc5ClBkWZIE0rdDsNNJqlrMR5exKKu5KsP1AU6gDf+LZiLYGagWqcnB9ODgaWP59aJJlFtbGJfJ5Fc50JD2wRSWt5F88gSGhLWZNsgsu02AbX62tslI8LG2M6xoeKTElsw6DZQyQPYUco22ybULb5PLJNCZIuZ+/pBKphMSP9yKa4Lp/aF1Qg1ixVDHoaXY0lAaawSHoVqKgAIpi8EuBUgUoLlyU85yUkYEMMFr1GCKDKsXVC4WByi9QWADIUAwZVI2ISZHIyJYASoFTmKrU7cFz7j3VIOvGHz+s4GwVRfYzNjNV638TqHcvLCPAIQIlF37Vstdl+apes3D+q30EE5JyCVfLgwGvXEkQlQ+QDCtz6zsGLzSl+Q8FeSFjwf+9n1ghwqeMUeaNFrcU6RNkeHRs191SAo0BPtNGs2ZIxk7GgrE+w9FStH3s5GSPFS8r+KOPjUF/mkovc29kMlgfIAanD+AdPD07gT9FGv3ZpAGjar7jeYMyEpS6IzzWcp2E/CyCLWTMx2dRyOAYgKRXjLLG/FAEE0W5WxjNa3i0dgZGiCH2v+suzcdDfXCiDRbCVec5po54t7eSTT8Y3vvENfPvb38bw8LDXOI2MjKDdbvvtNm/ejL/927/FihUrZuxjZGQE73//+7Fs2TLssccemD9/PpYvX44Xv/jFPrvvyZrW4n22ta0CU29729twww03YM6cOTUh2WxtaGgIRxxxBE488USMjIzskE7uDu1D//YedKtAk1pHGMhybOy0YcghTSyKKkEjYaOmzFRIZabJyGIgyzHRa4HIYaBRYDrPYIxFI3MoypCfbivjheQwFtYaLyQniY85a2TFx0JNZw0sWLip2zpL3iKBDNf0AwDKCc31pjbBUgEfetPJHQAXKha2RUM6cCw8r1qccZdNCCtTss9U1eIwUDbJwnFfaDmRDDd5NvfmWy5r4wg2dWhNSh09Cxz26TG4VITeIgyvGuRZkc0HObQfZTCVdh2H9aSPpuTSMlUzgRvI4BJiJqqoQJWshosKaWlhGxyW4ELHDv/na8vwynetRDptYUrHny0tbGaQTBWAIdg0Y2YG4gBNqJdc8WAMXkjdDyasOoFXITuONFswZqUEUNTAR8ROaSMBawYImVc1diPoqWIARSVgm7zfu89bgsPOHUPRdF4Y7RBYHx+eLGWeTnji19Cjs8TGnsS/UwEvttY+uujw/Y0cfOkez2RR/e8xODO5gZ1OAXJY9dHlWPR5eahHvk6qxXOWmVWQC2E4xXyoHwfkWEC+lW30mivqJ+bAAKMfQMV6sUgADgohVb62nB33YJ9ma/z4p7YBGP3qpUBuGFgaSPg/sEC1G1H/G3tIKdAy8kGt1wcGr9QzQDO4lXuX/4w1myTPJh9WrB2XrwWRq2cAOg5JUkI1F3R+7zmWubelto1E6fa0L37xiwCA173udbX3r7/+epxwwgn+95tuugnOObzzne+cdT9jY2NI0xR/8Rd/gU6ng9e//vW44YYbkCTJrNv3txtvvBHXXHMNVq9ejZ/97GdYuHAhrrzySixatAhvfetbn9a5bW/bqqfCyMiIF4bFiv/ZXmVZ4pprrsG73/3undrxZ1szxGE6ANirPYWULCZzFvElZFFWBvsMTvC2cvdbZ5iZMhWGshyttMB+czZjottEKyuRir6psixMsS48TNjiACFbTxeIBC/WrPIEtiRY1SLJ7GArA6u6kop85l/ZS0GWkM+pP+iNTPwAgpUA4IXB8Zc59goi9/+x9+bxlhXVvfh3VdXe+wx36IFuJrEbHHCW4PQwDtEYp5eI8l7UOMUhDnEg4gAIODxQhg6KU9Q4oUYDqDE+cXoOUROnX6IgOOCENCChBXq4fe895+yhav3+WFW1a5/bCI0gNnR9Pqf73HP2ULv2Pru++7u+67vEMqFciyg2reaErWj6os0KmUvwpqMSKpTPVCWAqNhG4tbt2hCanoi4fbyuOwfYAhhcRSj3YejaZ+tV8t4sW+ix9f5RSuwRNKGZMbA9A5cF2ovjeyag2FZBNcCDnilAStfCSJllC1VJSNAODMh6sNCgDRMyd8NGaMcrhEKDFk01Iv4P4T/VSJg0mGt2XM6TcB+n4CKE+MKE7IFVsGAIthbx/Abg1ZnA/XaTgtR3feNZqGdEtxRCpQHEOd2eg1RfRUmfVSNu72a5zWQM53KXonp0+3J94xeWScPEAVhRqYBaYeM/vBmXveyV7eoKUpMvd9HHCoCAnOn9Ubv9X/3dK4RJcdfX2etpjDZ8l9oXBJYsAKvQlQBWQ4ZhwtIQJRmCu9E2/tPpAgJrnx05df20fW1BTPDsmgauUUsVwo7BJ8qbkRIBKMVaJZp8BoYqHkhbYkdAVXuMHI7fUmSqUjY+Lre75+E22G6NMN+uXimQAoAXvOAFGI1G10uo9Ho9vOMd78DWrVsxGo1w/vnn46CDDrpRfXj3u9+NV7ziFXj84x+PHTt2RI3UqlWr8Na3vnW3jufmbDeKmTr77LN3+f762k9+8hM84AEPuOm92gObIsbqfISdVYFtZR/DrEKmLRYmQn0OsgqjJsOMKWGUhQbDguBYYWeTw5DD2v4IV+5chV5eo3EK1hHqRqNazkCKUV89gF4/jqLyIEwXtqkFTPF7I5ojeQol2NK0Rp3EUqLGN/YFllVJyBf8Z55VCD5PgTEJqfXEACwiCIqWBKplXsBAsV0ABhvRT433d1A1wUwA2q7ws9ceAwC405vfIoCJRXsF6novEQm4ICvaKXLA4DftOcgXGWobY3k/hbUXw5eLkQw9MxaRvJ5YsFaAAmxPeaBBoIxAVgEkPwmXKThDcDmhGWrkCw1cLgBMj+THq2oLahhsQjo7w4ysbFerFnTqdkJKM/Q6zEpga5w/xsAKTgGndAIkP0mHc8HoAqs4Cfq5ijVA3hg12wk0PmGHgG5mXsqkJOwXOQKVYvfABmiU+Cf98rhjYvmXEL7s6IH88f3iBKm3x5pWAKGO2HwK1MXPppmo62kicOd4/RIDh7z9ze2YAODcgYyvKAAxzgxMWYyCTc0zh7ztLVCsgGY3qIA0IhgHGO1Bh+ZZH7IJaxVWi8wU7xpc3kDb+JEzwI1qQ7NeV3b537waGz64Sa4NA4B9KDSEPIMDe8pSeXYsHg/77cXwoICr1F6DPDCikEVK/umvIQn/Ad3jInRYKCnYzNBKGC4O/fg9MjJ/sK2LQ2/a+ntYe8c73oH3ve99eOITn4jTT2/D2/e///3xqlftZpbtzdhukgA9tF//+texNl/aDj30UHz729/+XTa9x7XGaWyvBnBMkaFalU8wyCpMaoNhVmFVPkGhGyw3BWpW0GDsqPuxpAwAzBYT9EwDx4TGahGxe28VHlo04yyKyJtJhl8++ST8/H+/NgIrZurUAeTkpq0yT5EQYogv/JjML/qg69rZNZbxAFptTBCKBxbDsyTZEjrFcrNFwCwhbmtpo41aK3JAf4uSGn4ENEPGPU46CwDQ/w1BV56tCUxHKPtSA/1r/c2VJVw4uFrS+nUp4TwzYpgxY+5yCzN2MKP2FcM23r7AZgmQcgyXK7hcy6vQsH0DNoLgyAGcKQ9ufMYYIBOC/4y1gsvkaTxfaKIpqNPU+joRoos70DICAYiqWkrl6DKI6NvjJ88QKudfQSzOXYYmMIKArB99v/w5i4JuANko2UZ6Uw4TW8pKsLBlumq/C2L/u77prHgcsZ5iAv7C+wC44gSdghvV/h2PIT2YXTSX+j4FpoS612taKy40Aa5tfDWCKM1xmyvKxiRjAkc45G1vud5+hbbx3Wci2jKEMB6nBzm1bYIv0UKxn8LowDNJchwbPrDpBvcNiNB840fOaBmxtIwOgI1nb4rAmULozzNN7EFOzK40rqs1a8gz09yWnClsRPXBlJQyJ5YHpgVbwWeLIpDiOK7sw4GkODrFO0uRgQfQ+W5vu/21yy67DH/0R3+04vOiKDplbX7fbbfBlHMOJ598Mubn57Fhwwbc8Y53xKpVq3DKKafAOflxaK1XKPhv6835O+KqYoJcWRjl0LBCwwqZsaicxsQajG2GhhWWmwLXVUNMbIadVQ+VF6/XTmNcZ6hqjckka3VNxFA90Vu5WsGWBljSuMsn3ui/9/3wN0wpRcNQ4eYcROnBRA/hiU9YrOqQCULtr2o+mcAC+xG1EWgZE28g2bsWUofPT+yh2G+xXfyjzJKW2mk5on6IvLFl7zcEJeUd8aNNxwBOTCR/edwxMEtioTD8bwYcMFnjgVCOWCOw2O5r6CW6LjHZZOhSvKOIGaoWZqrpa7iMBCiFRtRm6xkJ/YHZZ/J5ANeIIzo1jGagPasly7LxYdhCw2lCuSaLru+2QAQJUjTZT0hJ5l6aTRdDaMk4Bl1aDBUBMWyaWiagnYdlnIJVTABRCfNTD+QV2ERKwFlYJk6kQZSdiuAT8BzAnC1WgpAVmYnp30koMgVywWG9sx6660brAiDqoJzPKGOV2Gmk2W5MbbjPAwwigHMBUWy4675O6PbPJaDzt1FjsY9JmCyAoTAo6clw1Dqdp2G2ILafBg1M2PD+vxfXckg9vbRt+OAmYZy8t1aozYlUp+VBEwjeEBNtpmBS5zOGTAMYUywZlYZj3wIQZR/KY0tAYQVIMYDCeesFJ1UbMhZGKvQhNOL2gQ+IWcmkJJHGNaoNT/qafwd/7PZTh2/XjW6G157VDj74YPzgBz9Y8fkXvvAF3OMe9/j9d8i33c7mO/HEE/GBD3wAp59+Ov74j/8YzIxvfetbeMMb3oDJZII3velNt0Q//+Bb7TRy1aBykrW3fdJHaQ1m8hKKGI1TMMohVw0mNkOuG+wse3BMWFOMsK0UVqtqDDQ59Asx4xwtFVDefsBNDCi3cBMtQGjGot5e4C6feCNsrcQd2GsymAGtGc4his7hgnhdgJSzFJ/ySDF4TQXaUoAsoVrFolkay8SvAqllEwTOol0qV7XzAzWA80/hk30kw68ZMuohwYQCxU3LrEzPSaoBfvhmCRtpJduv5inun5WwUrYvO1S1PNWqhgGWzDrVcGug2TBU40F+JcLzYNLJuQdD/rhcrkCli5O2ahhqYtH0vX+VZSgPslgJK8XGa68UwXkgli1ZNH0FW3gAqxH1YS4wVsprl8JE7YFRJGM8+zQ9j5IcJkh5LVuoF5iG+6gdW55aN/6vEMOKnfI0gbkKf6PdzrSHVXRnD6xbUg4ofB90dfHjBEN0DwziiO+TDEKoeNrpO/aLkvcsnmqs2qw32BagpCzZIW9/M2J6f/iikIuaawKVyidZUHef4S1BQFfO2PCBTbj8eTdskEkJSIq2CmHfPkw+zQqyvwZAnpWh8Jn8vtN1Lv8bqc0X2WKSsGW0JAhasKSuZyi0TB0wg+jtREiuJQ9MOXNdlg0tkKbMAT5DT8AbtQCNCdCMzc88vsOGtR1ux8c1OpoTEwG20tBFE4/FWWG12APFzc9qixzfLlvye7zJ6+9h7dWvfjVe8pKXYDKZgJnxn//5nzjnnHNw2mmn4f3vf/+t1q/dBlMf/vCH8f73vx9PeMIT4mf3ve99ceCBB+LFL37x7RZMFUpCc44cGijMFxP834e8E0/61ksimAKApbotN7OmWMbOuo8dVV9YLKfQzypU1qC2Gpmx4FrBVgTKrTyV1cKCsJ8sQvZRqFcFAGBq3c6pLSMDIOovQokZAKKfqmUm7l0nk301T1EbE9kPn50DtOVS6hm0xoOevYjznPcdIitAarKfhV5W6F1HrV0AuoDqh28+Bvd+1VmgGZnsOzcL9usQvO8PMNqPMPNrjjd8QACLmVhhmODv0x5c7dyYYf7SClyIJirUGNSJNoSYfQYjg4kEnJH/3Aqa0aXU93O5GHuGfbACqjkjwK6RGoXOs3lNzwOqtJBzyvp4YNMpVwN0gEfqoh3ZlwCwXAKkwjmeWj/uM5yfdJsBfCXsVBj3qIlL2KkYpnMyOUfbiuRcBGCY7le+SPoTtuULIQfRMiufZRdBU3oQuwCChgGTJGREV3S/jtdRccZSHPjsTV1mxHemIzBPjoO9KSUXDugFu5Fdt43vORPBWDOEt7lI9EFpqZjpzQTwxUDrTBrGrYvsNr7nzGQQEYFOPAI/NtNd5dAVReAGsaxLui1WbWYdT5ffAVohuhHAFK43ylxXaJ8ycca1xwaOZpyhP2DIvhTgaoLp1fjlk0/CIeecKv0lb/4JxCLIe9vtqz3nOc9B0zQ49thjMRqN8LSnPQ0HHngg3va2t+GpT33qrdav3Q7zbdu2DXe7291WfH63u90N27Ztu1k6tSe2VdkIQy8uX52PYJTDkd98Kf71j/8BhhzWFGPkqoEixlIt6VSOFXLVINc2aq16pgF58DUpMwFNpQIvG5gFA1oysdJ6uEPW23rRDkFpB6VFqKmmJwogriNGeAy3rYif939RiEfU2pCJho6RY3jKD7XnmgE6E12cQP2EqyfytxkD9SzDLGpAAZP1DOVkG2G79335WbGLPzzzGAFOViaw4RYXbQJUJRYL2aJ8V+zoghOXecaIqPXkIQIcwxkPKK2wSyH1KArFA5tVO2GznBRHdibUnmPAsXhUWSdhvhDq84xTiKHGrDvbjgvrxCHd//KqVUmqfioeD7/MAGQCwLLt3x2ggOTzZGIK5yWAmgiK6oiHYqgxAtcEQKTbjAkGK64pxNmbtRzbLgHcFIBKos9tcV0SsMNDG7cn4VcpJRO1VUHTRwyp1yeTOmW+DJNKwnZhwvbbiZ5Nodiwk98YTXQ7dulxJecjatBIvJA2fuSMFcOx8T1n+pJQ/rcW7BYI0eQ2fh+ON7xPzz1x1LrFsjkB6MR7QNJXIAkDE1ApKTPTUOIHhQ5oYg+EYziQRcsU7BMi8CFu6+WF69mwB79ek5hmHsaLvkXkGz9yutdDtYPcqfbgLwiuleiq/Cbu/PE3Agy4SkuiTCZO6Zyyh7fXxjfDaw9sz3/+83H55ZfjmmuuwZYtW3DllVfiec973q3ap90GU/e9733xzne+c8Xn73znO293Oqm0bbrvJ5CRQ1/XGNtMrBHqHI/5xsuhiLGt7MOxiqVmHCtcNxli1giiGJgac1mJSWPQWHnyco6k+GlNyK8zUJXQ92gIZliDJhrDyzXQt7CVhq19Or//gTirYCuNphS/HWeDV4sI2sEEtaaUrD4GyjWMyToHst7w0oOhwDZFIXI9JRJvErE0SwhLJZMveYYm6E6C3if6LxFw0VuPiWN5z9echWIBqOZlP8v7qTiJBTCXeZ2hTD4UzUMjO5WrqJGSfUgYTkrUkIAu9mJy/+BMrg0TqsrCFRrNQEnIrqfgjAI5hv71dWgGmYjWA4hSBFW2k0QMZaJljKIzecIMFdsI9Ry3oCnc3KbYqDSjLwVLEfBOLdvZVgBSAVx5dq+jYUq2FQGZaz8PfUqTDyIYSkCAiO4R7yxMAnZdEQodowO+ppsADRcnSpc5D/4SB3LDnTtXBFiWwLXGdBFjsYVwsRRMh9EIxXor1Y6ZB2jxPAQQpDiyS1wrcfeuVGSHDn7Hm8XPKmw+hOIimJ06aEIbcjTc2jQQd88d0DI3N5TRl4BwqBakxd9e4qzeIblCJmEAVMH/jRHr60URPGQ7qRt9a2+QgLYA+JBuo3VEj7RpOF+hUHVSz68pDWytJbwXul7LjYDy6Rjw7bClTyU39bWHtUc+8pHYsWMHAGCfffbB+vXrAYhR6CMf+chbrV+7HebbtGkT/uf//J/4yle+giOOOAJEhG9/+9u48sor8fnPf/6W6OMe00pnsNzkGJoK222GNcUYS43U3gt6qZE3+bluMoRRDgt1H7lqMJfVGDUFmAlaOWhHMMaizB1UpWEL0TCpWsEWDbR2sJnD8sEMnVs4S9CZRT3OoENIkABSjCxvUJdGtFcBbDQq1vQCAZhoKdsyUTDLiFl1AGI4Ja0jFr2K0snWoS3WWwnzVM0DP3/DMbjzGWcJuGjEvBF+kiVfa/i+R58FZ4AfvuWYWOftZ689Bvc69qyoOQq7UTWSAsxhtmE4QzATjuabLlfYdqjBvt+zAnwKhZmrxbqAGu9r1aAzqdhCCchSyut9/IQYYidEsPuvFeaqAdzQRGDh+lKjT1fSF+t1VQBaU0s/54S6hdaJXQSQgBi/TAgPyZe7uOCoXTYApBXL+fktbDeCpZRxDM2DZuIo12mF+RotIANWPIYFR3r2YmYHCqbWLdjKIJmPCMc11VkPKGFJMsCsAKhY3LghwDM7lMayPFCJIv3Qv5Ci75mkAIpIMTZ++AwxggyhckqAQIhTphcGIWqygs4QEx1Zp0Pe/mZZ24vOXfI+ZY1WhBC5BaQtgOr6XbXkDiUgj9t+xqcadL9L+r6r/yMrGMbMEpC5Vk+mGeSZqaitatABmmRJChIHI8/ISAGwCmwJqte0Oqr0oouO9H6F9HJIixqz76wHusGBfvOzjsPedvtrX//611FV1YrPJ5MJ/uM//uNW6JG03QZTD3/4w/Hzn/8c//AP/4Cf/vSnYGYcddRRePGLX4wDDjjglujjHtNKZ7BPvoxCN9i/WMDFCwcK22QNVuUTKGJUVmNgagxMhVGTo6drKHKonMHOusDq3hgDU+HyxdWY1BmGa0ZYxgBqpNHMW5idGpQ7lDt6IACDX2ssZwZ6IAIkZWxMJQaEnapGSuwVvPC8ubYPWlW19gjLJmqQskW5o4UsNGoQS8mEDLNQJ65zw09T2/1EXa6W5e76xrMkEhCNP6mdBxK9VWByfnimuG0fespZUEWrrdKe/VK+Xl6cqJVYIzR9JZYCUKBaauWtutS21gfRJ4va+TXMSRDWCt5LCoq8ZxIjW3ZwOcFpggagr/wNdCFoUu2/BrZnYHsaVlPcftNXsN6QMzidh8lC+SzIAG5shjjPmGUPYqdxRjIRdrRMgIiY00nZAqgRtVqpJ1U4hwEYrZhz/XJq6pwG089gMLoizEgCpGxPPlAK4Aaifcna0BpZig7qUQ9E7XUQskWhWa7XBDsEINUZj7B7B7CgOAEsnoXiLFBu4dgIm597rOiltC9b0uiOG/tvq71HExVZk8iWTQ8kBPgRIxbyTfcvFwlFV/FOaDEeLNr1kkGIhct9PylsHx4oxuuZW8F5BIeIAEY0YP6cyPODuJgnIUyOG076osTpPLBoUvuQvKay3RdpBpODyoIHnh8AEokBM4GtHOTmZx3XhkuDwD4AVka7brBqCeO4t3X8Bm/q+ntKu/jii+P7n/zkJ7GUDQBYa/HFL34RBx544K3RNQC7CabqusajH/1o/OM//uPtVmj+29qHH/gBPOlbL8Ed+jsAAPv3F7C9GqKnG4yaDEZZDEyNymlUTsMoi4nNBFCBMWMEbW8rBzD+DuucghrJzf7yv3m1pEFXCmoiYYnRQRbFfAnbiJ4giDPZAZuffRw2/tPprdaBALuQQzUiFlXbs1h3Sy8rNDMuhjoYfoJLHiaD8zgPAKo9UAjAKmRfpSCJ28+cZ7JYywQwOoAxu9kLwP2k7Axw71ecBSigWQ/YvkO+Q7XFiT2Yypb9jdxPwM4ATV+BLPuMOkCRhAZVI1opm0koUA6M27IqSRNxOAljkUzw9VBB1wyXE2yjoQ9cB3XNDkARaNJAEQmjBfiQo2zPGYqAqsMieUAo4na0GW+cFC1GlxxJwVLQVqV+TYFVSud07cFMKlRP9VCpJgj+phxX56n/yYNCzSDlWack9BjZqyBkruU8BN0SF1KslsfCOEEhJjWE7UcCQoci0wpuaCUMZxPgEsYyvTY9CAxHQN4HCdr5619AB1vv/9QLx0ft+p2LobtthoA0DjXqXBImY2/66cFLKsCPqD20ACBtqGlJHbywsiNtH0Ets9xeTyTXchTtt7YG8YLw22RCfMji4PvkLzKClxD4gw33DPYUJYfM3+DYHvRaaTg0jGXC3GHQSNJMyPBgtA9xkHOy8cNnrDgmdiTZfx85I/aHk1AfZbv4Ad8eW/pAc1PX30PaYYcdBiICEe0ynNfv9/GOd7zjVuiZtN0CU1mW4Uc/+lEsLbO3rWwDU0GRgyGLjBzmszEUOcxmGou1WCE4JoyaHANTwaj2pmCUReUMJo1BYRpkRoTpXDgUV8mpooaAgQPXLKUh6vbJVIody+xJxkmhVw4ZfXJDVCWBagFp5Cg6lasGyHeoNvzjJ0drxPdJVzJhNoOWmWgMOmwVgMgYjfeV/8sDGhS/kb5H4W8s2gp5Um2kD7pC/HHrEiCnMLhaGK4AOPJFF5mowDSZCcNmhGzZAcywPdE5jdYrzF3ewBYKzUBBVcEVm8DEbT0631K2LGixXAZkIw9sDaGe0QD1kftQYjNfxEzBoLuKhX4JrYDYIvp7qXQecMK4OSfMT6yZlryCNxUR4CidKP33ARAhmYvDT9SD2VTYTP6fXeGHzufJAmkIjympnebPY9T72KRvgLCQmWuLA2sVASH5fQRfKWIgOmn3LZwvjExOAENkjLg9pggKU1Dl+4Qgog5faAZpIFYW92BhmliK6zbteW1DdQmDlbJGQIfRahnX9jOylGQfho574BdAV4cq5PgfJ2LzePsNYCaAotgptIMb+sLtLnl6nVolYyuD6RrV0ZaRYbDXlUWGSwlTFv2r/IkJ9ffUTC3hPe0imI2skw0InpILwQvi08zCdJsxs5Fw2TNu55YIt8N22WWXgZlxyCGH4D//8z+xbt26+F2e51i/fv2Nru13S7TdFqA/61nPwgc+8IFboi+3ifaxB70PmXJoWJgnB0LDAqQkpMeYyUoMTIXcz6pr8uUIqhyLs++4ydBYhbrR0Ds1Jvv7GbhvwQ3B7NQY/LfctGytYfIGttZRYxAcgkmL4R1bAhoFqghuP4kxkfe4yXeoKCIH0M3scgKUAvNgRvLe5oi11WQltBMaxJ1cNUC2zaBabVHPWTRD50vMCGthc1knW+K4z952oVhU1TJRqkJ0UAcRZq6cREYMLGE1ckBx7QgAkC1bFNsbrPlJCVU5NEONxTsQynkVw27Wh/OcaPPR9FpQCngglRNsTlGnqSsRrNtCoV7TR72mD1U72Fx+RspyR18WXx4IRo2MEmC2K4NIF0rnsNeUeYuFTiZfIjCPhp+J6WdcNjH8TJmSID+Zbp2HXIJYFWjx9WqBVAt+Opl1CVtESQHcwJrBimBb7B+E2QgZem1tupYlIsXATNPtKHXHNBVprxDC+/4xI4qq0ag2PMQEbnyCR5Oc+NCBpF32slcmwHZ6oFb2LUbHwlhTgnEaP/icnP909ykdGfbjQ6MxPJoumzmpMeh1TnH7iQi/g9ECqE1CiWkmZQrKOGQ6evBHvt+dPkeAIzsh5cQnyjhJbAmMVVp/b+qchn1u/uvjovAdjrDx7E3Y/KzjoXILnVvJVDYOutjLSsV2OxKgb9iwARs3boRzDve///2xYcOG+Np///1vVSAF3ATNVFVVeP/7348vf/nLuP/974/hcNj5/i1vecvN1rk9tS01ObaWMxg1GdYUIyhizGdjGGWhyMGxwjArocGovRv6qmyM/24KjJoMq3tj7Ch7sE7B+YK/PFJtyA4KukSHEahLA51ZOKug81rcglnSjMk40T9ohp2zYq7nb/66RCLmlslcJZN1aCF7r1yN6DXlPECwPbSmkWnWmQXmLgMW7qxES0MMN3BwxBKm9Dfmao5imFCXcnPOloHKP92TlYk9AIzlA3rRmdwWhGzkUFxbop7vIV+ooK/dickh+4hLufeS6m0FJmsB42v+qQgmBdSF2n2t/sSzMQTUMxrf/egr8CePPQMgcU93uYJqHKr5XACEQ6zTF8YmtTeQAZl6j+73AXRZ7UFR7YGinaqRBnQ1a4G0CPNVOnmj3XaHzUq6sqL5jDwmAbHOJIkFhDZ0mG7Pig0FNy0DAUXtTB4K36aMVotrogmlqgnOEZzWUYAOJ4Dm4He+uTvZp4RMCt6IAc/GMPy2Gz+hG/k+CM87GWnw+3nHmzug6OB3vrk7Psm4x7Ge6hfCR1PnfHruWjGXxWuG2/fWLxiPSU4g+XNB4JiNF3VLYTMJ48WBSQrdSYX5DbUedI3cMzpaKR/iXBGFDLostCcjmABHH66EBaMExMXj9CAMQKufYgA+UWDzX5/Q2eWdztsrMQktxd43df297eZpuw2mfvSjH+Hwww8HAPz85z/vfLc3/Ae89odPwtqMcG05i55psG9vEb9YXIdDZ3+DS5fXYaAltLfcFBFYKXL47/EqKHKYySpUVuO6pRk0VkkqcS5P8fraHHZNLawTAeP9nDy9A9GkE0Ck6NlPIKQYBIarNNCzvqSDgy4JNmeomlDNimGnCmDITwLlWof+FgXnS7iwAmC61ggBTKjShwx9aZfBFu9WPnBQlZK6Z7kDGoIeKYzXSymaINAmAiZr5Omi9hh99soKOw/OYX340OYkIb0xQ09cDMGV6wqZjBsHe8c1cIZQrtKoBy1wLHYAO+5KyBaB2V/7icExTAPJAAzmm4yOu7fTwEOfdCYMA/nWMSbr+55d8tvWFMX11YyCyyiyRnHCBQDl2T9OXoFRUe3/wfwy6M2CpxL739eF7zoGf/SSs2JIEkBXxCyHAjbtPBbZHP99p00DPG6BSNBmCcvldTNavJOoafsKIIrPY/QmaOkcQI0ggQ6jFHbrw3kRbGgGjXUERWASy4Hkeosi7t92y2F4poYEkDQKsIxgMhoZqQTwbPyHN3dsHVKQ1PHvQrJMR7CeMD7sgdxUHyUMnICesI/IVHEEQQKQ/AXkEN+Tdt3dKRZtEtAR9gcxOLQTQBTsB0wyfgRhhBidclOdY3JBE4gI2ph8PwLVGa7hSoFy2+quotA9gK0Q65SB0rnFpU8VwNQCKbTHsLddf0sIv5u8/t52szRi3pP0/L//tnPnTszPz2NhYQFzc3M3ap0XX/AMNE5jazWEAmNtsYQ5M0HNGteUsxg1OdYWy1io+ljXW8RyU6BQTQRZS02BX25bi/EkR3VNH2ZZQU/Ej8jONoAj9K42KPdtoGbrCKTYkWTKeEYrlobQDLeQQ1UEN2vloTe3ML/uoX8NsPOuFvk2DaelaHFo1mfShUw+9iCKLNrQTpiIyPtSsS+AW4lZZzMAFg8RU0VlAdeTScBsN3A5o/8biporHYr7OnEL/+Gbj8F9/+6stugvM2xO0JVcsroSEBT+Vw1L6M7Pw9WMQjMQEbgZA8sHIE6UZhk+0w8Qvyl/0CRsUG9rBVtoLO8v/hC9HbZdxrI/Xgfbk1BrM9SwBaGaIRk3fxwua7PqwL6IsQeGAUA54xkgLWPMBC+0b4FpClxT1iRlAsP3AGL2nfPgTFhMePbHgyO/3K7WD15RIRybZl0yeVCo2j673JtqejAkDvcJS+MZq7TmnvTfa/iKBIQkCROByVqhU4qsGE0NEFoQFppnxNKw4PTxxkXD3wEgBaF8aI7acdDcTvrp9kJ/PADqgKfQ99CP8NkUkCLvFM4hvAdg8wtfhY3/eKYsn3ErAnd+O16oH9hqChYHyTEGIfkuj589qxTOYYJmuJYTT8aJsNzrrmimbsERtZl6YIDHRh6eqO1P62Deup8HyxYpHyMPKEHnGRJkNj/zeOwp7abMGTd1Hwe99WSofu+GV7ie5sYTXPny192ifb29tN3WTKXtyiuvxK9//eubqy+3mZaRxVw2wb88+F34xIPfjTkzwab7fgK/WtoHADBjSlgmGGWxWPeQKYuaVSyCvFTnMN6hPE62PjyhlyT8UR0yAXLRJVj/REqE6Hqu0qKm/n83L+KZ/JoMbBXyHcDSBgYKB5sz8sXu8lF/w35i9ixNWqQ3gIIYdvTfKQvMXV5h+cDAsPgn2UqBSoVmdRMn6xUmj5kHUt57SjQ7omsStkMy84LXlRlZ6NJh4RCD6+6lsXhHKTisawY1sr6uGWYszumrf+owc5WL+4v1xfzxkGNM1uaoZ7WI2gmoZjXgswUDE2d7ytfiq6G9YWfqlC1v2uMK+5CwnX9KD0AngKQw/yXgTgTR3X7Gunf++wvec8wu9weFWGTaFoArfGalmnoopbYfLmHGqPGlg4KGrWmBYtBoxVBfQ+K7FPruktIsKxicME4M15u6VuOXKxbvAqdkmx22KwCZXa0/9VkaKo0bCiAphMFSbVNwU0//1t5t3SQAJ/zviy8jAJT0jpsux8lBpAeTxHE2/uOZCAWa4/oI2+BoSgryXkxRC8UtoIzHmwx2UuePQkZf9IVCNwSYas5yD5wiuKVoAMxMQM+2DNr0SaDAUAGXPvUE/OqvTsClTz1B9h9wrNdeAcDGfzp9F9vZ225Pmqk/9LbbYKppGrz2ta/F/Pw8Nm7ciA0bNmB+fh4nnXQS6rq+Jfq4x7W3/dE5UH5GecOPjsTPFvfFkd98KWayEpWVQshSSsZCEaN2GtvKIa6bzOCa8QwAQBNDEaO37wi0/wR2IPYFrAD0RYCpctumOocQn3c4V77Eg84s2BH0qhKkHYorczjDoJ1GJtnVNTDSUkNOow0teXaElZ+EM89sBMbDtOwHSJZh006u9QC47j65WCkkkxEXDpzLhOgKKRPDmawT2CmwWCSUq32YMGvr2oWwkqoZZgIsHaCw7dAMVz08Qz0EVl0qQElZAW/ZmDHz34x80WH21w6D3wi7FQAZgBawODH8FB8oJ4JzRixX4woVHdRFT6RQbKsAIvSuncCMHMyYY/Zjh0XyY2ozxILIaVivA75Sf6UQzUnEzWGddM49/G/P6lyDYT2nk3OXgIAAisPxx3EIn/v9RbPPFMilDA8jWlcE00xVKwkDpiB1V/ftMF9zcvxAC8J4yqWb0N1Iygql/QpvAphIP0v7QC2AlnENIIrjgbJmoLDd8i+aW3PLUMbG+BInoVyMYrBxEWx1Q5TJK3yWJCy0y+0CDQbgFcY/xFS9szsrlpCd6gxIOwa72uY0yFV+7AJIDqFBlochMICenepHeEPeV2qq09TeoyiG/aS+4V0+8cZ2ScXQuYvLBzaLiHHwx07DIf986sr+354b3wyvPbDt2LED73//+/Ga17wmlrG74IILcNVVV91qfdptMPXSl74U733ve7Fp0yZceOGFuPDCC7Fp0yZ84AMfwMte9rJboo97ZNt0308AAEY2R0+LrmmpLjCfj/HhB34gWiSEtqZYhmPyNfwsykYjzxpYXxJGDPoAzgUk8cjATgwGP+qB/RNh0B0QyU0p3rSI4WoFbM9RrZYb1eAqhfHBNeCA3nWiZ3KZZ4FC6CaTEI8z3Qk/sFKRobLdicBlgO0D9SzQDKQPaqI6D0JqrKBKhdEdnDBMCUMQ9h9Zj6Aj8oxMNmIUOx3yRZ8BWQDF1pBpSEm2HEGKEksfzMgDJAeohmELATVN4QVbEIBUzSjUQw1nxHzTaUI5R6gHUobGGcn0YwWocYV6aEBV02WbfBg0jFEANBxCelm7DLk2MzK+j7X4WqF8zMRLWKRpcBDGECQlelzeLhtr6yVzbLot5/sX+x/OeQDXyc03OuIHQFVSFEjDIckqg4SePAPTmd9TAiYhMFqGsN1vG94LHYCEtcIhq3QZdFkZw8IQeZ1PysJxKH4cPjdTswu3ACDqo8LvIPgtqXZfqW1BBFcBoKWeTOHvBGhFvJcyYRGQB7pG9p/6TUX2h9C1FYilY4DOjy+MyzRLBqC1rU/6CUh4sGxXCLrLlY075zVlskLFBbZejmCVlLyq2+26SsPWCsq4FpQRYujwV0/ritH3tttfu/jii3HXu94VZ5xxBs4888xYWuZf//Vf8ZrX3HqWGbsNps455xx86EMfwgtf+ELc5z73wX3ucx+88IUvxAc/+EGcc845t0Qf98j2sgueDgCYN2PMZ2Ms1Tkm1mCh6uOvvvsCOFA07VTkMGoKfO5hbwcATKxBWWUw2qFX1BjMjaH3HQMKGFxhYK7JMLzUgDRjvL9k8hSbC9z5428UYGWl/pXWLt7cSTN4toFeVsh2Esb7sYhEl0zLXmhhF/RY1gkTaoeJ0hDgFSwGBlPhLb+OLVoQJnorb8QYa67JU7QeE5oBo57x9geJhYCq0HliDyxY3SeomkE1Y93FVSebcPEOBFsQFg5RWLiTWBvUA4qu5C4j0Vb5Y7E5xCHdiPFmPZRlmgGhmlWoBxSPLzBZThOagUI5pzC64yx06cCZhhk7iZAUIqAPx+OSMbQBoGZJeNMDi1DMOYTVQkgzsjd+cg1hwBTcSCf9/37evO/fnSV6N+u1biFEF0rPJMtG1tGD6PjKW5AVQXUC4lIPIz0WHzNdUgR0nchVcgwrWY3k7ymQFefUGN5idIABkLBJiGE3ZA4oWtuAELaLfwMtWsud1N3z4EpOtGT8caPakiuxn9Tx94p98YJvMk7ApZaQWxDYx9VDaDCGEhMQkjBjHd1T+D8s60FS6/nlP0/Hh9FmIahuHzrnIAKn5MMQHsxdKzhvfBZkNUU1sozT9GctGPXMnWs1WyprmfXQNj/7OJBi2ErHkB/5JBpmwiHn7GWmOu13ZaWmf397QHvFK16BZz/72fjFL36BXq/Viz3ucY/Dv//7v99q/dptMNXr9bBx48YVn2/cuBF5nq9c4XbaVmXieXTiPT+L0hk4JhhyMMpKeC+5ijUxctXgr777AizVwmStnhmBmZBnDRqrpQSMBapZoF7rvQkmGm6NFK2LRYn9zclZBWuVPMEGNmgha8M/a2U9NSE0Mywi7waROQmMRQBCUOJ3lHrSsGLoCSHfgU5xXJdcBnrib6ZOzEfVSLyu4NfVE5IQo0mAhxFQEZmv4KPkmRVTMspVGi4nlPMGq3/qItszcxVjeT8xI1U14oRuC2GSbAYpckwepBCJiByA7bXu5ayApqAIJFrRMUFXDs6H6VQlA6q3j+A0wYw5FmKOLJLPfEwZHxc0Ob4RA8ohnoeOZmqKuZAOIs53ZIFQKiaG5Tzg0rWAs3xnon1K/MFWzH0pgE6Bn5kK9yZgrOklfZpuCcN0gy25VjusjD/4691GCPcl65BncDb/9XHCkq3QGQFRH5UJ8CLDrWYoLBfHlLqfA625arrdCErakxaBRAL8SLevThKA3z9N7aszRhHvEKLre1wfrQaKMHWCp9aN/QVS9/gVzf9cgkdVJyTNFPdHkaEDMDLt8QBwYyM/OS8s/9XTTmgZuOlD9O7pEWgxkhp9u+7i7bbdDsHUf/3Xf+GFL3zhis8PPPDATomZ33fbbTD1kpe8BKeccgrKsoyflWWJN73pTXjpS196s3ZuT27jBFHsqPo4dP4arCrG8TOjbLRFAIDZbILV+Qhz+QSOCVsXh1gaFZhUGaplKQGTLQqYya/JMDrQoX+Vhr5G9mN7EF8pf9Mn5cDWG3cGZsPXAXM5AEtwlYaqxcfKLLd3NZchCp5tjyPACqVf2LNTqhEmwvbbiT6ACADRNJIJMEsEmqhWzjKSDMUQYkmz39J0e2da0bSeANUMUA8J9ZAwWm8wWq8w2lchW5Zldx5MGFzDcAYYbEkYqEJsFVwmwvW6L4CrKVrAIH2WDpIT0BYYseDSLuVhCLqUsazmNcyoxvLd1qJcrcUWIRGHu6IVdKeTfUcnFb72mZOhTMu0PnT67wBeJTToRe1TN0pVA2YiY/ejTcfEdeL2s3bbAbiltQRtn9HMOdTzTjL2/HfxGMjXGUTLUMWJ3LOFZrTrSXpX8h0AHXDR6rOmthGYFvhlO6ExjuzXhg9u6gKHlE3y7zc//9XtdhXE7TuIuQOjROKmziF0Z1ybFTd9eNyOMYKGSAW2imMWIOlUHCfbplDzzoe12HtthYebqNlK9xlE6UxtaC/0I4zV9LFrnloGK1vCbrF/qGLlGeZo+dCOddweQ3SdLjzcMaiwaEYG7AimaHCXT7xRMvf8tZJqoTY/83hsfv6r4ZYzuac5Sspk3RhUvrfdlluv18POnTtXfP6zn/2s44r++267DaYuvPBCfPazn8Ud7nAHPOpRj8KjHvUo3OEOd8D555+Piy66CEcddVR83Z5baQ2O+cFTAQAbh1uxUPcxanJUnqVyfibNlYVlwnJT4DeTueiSPuhVYCbUtcZwfgw3sChXA/1rfEZbLnev/hZC/5cFVCU3XvY3VWafgcPk62sBWF2hOqj0YInRuyoTpsKHfUJ2XLghOgNw1oZFOOMOSxLr+Hnhuh4lN/ww2fpQlqoBVRFsz8EsKZgRtWErz8gwtZl7thDdVWBJ6hkx3bR9AVRNP9EhkWd6CKjmGIsbCM1QgNXy/oTFDYQlH/5zmWQFulxAGWtqWShfqBgMmDHHCYy84bL2hcqrWQVl2Ze2ISwf2Ef/10sCBnV7TAAAB/z0/xzTggzPJLH2fyrp+0VvPSaOawRdaRgweUWtUjwPnLiic+uOnuyPLHDfl5/VAh20/UtrB4b1bMFwGXdYJc64G66amtc4gPYACLw/WrVqF9qaAAwTkBCuvTgGU2CLAhOSbGMFOAoan1qBa4VoKjnNOHlGhjVj44fOSPbHLfDJXMta+TslKQnbicg77Vjbf/Z+TtKHlrWhzAFF4r/kw/FdrZTvY+o+zu0u2JfICQWP2VuisBVHd/lficdcyqaFLkYN0y76HgcmjGsXLFIyZm5gu2MPtNdq2KEPzYFFI2UGDZSRz37xlycBBLhSrwiXHvzR08RvqvBMmDdu5Xq3p6vbfpvOzLsprz2sHXnkkTj55JNjwhsR4YorrsDxxx+P//W//tet1q/dNu1ctWrVig4fdNBBN1uHbivtumqIffJl/N2Ff4VlW6BxGlcvzWGYlxgMKmRJgTYFRg1gLhvDscJMViLXFhPtoLUDMzBYt4zxZBbkFPQYMDu0MCzDdpIHAPymB7uqhhnUcI5gxwa638Tio8o42AMngCXU8w5qrBA8Y+p9auj/zqJoHABcwVCzFWhLD3pCqO5QAssG1EiIjprk90giOu8IlxWgR4R6RiYQVakItAJjEwBdDCG5ZJ4KWWIaqOeAetZBlQQzIvS2CgirB76vGUST5dpyNuP10o98Rxu6AmQuCen+Koi+GT7TT9icYqdDNavBWkTv4RjF90qyAr/70VfgTx63CTvvOofxPiqalgKAKeU473HSWVGcnWYkhn6AgPsccxbIJPWXw5znQWv82088sZwOEqF+mDRD2IaSfXpckYKmILEJYTJiYSL1RMr9wBE48xmNSkBSMAMl739FlmALjvuMQDFrGRgAIhanpAhv0mgXWGvFMgl45A7ymlowZbT8cXNCorRIDS1oSnZCCWPTgRmhCrQPwQWQEDtmqdVVMSWhQQCB9SRhntgRXKlb0AT5n5lBAZF613bCFHgOrBS3617+vGOlADolDuWeDYtjEsapU5gY7RdBZ0WdL5Ox8UOgWDL6THjiSsBXoDsDa6UAIgcmgqt1HN+sZ3Hop06GMgasGHaiV4jh82EFZwnNKIugjQzDlRp3Ou9NuPQpJ2JvSx6afof197R25pln4vGPfzzWr1+P8XiMhz/84diyZQuOOOIIvOlNv90df82aNbu1LyLCBRdcgA0bNtzgsrsNps4+++zdXeV22WZNiS2TOazrLcKQ1Oib742xsxSBiWVCRg6lz7tX5ORvVjDkMMxL7FjuIyOGZULTaGQHjGDLoUxgA4dfvuyV2PieM+EqQrZDyUR/wAjk/VuUdlAzlQ/1cTTHC0/Kbr4BVRl0KUxNfk0GMGDX1SDjoK4uoOcrCRkeMAFf1hfDvr5FfmXemUuUN+psBgFIiVO2y0WXxQYdHZOIr+VmHJiRAMCCiBvs/atItmuHUofM5gRV67iMhNsEMAHCqDV92Z9ZavVX1azXhYX5KwPyRaDOResEAE2f0NvOsDlQzivYnmQJjteQN9wU8X25SkM1jAf+9VtA+xjZZ0/AJLG4vwdwQTWAAH7CeHkLio71AQMqEfID6AjNU4AaJjdVAzYjKNveFb//3mNwv+ef1dFYx/nRz3OBrUz7VM96cJQjGST/XokVABOABkAOua5sC2jEa6ndJ2cMyp2wCkbq4HUMMBN2aoWYfhctXm/TbEvqJs4Us0sjxt/VdtMPQx+CMNpIiByERHje7rAt1BsOFK02MTBNHYF8F5yELDVKQ3IdTRAJcGG0Ib2GWp8qf05C+C8AKQDR8JRUOMfUDUcGYB5BV9JHSv9u+xJCh+QNNTu6qwBOud2GFCuWDfByBjVXCXs2MmDDsEYsEX71Vydg49mbQLmFSkDtZU9vM7Lu8ok3op6YCB6z2Qq/fPJJ2Ntuv21ubg7f/OY38W//9m+44IIL4JzD4Ycfjkc96lE3uO6OHTvw1re+FfPz8ze4LDPjxS9+May9cbUgdxtM3drtXe96F/7+7/8eV199Ne55z3virW99Kx760Ide7/Lf+MY38IpXvAI//vGPccABB+DYY4/Fi170olu8n8qLzRunocghVw2uG63GPoNl7Kj62Ke3BAeCIofKGSgmNNBSGNlp7NMb4WqaR1kbOEtwW/rItypw33s6+Sdos2YCd/UA1WoHRSI8BwCwZPM5R96nBSD/N5Kne7u2gW1IMnYYIjQ33uflwAmUclCKUV2XgwcMNVvD1TrqWoLeSFdA5mvoseGYGUgWUsw2AKfwdO/fhwfapt8Ci5C1p0oBIm4gWYM814BrApXk9TsE5a/gCBx8aCwIpvUEcAyZRBKdj8sFWAVmz/kafqwFFJXzCr3tkmXYDFqBv2qAYsGinNfQE44ZfkHgLuHMsCxD1/4gbZfIgD9uAG3ZFQjICnXxUpAR6wgmAnlAjk0zosaGmHG/55/VnfRShioBVBHYhHnfC9lhkr76daihjhVBAAtp9iX5rLFUaC3/+21p78ifTuiUkCLJ2LDhBMj5bSYWC2m/V6ycggFC258UPBK8/icwOLJdIu7octpaciwmkw5wgVJNQAX565oTxigWH2bINlWyvTB+4finQ53KA1Of/cbGi9Vrah3Vp8Y5lJAilZznYOUQgFqKMOMP0LeEAY0x25S4a6Q+H/eclIwxTijLqOGSHVDG0bmchnUcT1YMXTTIMouqbH+4XGnAOGz8p9OR92v8/H+/tu1SLNgsYdK9QGqq3YiHkBtcfw9rmzdvxsaNG/HIRz4Sj3zkI3d7/ac+9alYv379jVp2d+ye9qgg9HnnnYeXv/zlOPHEE3HhhRfioQ99KB73uMfhiiuu2OXyl112GR7/+MfjoQ99KC688EKccMIJOProo/Ev//Ivt3hfFTF6usayzbHY9GDIYa6YoLJyI57YDAoMTQzjUYSYecqNZ6nJcfd9f4N1c0vo92oMN+7EeEPdipZnLA456y1QvxyK+eXaUkSijuBqFQsdA55BUMlNPLmhmmszqTzfSKkIZVzUZGjjop5BTxTc6gpEQHZVLoVvGbADjvYIzRBo+owgdo/hPp9hFBmSsPtUL+JaUBGEztkyWk+mnDGYG8uEkTNcwSj3YTQD0VMBiG7pNrh8A1FTZQcCnGwh4ChMsmyEkbG9llULou0ddxHGTpU+w9EAve0Oy/samElbuqbY3oAcUCxI2RpTilA9hAR16UFW8JIKHlKBomchfkIB6U4iVwKkogcVx6/icXz/vcf49+kknWyIpzIFIwDqvle23Wf0DmNhUaSYMWLx4VZk3V5PqQYjhFw7bRegJ4iaA+vGaSmX1CF82kE8GaPpbV7+N6/uAof0+7hNH5rzmWytJ1J3eyEtP7AjXKuoT2TrX4GNIkT/qTSiGLYbtxOsBnYBJCNT5m0VACQ2AWg1XP4CCqFJtiTLE0c7gQ7wTC+scB/g5JX2NSzjtxuvEQ+qo8fUOCDldgNcU7uvAOgAqMLCFPKUX/RqbPzI6dj87OOw+TnH4tKnnIjNzzweTdXGwO/yiTdKOC8M0h448e9tN3875JBD8JCHPAT/+I//GA07b2xzzt1oIAUAi4uLOOSQQ27UsntUbb4HPehBOPzww/Hud787fnb3u98dT3ziE3HaaaetWP64447DZz7zGVxyySXxsxe96EW46KKL8J3vfOdG7fN3qbP0gu/9NRabAo4VDujviOVkFDFmTInZTOiOsc3gWGHiy8k0TsEx4b+X5jCa5HBMaCoDuz2Hmoh4uxnKzcosEZpZB6zzKVXXFuC1lTgJezo9TlqO4pOei2J1xBuV7smNjpQY5mnjpMYfAe7KAezaWiaiZQM9kqd0O3BQtdxQRXztdTHh3uqfumOZEWoBRXiCVw2Q7QSaGa9rykW3YxIwVW+YIO/XKJdyhIKtaqxF1L66gbkmixl9qUO483XjQjPLPoPQsHgiVYi180INQrIedA0RQYgugXxBlpu7wmLhYI3+tTK2NkNk1eoZsVMgK4AstGjcmabBA3HC6QAbIIbLyLb9AtB6fvnIh3KIXlJBgC4b8P9pzwD6sQ/HGgpVMwHVKr8v1zIkklUZjCo7GCnR5SRgOWFczLKAzGZN4w0zPcNRK6BqMzojaPLrdZCFgqwXQmFh/yl7gun33PkssKDTItv4kf9tpCn9wQAz9T8SkbeKuihqlGTehZpy1o9xMPEMTFQEWNxqnQitvoradSO7FMTyKdgJPlG+L+S/D/Xsolu5o3asExDdMeIMAzTFSsZl0wce/3BGAUw18t4Nrd9vsqMU8JRKSsmE2nvGReCpDCMvahAxRjt7AAjFTBmP62dHvQ7X1w7+2GmdEOAfavt91ubbcMYboRKvpd1tbjLB5cedtEfV5rvgggtwzjnn4Nxzz8W1116LxzzmMXjGM56BJzzhCSiK4gbXv+qqq3DggQf+1mU+9rGP4elPf/pu9WuPYaaqqsL3v/99PPrRj+58/uhHPxrf/va3d7nOd77znRXLP+Yxj8H3vve96y19U5Yldu7c2Xnd1Pbe+38Y+/V2oqdrXFfOoKcbGOUwajKMbI7lppB6fE7DMUWbBMeEhaqHftb2UWkJvbmcUc9JijXVQHPwWO5hPqsHvpCp8sL1cK9zU/oMpdunVzJOMpRUyJ5R0L4cDRHgLh/Arm7kabpS0MsKduhg5y2gAWdYChjnTpymcxczulzftQLj5GqLc6YHAZ0UfQe4jIXp6nl7hlqhGmUyKWkBbK5v0cxZQAs7FgTszZDRzDhUqyyaWSsmo7nzae0yJsqH36p5jtl6ti9go56VvsbahM4zWHMCMpo+wYyAfMmBLMOU4uckNgAcDUSbgQc+Yb5J3MejFmqqBbYq9dZK2YU4ZtazWbbdVgqkplmRtO6fnJh2X9NhM3GQ5wi8UgsHYnTZphhC6gIWO3ReVJ1+6JmLABxSMXoKrFIQkfQr7i/1M0oVuBT6yx2w1A4qtyHDpHHInKNWCxVsRqLdiEPUT0Xn89QUl+UfMqItozTrkQmoJcOO01CpIylFEzyuIpCZWiaAS+9PJXquxBMLiGxXZww7jTrAvTPOnHzWee8NOkslIV4P8NSyBioVsxVJtzYRpJ0YpdaqFfMDcBMDV2nozGK8s4fGauSDGvmgQrlYoFrOUY0zHPqpkzvlZUI75JxTuwWa97bbbTv88MPx93//97jiiivwhS98AevXr8cLX/hCrF+/Hs997nNvcP0/+7M/w/bt26/3+3/+53/Gc57znN3u140CU2vWrMF1110HAHjuc5+LxcXF3d7R79quu+46WGux7777dj7fd999r9eoa8uWLbtcvmmaeDzT7bTTTsP8/Hx8/a6Zimcddi72LXZiaEqsLxY9aGL8y4PfhWbKaEglIT/rFFYXYyl47L/XqyqYdWPwfA1qCMV2Mb9T60qY3Nfra9CWtEi3rdoaV0QcgZPKnAdfogkh5aCNL9PiCLZR4AMnyGYq6Nwin6tAB42gV5UiZ5mrgJAmbRgIuooipJpxnOAAIGpY/CTttLA+tkDHTdsZKUVjhw52VuoLcq3BjZL+DxpksxXMjJTEUTXB9hi2x3C+/h/nHGunwbNRLpdlqnnnzUop+iSpEh0hNFlg+N9A/xpg5kqGWQbggGooAqdyXuKhvevquDxrilYR0z5S6UM80LJA05N7CLcF0JRmpcGHA0MRYlUHQMUd8iHdpvIi8ZhFGFgwB5RrgGI7IivFXm9GXoDt8sRzaVesWmQz2i+aAbfn2/mUfV8AlzyTExK/4na8pij6H4Wxi9eNBzArXLypuxwQtVth/53lwmLpxOwCyzPNRlEEWpwUbabMQRU2skjBewrhN9ZxEkdbFicctx/b1OkcSI7d+WVKBdTtQ1I4BgrngsI4rWTfIqOXXoOBOaJdnMuOYB4tePS/XeVBYAj1IndxLMJ4kRYGSmUWetAIq+uPqZifREsIMFCPjWgxl3PoXoNsINqqcjlHPTG407ldp3Pt2a29baoFevl3ee2hjYjwiEc8Au973/vwla98BYcccgg+/OEP3+B669evx2Mf+1gsLy+v+O7cc8/Fs5/9bJxxxhm73Z8bBaaqqooMzYc//GFMJpMbWOOWazSFFJh5xWc3tPyuPg/tNa95DRYWFuLryiuv/B17DJTOoHQGY5dhYCos1zn+17dfDMeEic1EgJ7cyHNtsaoY49rRDJRyyIzcuIueKJu50jDLhGwJuNOZb4mFjcOTGzNgaw1bi4uwijd4eH8aOfaQQSNp2hzDBsw+HLh5KGVpTCtkD8soxTCzlWQMFj6cQxwLrpISX6r06VQ6h7YArhXxdxPqASrPuNTkDTwZPLRA7ry1A/zEplD0ayjFAvwUw85auELAEjTaIrOmneg4Y9ieg8ukn4HBqOZ936gVmltf026yVpgqZ3w2n/XgxGuYmh5QzZu2SDP8fKFbIXrK+MRhCO8TliDYRQTQ1NEkUfIKH7l2LNP9hOVcKMhsCBe855ikHp18X6711+fqlrnKF4Bih/yfLwgwdn2PBlKG0c/fMTSZiIzZcJy4yUoWHzVTv8Oo+fEfhDBYBAoBcbbAaAWjpJNlpoBkh/UKwGVqe9Mb5KbNVguhtLjtKRZNZ9Y7mDthdn3SRrrTcIuR69qDkVQnqNt9cAiDB+AWtuX3Hxm+aTAbWvo7mwK3Xdppan3axfIs+41JIlbMeQMraQee1ky0mOF/XdiouSQFkHKwlUZTGWz+6+PiOc56DRhAMVvCZBb1xGDzM4+H0g75oI51RkOztdojQny/98Y3w2sPbVdeeSU2bdqEww47DA94wAMwHA7xzne+8wbX++xnPwtrLY488shOhOrjH/84nvWsZ+HUU0/FMcccs9v9uVHZfEcccQSe+MQn4n73ux+YGUcffTT6/f4ul/3gBz+42524MW2fffaB1noFC3XNNdesYJ9C22+//Xa5vDEGa9eu3eU6RVHcqLjrjW0nXnwU5gzj1+PVyJUojGezMjJQjdOYySYx1BfYquU6x+r+CER9LE0KFFkj3+8oQLWK4ajBFkJ1SIg/AKqids7zN1jHJMBKTauBITdEI5NlWu6hXsqhDxrDeN2VDiJXpriMLQ2UsXALOTBMCr6F9G0lk02qn4qsT0OtJ5GSSdmMJYyW7QQm+4RZTV7cKFDjqauG4AaEeiL1CWGVF5m3sTPKXPskX/sne+PAPfHJURXBGZn4sx3kCyiLmJ0cMHMVsLy/dKG31XfFs03VHKHYwSjnhIUK4vJy3u/PLxtDaGFOTgTdfuhbli7gChJGINVPxRaAENDxHpJtUTcjDO2yxMAfvfisuA1iYLy2xRJRnqM8wGI5F6wALpzoepTPwAwWD347ERRO+RcR0JrFJjX1YhLCNJCKx+cZnsAupaG+sD6TD/VOjU/Sn5b1ShiqwG6l4+o/D4aUsR+JYSZbwuV/82psfO/fe1BJMWs26ILYP2y4Rrfgy/tEhb6FwWEPNjqhxXBNhDAjtW5aUXvYUBI+DINM7Q5CqYP0QdEz0TpvYGsdTX3T7a7QTXlhPgFQEwHCti8PI24Q9FK+yoKj7gMTE7Sxcn+oRVCXD2o0pcYh/3wqXJNhOD/B8kIPWb8BEaMaiyXLnc49dZeFjO907qkgzbj7v/4fXPKk16/4fm+7fbX3vve9+NjHPoZvfetbOPTQQ/H0pz8dn/70p3dZ5m5XbWZmBl/4whfwsIc9DE996lPxyU9+Ep/85CfxjGc8A6eccgpe9apX3aR+3Shm6qMf/Sge//jHY2lpCUSEhYUFbN++fZevW6rleY773e9++PKXv9z5/Mtf/jIe/OAH73KdI444YsXyX/rSl3D/+98fWZbdYn0N7cUXPCNm6N2hL2NTOYOeaeIyRlmMmiKCqJ6nN/YdLAEQ8DLXn2B+MEZda1CpUGxTMGPxVSKX2CEQUO7btKnIDmhqLSJy1VZhJ+J2HaBzMwyFkrOZCsYXIg0TRmCnws03H1SS/Tfn0b2DCE+1A0oNFD48FyrZ+/kszUpry834OXIM/Ojvj/E+TNwtnkocRdHVOIPzmT+qED2Xma3kaVi3M0TqmhxrtClGtqCQb9MothPyRcnEa/qh8LEwTsWOIP5mZN6HKl9kzFzlMFkj4CXUulOV1ORzHlx1gI4PncW/E3Yo1usz7XKhdE8Yr3Bug4jdFrJ8LKAcnOB9MeJYUy8ptJwCufH6dn/RQDUUMdYSBmUFVKtdZFSCaJ/NlOYogCN0gSLg2ZgQGgtsRwpkQliP0IrdA1MT9uHCZ2hLmFBqTokIzCLATFmolLWiBGdwu51OZlwSDgc8qCJgwwc2tQzXrjCLz/jjmoBSdTLgdpkpl/YxvTD8YJHPamTjvD1CMt5Aoh+a2o5L0GzyOTuVPMykTzWcvOR4IwtWe8F5zmBf7Fh0Xg5c6hYgJuc0SATIi+5tqcUnCkDRrzG7agznCMVMFXWgpBj5sIZrpJDxPT79hk5B40ufegKIeC+Q2lW7HTJTp5xyCh74wAfie9/7Hn784x/jhBNOuNFAKrR169bhS1/6Er73ve/hUY96FJ7xjGfg9a9/PY477rib3K/dzuY7+OCD8b3vfe96mZ1bsp133nl45jOfife85z044ogj8N73vhfve9/78OMf/xgbNmzAa17zGlx11VX4yEc+AkCsEe51r3vhhS98IZ7//OfjO9/5Dl70ohfhnHPOudG2879LZsbffO/ZGOoSfV1jbDNsmcxDkcPOqoe5fIJRkyNXtlOnL/w/aiSL7/yHvgP3Of91GI1z2EpDXVPALBOKbQJEJuuA6pAJsl6DapR54XnLHgGQkIRnncJEYK1KJoyW5iBiqACeLEEp+dsxxafvcNMNmYG21NFWwZYaurCwY9NOtEu6TauvxXA0366RLQD1vIwVNUA9zzBLcvMGk4jLk6dnNn5yZwJnrs0osgqqaOBKA3gmTRmGrRW41D7z0Gu5ZizYEvSyhh4J0Cu2ElQt4T7WYrhJFtAlw/YIxQKj2N7AZYSlAw2GWyyW99OiWWrEa8pMGKN9CaoRDVjTR7Q6kAOE99xKjgeIWXsuwfZBC2VKvw3VAqcAfMJ+4rY8s8J+zgzvqRGhehCcl6s9vjDt/0ACZjzAi0LuIPh2rT8UOQjTl7BMsSj2NGgIrIoPaQmbxRJ+TVmtAJaANnyYgKcWsLXvqWofIjrLtJgkrhNMLMkfD9cJtUcQAbgPlZO/9rlW8cEkZux5gbkyElp3Ngw4oq4PPrmByQP4lLVDGAt/vEbC16RZsh2BNmTOCbAJDFBg1wJmUozLnvEaKb+C9nrovCfu3A86gFeln1PM4IMjYaUc4OaSC9mH7tiKz1TIwgv/EzFMYWG943mwatG580yWgsnlgU9rB+sUMmNhrcJPj3od7vKJN3omXPztfnzkG7Cntd9nNt/GN73pd87m23ziiXtUNt8NSXtuqF188cXx/U9/+lM861nPwhOf+ESccEKXFb3Pfe6zW9vdbdPOyy67bHdXudnaU57yFGzduhUnn3wyrr76atzrXvfC5z//+Wj1fvXVV3c8pw4++GB8/vOfxzHHHIN/+Id/wAEHHIC3v/3tv7f6PdurAfaZWcK2aoi+rtCwQtVkmFgDVRdwTDDKxTp9YvDJcKzQ0w0m1uB//vvRWDdjcLWdw8Qq2HUVyOaY7EMYbBF2ii/vQd1tEaZo4BoFZaQMjW20d9Vub5hNqaNYHfBP16rNSgoZgIoYCC7cPuSgdOuDFRPHGCDt5LtGbprsCKqwsU5YZBRYJm9qJHXeDgDrheJqrKDH5L2iGMU2gu17G4Oe9bobBaokw8gNEGgIsAPsKGvFsEywlYjpkTs4B6iRL99RKj+RM+p5B3KEyT6ALgXdsBLmZnB10EkxJqsJ2bICmEENUM4pmBHDR22RjSyqWSm2XA8FwDgN6BDG9OAg9dKKgvI44SMaYCoGYAU8UQfcJLYIYVspyxU0UR54gX3E1Wf+lavQhtkAAWk+bES2pcGCFknVJPqyhN2J2qfA0gCtuNozPdMMVRt+ZDASEAZ0gAZrFtC9q7T9pJHiKGjv6MSmGgcgEYBc1j6KRzaW2uML5rYh7CcO7x7wJGOm0iw+QjTCJc8kMXuNWNq33Hu5aRYneMCXZEn6bhiYKKkJGFlktGBLS/9jaNHbm2z8yOloY7X+peAF4ap1bI/XWysWDw9eIMCVSsKITsZAanH6iyjYOVgAOcX9y7ZVvAdoY6O2Mg9JMX3RfebaomwMBnktGcujHogY41EOMHCf818HYzRsqODQoTH3tttzu/jii3Gve90LSin88Ic//K3L3hAIOuyww0BEEZQxMz7+8Y/jE5/4REdTfWOdz0O7SQ7o3/jGN3DmmWfikksuARHh7ne/O1796lf/Vifym6u9+MUvxotf/OJdfvehD31oxWcPf/jDccEFF9zCvdp1c0y4fLQGE5vhjoNtmDEltlkpJLdYFdDKIddSaiZdB/CZfcrBMWEmqzDXL5FnFjsX+hKG0UA9INRzEIaHRZjtrDBb/WGF8SSHMRZ1LaeZlDw1gpPsPv9UyUyolzPkM1UnxFGPM/RmShhvtaAgmYZyEcrN3vQa0S8pYYN0Jssyk4T7AJlsfNFXGIpO33bgYJY0mv0r5FfkgAb0SMFlXv9VMNB0o9HkwQaIRJdCgCoV3CoXj8mVRiYS48CkJASnINmGuWT7BXEZ5wzHsr9sGWI50Rf9VLEg52N5P43hFov+NgdbSBkVXTGavkI5p2BzQtMTAXsIxwGIbE4ES0FH5Cc8M5bPrVjutMWjyYcMgVjEOdob+Fp8MXRIaCf7sK+EKQp4pdgBTNagAzyCJxgbjoWa42feq4vjmFPUNwUQF/pKnACOABBTsKDYZ5hxTAqYdufmKVd8GaN2Qo0EStA/6bZPKzRSAYxEQbtP0vDWArZRiRUBd7ZLoNbwVnPLLsUHDgJRyGLzfU8E+qQYKFjsBJQHp94qgBvx2WLjNVFB+xWE8QN5CCE/ZqFgsdTtk2s+GOymBZPjuAe9ogPYqzhi6ZtwLrgFV8EMNGjE2HtJofYX1cBrHrUDaUg5qTBOITsv6LKMMMmTHT2QZqh+hfFSARAwBrDfugXUjrF9uY/VQ8lUnkwyAYwALv6Lk3HXfzkFP/9fr8V9zn8dLv6Lk7G33UBrnw9u+vp7QDvssMOwZcsWrF+/vgOGQkvB0Q2BoFuKENptMPXRj34Uz3nOc3DUUUfh6KOPBjPj29/+Nv70T/8UH/rQh/C0pz3tlujnHtk2DrdGo84tk3nMZ2PMZJKHP2pktt1ZFVhVSAqZAkeNlWOCAiPXcmHkpsGkMSj6NSZrCFm/xphm0LvOh8/806C6Loc5aBmFsViyCmtmR7h2kkNn/gLzN/7Us0XCeEA2rBF1EwSfWVMh8zqIyur4tEgq3qpFS+Un2azXwDlf2NQ7ZcfJAgBnkHCXBpp5J6Upxgr62kxCTiw6JNvjGIqCg2g2CGI9UABmh4FqgGqfRiYqC5m4vEZML2m4gY0hFWcgT9e5E2YgDEcwQFQSNnMZkE18wWbltVMLvr99gs0J5SrJpGRNMVSVLzmQUyhX+eMrIAxf3TJTzIhsFjHguAU+qpHvI2BQLRMVAVkgjxjRyyrR6LdyGCRMWAA7Qqy1ocAUn1K7PWJ0vaGCESR3gVQM74Fati3pX7RTYIpMF6EN7QWDyzZURvI9Q7YJrARSESihZTvDhJ5qkLzlQBSVJ7o/ASbt9RrYFSQPECE8FYTw0RdrSrzurGoNPX2/uyE0xOLAsG29vSjK90Akpvz7Y6JaxfJOsg1u9x2OwfmTEMKbHe+v5EJKW+gbJe8jkPLZe2E8jbBs8T4RroPCxfGkyFpJZrDoLT0rXStMxjnyQe0ftIDfbJ0DkWig/sf/k8y8S59yIu73hRMxmuS4x6ffgMwAh3/+JPQyh73tRrTbCZi67LLLsG7duvj+praU4box7cc//jEOPfRQGHPDUOnGbTFpb3rTm7Bp0yacd955OProo/F3f/d3OO+883D66afjlFNO2d3N3abbWYedi7lsAseEbWUfRtkOWJo0GUprouO5IoYiJ8uA5MWExilkymKYV6gqA7YKzhHyHYR6xrMEAaysL8F+HSKG0VaeGJMbaag/xt5HyjGh2tYTnYKfVLSS91lmoZTP6PPZgM7rrYLpJzPB5BZ50XRTpUcCqCJA8GAp1OvTJaF3VVsVPky6ugTMyE82waQzvVJDKMhBdCaZg52zoAXPwNUEPRHWCo0CCicld6x8p0rPWvgSKdlOBV3KNlXdskvEYrxZD1uw0N9qva6Z0BTwru/BcwrIl+J8B9tDZKTisTsvWvfC9SAQD75REZh4YXrKNEWdTGBD0OILJO8peFF5BgtotzEN1mR/nAjQ23Vax/p2YmYFCf+ErLKgoQvgKjBogSzJvHVA7loA55EfEUNnorXrmFkmWqaoj3LdfsCPcWdsSECa6AMhbEqwDQn6neD87x250zJL4TeR6qDSAQ5i9FiyqdKSBDGdeRnGxYM0buQaJYKE8jIX/akAgAxD5VZ0W4aBnk3MQ/2xBMrOZ8nCqna/AWRR0gFa0aH2fQB4AUgFEGjYZ24CKILdA0fQSoleK9hIsBNX82ACrI1D1mswWDWGNg7lUu7HVZa1tcI9Pv0GXLtjBnP9CQ7//ElYHPXkntVo9PIaFzz+jZjUBg/76quxt+1tALBhw4aok7r88stx4IEHYsOGDZ3XgQceiMsvv/y3bueP/uiPsHXr1hu93yOOOOJ6y9VNt91mpn71q1/hL/7iL1Z8/oQnPGGFgGtvAxwI28s++qbGlcurI9PETKgajdxY7KwKzOWlB1TYpZnnfoNFbBnNYv+1C/jvH+0H95sMdp5hlimGSsLNbG5mjNEkj+uSYtQTE+tiiWxFGCUpYtxHvnbsQRMQQDuRCNWNtqhqA+XDjs6qzgQVvKysVfGJNYYRph4wzbLcuJv1FfS1GZphIl72YbB6Bt42geNTtrlOS9kczTIhBUbGIdY745ylVhgT6tmQ2+3FxjmDK8AsKdmPN6MMnlY2ccOYrJW+6FHLDKkGYC3MVBRuWxKzTPgw3QTQFWNmK8NmStgpeDYq9DWwUKnOKQCPJOuOGK2APWUScP2fpWG26bmUw/8he3AauyTMFjHaidr3WXy5/DlJ952AnfBHFK1DgEIQHoPaAtcAPBAXdihkWQbQHFmcFEB5BiqWK4rAPQEdYfJPAFlq9hiKFae187gJeiq0ovd031NMjvSPIrsUfKGitomSgWFvPRIHWoAIZa7VMQVxeNgPIa5Dhr3Y3+84Fe2n2HLqfLRvuH1PYWC7i3Dpw+H+4UX2Ta043YfUWQnz3JQayFrwZBsFW4u7uW2EraNCOtSfLaEUY7RUIO/XqEYZJuMcs7NjMBMWl3twjmCKGkoBjVW426dOxk+POhkP+cqx+JOvvgoOhEmd4T8f2zXy3NsQWenfZf3daaeddho+9alP4ac//Sn6/T4e/OAH44wzzsChhx7aWe6SSy7Bcccdh2984xtwzuGe97wnPv7xj+OOd7wjAKk08qpXvQrnnHMOxuMx/vRP/xTvete7cIc73OEG+/CIRzwCV1999YoaewsLC3jEIx7xW8N8zIzXvva1GAwGN+p4q6q64YV8221m6qCDDsJXv/rVFZ9/9atf/Z3dwm+L7WMPeh/useo3yJWc4LlsjFxbzxo5ZMrCeMbHKIvGV6RXYCgIi5Uri23lADOZnFg72yDfTlAVodguwuJwY1y/ahH9rEbTaBABOyc97Du/2L23Al73Ie+LdSNo7aCVMFkAoJUApPBb06FmGSBGfI2K9gra3/htreTJn73w3OsvyBGyBXmRk4w2tSPzjI2UegmTth06NEOHes7rmsizSVV3Ug1ZbXHi7HmvBdMyAnGiZJnkXN/B9tgbg4rAGvAhRcWo5hk/eeMx0fOKtQCfalYYKtUwFg/SYjmgRFfFGrAFtTUBFaEeUsdtPAVSQNvvoIvyOvqWYUnDcNOTZGSB/Ne7Yq52cYMMbFe2KIac8SaciMjBohuj9F4UQYQPd/mwWfRrSifmwA4xYqYdaQflRc0dhssSXKNhK/E+iqaXoWOB5QqAOj2nwXGc2m0B8Pol6vRLRNrCopBibH6WN4704A2KBUiloncPpDY/59ipQcQK3ysxpvRmtjoZ/ABGw/h6Jizqvfx+RB8VgJ/3ZUMCeFwY76l+xHPsF1S7+i49Qenn6bIkrGHQVfmHMlKuE8oj//AUbA6IGHaUxTBmYL9NZsXI1x9TXWuxdFGtbxY7wuJiH7Vnz7V2qGsTtZ0MSOivyvH1Pz0TeoWh2N4WG9Pv/tqN9o1vfAMveclL8N3vfhdf/vKX0TQNHv3oR3fcxC+99FI85CEPwd3udjd8/etfx0UXXYTXvva16CVZhy9/+cvxr//6rzj33HPxzW9+E0tLS/jzP//zGyX6vr5svq1bt2I4HP7WdR/2sIfhZz/7GS688MIb9TriiCOu11Nzuu02M/XKV74SRx99NH7wgx/gwQ9+MIgI3/zmN/GhD30Ib3vb23Z3c7eLNjQlZrIqWiA0TsEoh8yDqoGpkXsgFUJ76T1wqRYLBceEdf1lVAca7JjvQ10yg3K1pPKXd5Eb37U7Z3CndddhsV9iPMkxmuS40+qt2JLPxZtptEggz1x5YAcAzmfSOCZo5aA9W2W0RWM1nCNk3n/KOQk3BqYKAFyj4BoNtayhJwSXQ0CUlfBZPScAir0wOGRw2X63BE0s5mqpnbgV+/R0CTPZvg83Oe8gbXymVPC1ivooErBVk7iga4ZZVLI+AWZCsLmE3w495SyQRtQNEXlXdAbGaxT0WO4/9UBMPqs5iq7lTV9AWjVLUQMVWtQ1xcy2NjPPBY1+AqRiTT7POq6wHgh6KKAFMv5zuMDSdK/DAJjquXabUegU5tKQzRXm4Qj02oMJ5wyBtZhu3AIeYrTmnel4RAZKdkxenxO0diGrjB1EixS0eonBZ9AhRX1UerzhupkKeR38sdOgMo7hKW3EfRsKXS8mYmz80Bl+P6oFRZ4BIw/cwzpkEhQT/rP+OCYCJqLlQRwEOe7LnvEaHPLPp3YYtJCJF8csEf93wrBAKzqfOgdYMeEEBIfkmpHfGYXfUbqJcB9KwF8AWMo4KFO18gIWq5RMWbhGgXLRTuZ5IyWxlICm3lCkCgCwOOphdjjB0rhAYcTAs6wyKGJ8/3Fvwn0/+1r8yVdfheXq5jNRvs21Dni+ievvRvviF7/Y+fvss8/G+vXr8f3vfx8Pe9jDAAAnnngiHv/4x2PTpk1xuUMOOSS+X1hYwAc+8AH80z/9Ex71qEcBEC32QQcdhK985St4zGMes8t9H3XUUQAAIsKzn/3sjrm2tRYXX3zx9XpOhvb1r3/9xh/sbrbdZqb+9m//Fueeey5++MMf4uUvfzn+7u/+Dj/60Y9w3nnn4YUvfOEt0cc9vmVkMeu1U5XTMUvPOhXZpioBUoHFAtr04JDdN2oyLIx6qJYljBdKsgDAcFDC1uKkXjca1iocsGoBPV3jwNU7AAAHrF6AVg6DfhXNCdO6fYDcg1XyPm29oobxLBYRwxiLPG/Qy2vRTfWayEI0s67DcthQ+NeDHTYc2SfA37ONFH2F8v47xoELh2ofKwVXST5v5qxsx3o/nJAq7zVAIpT1D19GCjQHMTSTFEMWgCdhJzOSl6pbPZMu0Wb8eZBTzUlIUNdioVDPIIaLXCbfB1d0SkzhmSQrL/o7JSxVxzQzZRBT1gn+72DwqVswFt8nWqW4DbTbJAaq1WKQmmKMyKL5964IQBdSgLqjYeKWYUoZpPRBNx4Dgb1IG5TUsANiFlzLhHBrnhn2FUJZgQFKxeZhEvDgWkJlyTpAR1cUHiCCEF10PnJyQ33KFbqnAPSCL5QHP8qzbVG4Hl9+xRB+zDgyaXG84rYRyy4dcs6pcLWORZVb76cpNO78SU36BgW5ttPWAZZTs+006OSwzZZdC9owIgmRR10ZwTOKCqGkFFikAgCQ5w2q0qA3qGCdQlHUsE6hajTq0ohcoDJRGjDoVVgcCVsxLCpUtcGwX2KmV+IhXzlWwoBVgdxY5MZG0fre9ofTFhYWAEj9XgBwzuFzn/sc7nrXu+Ixj3kM1q9fjwc96EH49Kc/Hdf5/ve/j7qu8ehHPzp+dsABB+Be97oXvv3tb1/vvkK9XGbG7Oxsp4bufvvthxe84AX46Ec/essc6I1oN8ka4UlPehKe9KQn3dx9uc22JS/I6ekajdPeqNNhkFVYrAoMswqrijFGjQCkhlUsN+NAgAYMOeyoevjlVevBjYLakcH2RDNVD4GmMighGXi/ukYyCIkYa/sjGHK448wOKM+CrV43xo6yh31nLK7cvqrT18BIhTYsKoyrDL2srWFUeAf3CTL08xpaOYzrDP1eBecUJhMtguqZGpYyMInAmwlwPYYzfkLWDMqcSFjGqmVZQmMSX6jMiSiXNC5/3rG407mnwi7kAAkYAgNUEZQPQXBD4MK1jtgNAUMHNBCBbc5gxwApaK9L0pWAH1O3YCdqm3y/QniPtWT5mWXRSjnjawwOUu2UAC7r17U9ROE4JYWQI9sUdG8+WhmASSAPgqYs7J8IsQhyHC4VuwpAwr/5zvb7crX4kqXDG/8Pczf7MdJdNgq+HzELza/YWj+07EU4HmGvFLgIQAZeJ8S4/HnHYuPZm0SLFfyO3BTo8ECrE4rQPgMQShisBHNQsGIImXNxNYq6umDKGUorRYNbota+IawX2KjUeDMdYKBrhun7TiRGrmm5lShVUmEg/YYIcLVnvhoFyqwwUn4ZrlU3BNoBsmizZSslGYDTQInSE9v2N/Y5jl9aFkasHwIzlWYS5v06JtGEbTgn9TuZ5X/rBEBbKGglf5vcYmlJwiXhHIwmOWYHwkxtX+5j2KswV0xQWYOqkULIQepQ6Abf+rPdLz57W283l2Yq1N4N7caUVWNmvOIVr8BDHvIQ3Ote9wIg5dqWlpZw+umn441vfCPOOOMMfPGLX8RRRx2Fr33ta3j4wx+OLVu2IM9zrF69urO9fffdd0X5t7SdffbZAICNGzfiVa961Q2G9H7fbbeZqb1t99u7Dv8octWgcgaFbmCURWU1RrWAp4k1McMvtCY4okOy/AKjtd+6BYABt6pGs8pKOZFcJoefHvW6+LQ9HJSYGZZQkHUL1eCOM9sBCOu0pjdGTzcYFq3ALi03oxRjtldiUhsQMXJjUXjjPQDIjUU/r9HLBEyVlQEzIc8amDUTZBuXkA9qYNCA15doZhzsQLLq4MW+rQ+R6Jk4mAv6Ozf5YsUhxZ2NEyC1U2p5qbFcvoFZoVomdc5Y2KpSgSail8FYA0pqi4Hha87JzSTfCWRLAoDynYCZiPt40B+FMa5n5P9mIIzQ7JUOeiKgRlUiWI9gxzNbATSxbku8uML7UIXTTS2IAtAtYBzCeQorWCqgBX6pdqpcIyJ6KKBaJc7usZhzPNlhu2I+qirfB5/R2GFRQh+91UUAVdMi9xiWBFqNU7KRYDRKjqTOXU3CHkGATptZRm3Yij2Q8VmdyjjoTF4IGqXQx5DhCbSsUdhMACHhsEhAQAhTx5ZosyJjmrto5RC2xSHxIWUSgZiU0Rk/46KhbLtg0q+wDRMAjM8AXDKg3CYAyY9FCJGmwM+HLtM6f531/K4DeEyZ6M4xMOLxEzG096ULPlTVOEPta/xJNqbFpU85EUZbiaznDapxhqbSMNqhnGTihs7yoKe0Q69Xy32KgaVxAWZCv5CHtd/snEXVaHmAMw36eY1MWxSmwSP+7ZXY26Ya3wwviBY6ZXpOO+20G9z1S1/6Ulx88cU455xz4mfOyXV+5JFH4phjjsFhhx2G448/Hn/+53+O97znPb/9UG6ks/nrX//6PzggBdxEZmpv2/02ZyZYrHu4djKDmazE+v4yluocldPeGkHukIr80xgIlXdlbJzorMZ1hkxbqNxCXdVDM+A2Q0wzDv3UyQBkIlnVG2OYVfj1ksyi915zNWZ0hWs8YDLk4IhiSC/cXDUBuRawt2PUjwWWM2UxrjPM98a4esc8Br0KhZHvDDkMekLTT6oMeS50DzOhGIquouzJxMC1n/kL16kJGJ7ewfB1/RIRSCjz0QPs9txrq1isb5YV3MABhYXV3uVSM2wYGwJoouCGVibYRgkjNtawAwc90miC9YFugVCxQ5zPm6L9zhkA3oyTlQjPqWkBlyk9M8WevcrRZsqRALAARjhHV+gdWAYPnKZZqhCWS0ghIHhQ+fWrWf828ZcCZL+hXuA0qNIVeT+rBHgQxGleJawVtdtmr6EKflDRmwgAZwJGgmcRBf1a1N8E5iphn1JQEBiY9H3Q0PlrW3kDWUC3zErQR4WOOLQsEMn+2QKUSZjYeef8FEgQeYf2oCPz+wPgS7acHneRlCGOy7AjGRPfX5eWbGJqPbEQGKLuuQjMGTuSbD8gsmiRraL22ILCib1tAYHa8GnsXDIG07sLrFwSMoyeXH44ne2uGDL44jExcNdPngKQFs1TaZD1GvSLCpMqQ1Y0IADDvli2jMsMw6LCjuU+ZocTedjzWkzLCo3VWJoUWDUcQxGjthqremMYch35w95287Yrr7yyU07mhlipl73sZfjMZz6Df//3f+9k4O2zzz4wxuAe97hHZ/m73/3u+OY3vwkA2G+//VBVFbZv395hp6655pob1DyF9slPfhIf//jHccUVV6zIuLu1TLr3MlO/p3b6fT6JNfkyej6ulKsGM1mFxink2mLUZDDKIfeujgoMQw7G+041rJBpi3GVwY4NmnU1svVj2FyEzwBgG4WmlpvaYlXAKIetO4fYsSweVxZes+VnYEWM1f1RDOEZ7cTLymrvYA4sLvei79Ugr1A7Lbop5dAzNTJ/g8uUW8FyWSsZf7bWyOdLgGWCbgECe+ExIpCioKuxJFdn5gBHML5ocpiQSDE4c1LHr2+hexZqVQUMGxGihwncZ+yR9b5CxkkBVwdQTWjmHOpZljCc9eyTAcb7eAsEr39SXv8UxeEMTFYT+ts4WjTokmEmLSgLhp0BCEkGoWzjklOO6VghpHqnlJlKNVRMyXfUZaMCQMmW5e9sUVi2fEGAT7YkQvc07MckxxrCrjHkmAKMAHCdB39+uc0vflXrPO6otSsAIuCID5kJxgE88eGZosufKxlzweOpzcyjNqTlKGGWKKbid0CCBx0ijJYHDvKFdIMuKJRVYW59jzph0sDaeAZFZw46t1CeVYpGnx5EpCwQM0EZh83PPF7OTZq52KiWCaLAmqGj04o1L0NojbhlswKoDJsslbzCcScML4WkgrBeeJPuJ3wa+hE/4+54pIL4JMxZjbP4AKYSoFuNMklAsYTRuOjIBSZVFvezY7mPfiEPWVpxzG7uZXUEd5UVujnTFo1Toillwh9/+Tg85CvH7mWpQvO/0Zv6Cud7bm6u87o+MMXMeOlLX4pPfepT+Ld/+zccfPDBne/zPMcDHvAA/OxnP+t8/vOf/zyWfbvf/e6HLMvw5S9/OX5/9dVX40c/+tGNAlNvf/vb8ZznPAfr16/HhRdeiAc+8IFYu3YtfvWrX+Fxj3vcbgzezdv2MlO/x3aX/m/Q1zWuq2ZgyGJSZljTG2PSGOTaRpATWjDyBAT4LFUFJnUGyhhZvwb9Ygh78Bh0VQ+GGEoB1bU96PVjLI8LVEMdi4lWzqB2GgNTY9RkEdQpYkzqDJmx6PmMmmFeYftyH2WZoVnK0PQqKDAK06C0Bj3TQCsHo1w0B12cFNFWITZ/o24WjWTgWXnihhE7BVdreerWznMcfjU/UcV6ZI0SbxugdWJWgDJibqh8Oja0nwByC8faP5ST1EsL/jkEBNdm/zXISeiOnNdAefbJLEkmn+350J4vLUIeWLAGetstJqulqLOqvYu6F4PbEMpLwYQDSPmsQQ+gOAEEAXh12AWfrZWyTeHzyOZp8fAKYnpOdFnFNvk8X5DVskVEYAjyxY89owRHrV4sPY8p06WAje8+MznP8iU5AhrpCxuGymxbCJeVMFDekoBJAO6GD2zqgrdgZKkZm//6OBz80dNaVsgDfG5UGx5jBhTF8DYIXr8DsFPgoBFKDDd3Fd4K/QxAPdTfc1ZqPN7p3FMTzVc7LgGAKePwq786AQd/7LQIQpR2cJ4JDfXrAL9OcoK51KJ3SscTCchhdBmuwiUnx1NIHYYu+SoeJ0X7kQjiwkOJB4cgABMNn9ALPajb2n1hk5aQ9ZuOTqwaZ8j7NXrDCuWkrdjdNBqDfoUf/E8xcz70Uydj2PP2Ln6MRlUWj7WyGjN9kSYYLUk6xITaahSmwece9nbsbVNt+l5xU9bfjfaSl7wE//zP/4z/+3//L2ZnZ6PGaX5+PloIvPrVr8ZTnvIUPOxhD8MjHvEIfPGLX8T5558fM+nm5+fxvOc9D6985Suxdu1arFmzBq961atw73vfO2b3/bb2rne9C+9973vxV3/1V/jwhz+MY489Focccghe97rXYdu2bbt3QDdju8nMVFVV+NnPfoamaW544b0NAPCbet5n6zXIyKFyGrlq4CCO5alZp7ihCyPlmDCuM+wc91DWpjsxE4CDxjIPK0a+bhwnDONFpFo5jK3ctCZW8LN4Wkn4sJ/XWJ7k2LY0wPblAZarHNoLf4tVpYTz/AyiSRipXDdonAKzd3IvDcpK/nfe0R0AmkpD5RZcqZi9RIphxwbciJM0AIQYFjckYb3cSZaSk79dpSVEOGhAmThbgwAzX8LktlOxXmmG7jcy6Qwb0KARpkIJWEDhxMVbc6JBYtgcnfIvzYywfk0fsH0WvVPGqIeiM3IaWDrAwEyk++O1hN52B9UIkFEuAUaBRQrZdxlQz7PYInhQ03kheZ8wUbElEyVHjyu/LSV9cwbdXzi1rFl4OQNkS+Ihldo2hG1FQ1FqGbGI+Tmct7B+987MjoTVidv0k3jI7jMBNITP0IIkn+UGAjb+0+lt/71XU5sByFFMHveTsmDhmiOOTFJgp0IGYbBpuOzpr4kO6qHpzMZQG1GS+QcPukLIyxI2/tPpfh8CGl2jgcWsBSpAZKh41NbLVL3GX88cfwed5kFbBD2hJVl2u361YGxXOplO6C+MOwFmpo5MGNcKrvQPC0asDcL6Wjko5TCYKeOmil4NdkoyfIsazOIZdZ/zX4e5/gTjMsO4zFBWmdxLssZnEwN1o6PZcON1bDvHPZTW4P89/K2xq0d86fjO/3vb76+9+93vxsLCAv7kT/4E+++/f3ydd955cZknPelJeM973oNNmzbh3ve+N97//vfjX/7lX/CQhzwkLnPWWWfhiU98Ip785Cfjj//4jzEYDHD++edDa72r3XbaFVdcERmsfr+PxcVFAMAzn/nMjn7r9912G0yNRiM873nPw2AwwD3vec9otX700Ufj9NNPv9k7eFtqv56sQqEaNE5j7DIcONgBABiYuqOdMj50pshBgUWgDpKnOQZIOzhHqA+exImEiLF6OMbscCJZfLPLEdBIeRmN6yZDLEz6mFiDUZNjqc5RW43cNGgqg8mvZ0RcykAvq1H0KmjlJGOPXARPAGBZYbkqcPXCHLYvDaCNQ9MoKMXduSA8OKeTqjdpTLOtwJDPfGhj87OOA+UywYTsn7i0bkGT0t2ZJ7AKSjvoooHOrYRqQvkThoRINANaLBDIT/ABlKS/CpcF4MFRw0SWhKnKgMq7tTc9L1IftJxDEHRHw86gvfIRKlXSCo+g6ZDfLidJIDJaUXyesEeRQUqy/6bd1cPn0yAtZuWFzwle6N0CKwBS/LcD7tI/2vPKNhFFE8CZkxIzoexLwNKJ/QAg17PSwbJAwEkw4AwPCzFsFsoNeYapmRgxA/WMDilunck9IxKE4lKcV747+KOnRfYLkP8lpKi8ZgkRSES9URoKo+QaC21mFw+bBKDfsrhp4kcAiJ1znTBT8UOF7t9AC55i7AdQWSJgV/6cJOfKWZ+g4U05qd+AGdD9Bq6WByHd9xpIp1CVmYQ0Vfv7ZRbLlHAMvX4FaxWsUxiXAo6GRSV+Uz40qLUk12jlUDcygc541sqBMKpyMBOGRYXvPFrmlcM+91oc8aXjYZ3CfT/72vj57brtCijv7mt3dse8y9ezn/3sznLPfe5z8Ytf/ALj8Rg/+MEPcOSRR3a+7/V6eMc73oGtW7diNBrh/PPPv9Gm3/vtt18sCbNhwwZ897vfBSA1+3iFEPH313YbTL3mNa/BRRddhK9//esdR9NHPepRHXS6t61sZz/gbMybEeYyKWx87WQWihg9LaadA1NhYEpvn9BEYDWTVSh0g6oyqMYZsl4jjuWZAAq2hDUzI6zujzDniyYXukHPC8TXzi4jVw1yLcaftRX9QWkNMm19SrOFnhCaWsM5hdxYzA8mmOmVKHQTGajAnlmnsDguWvE60AE2qZkfWG7qYkRI4FpJqCawFADCHV88fBw2fNAbvo2MPMWPVTvJQNzWQ0YQ0E5E4b3yQtkssyiKxjMMLMDAa4M4E/sEV0g2oTMsHlITCYVRI07oQV+lR1LzT1eQ+aoG8kXJ0gMkNFbOUTwclyGGTELILbifhxI1SNirAF46jua7aEzJeu3QReYrMFAgr4nKPChMWLFpBipbVDCLMrEaf5zwGWzCnrEvKdOeY9pVPT1/HEQQi4JaS8YeU8dYU+wQwrUC76SNtrxMcu0AnlVKaual2qK4rcBsRTQpAIBStofaAcuKRgBHNOSUzL5f/dUJYCd6P1eryD6FfkfAgwRAhaFIs+n8eRUw12XPgiA/tSiI4ciwSDoO7afoxoG58x+mxOauCcid/YOJa0OGtg1t6txFti5sKwAxZsBVGiZvUPQq9Io6VkgIdRBtIrYP4zKZZJjpl1geF+iZGstljpleFaUL1imMqgxaiVbTMmGmV2LiQ3+jSoDbEV86Hg/84gnoZ2LLINfL9fw4bmftd9FLRd3UHtYe+chH4vzzzwcAPO95z8MxxxyDP/uzP8NTnvKUW9Wyabc1U5/+9Kdx3nnn4X/8j//RSWO8xz3ugUsvvfRm7dxtsdWsMaMnuHoyh56Wm8PEivh8qS7gWKGnvSDcu547Jhj/JDicm6CqjH8yl2wbU1gMsirqoGaHkyhuXze3hPWDJRglmqxBJll4ihh9I/vPdYN+r8LSHRW4VmL46RT6WYW8kMy+SZMJAGsM5ntjEDHmB5Oo61qcFGLQiHYii+LWED7IrAjSl32octiIOBcM3bNy0278xBtqkoXMJReeqOXXb3K7kgVLmx8bnTkJPVrlxe8MzNUgggC6wnsB1QQuJAOwhuiGtOBSZDsB1aeOZogLYbWykWT96dLvUwtQCq7okY3K2n7FkBlaligwGgyZnDoZfOGRh9vP6iHAma/NCNlPcBYI5XJYAZyjBTCMrrA9ZaT8e7OkYjahGgu4UhCTVAACkMKhMAANIPpDIQLFzlwXwFX4M91vggk4HCMEBNmq1euQAqBbUCOFdZ2c12lAQcJEBd2T9UV5yV8v0SDUr+MStgokLukAxb+tT+oQgbyKgxh1WFbE5yAAmYveUFyrLiDuzP/cYZyiFouT63waL/jzjxDqTDIwU0AXixgHMOqUME8+64+ZoiYxHmOp48MOgFg/kBRLRl7RdAqhh35rarMBjRZAFhjxXq9G3Wgo5bBtNIB1CtZ/lxkbx12p1rfKglBkot3sZzXGtfxwQtZfzzT4r8edivt94UQc8aXj97JTt8P23ve+N1owvOhFL8KaNWvwzW9+E3/xF3+BF73oRbdav3YbTF177bUrCgwCwPLy8o3yiLi9N8cKW8o5OCY0rFE5LeCJpcRM8JYCgInNomndpBFAsLyzB505OEviNGwVVg3HyJUVYKQs7ji3w9fz62NNT0w7K2ewtljCqMlQuTYuHbJmZrwDscsIq2dGyLTFwHijTg1U1oGYkJsGlTXYOe5hfjAWgz4m1LWWJ3zyKeFpppJPuWaWm3Ys9eEnuGxYoyl1G0pJRSYKQK1EXzNWoDkL7Z+YXZLanaZ4B6aBjEwWWWbBxsHaNn5Gyokuo3DAWINz5ycpgBVDl54FUYDtCzhwBQtj45vNgZ0bxR7BTHyxZA9YbIFYKoYDwDJtVmDUL4VJMAFKscivnwsDEdEMW5CiLKDGvgZgArhCceTIdinEkjvKs2MRe3gQFzIBw8ZZ+XIxKtTHA1RFcD3v7eQZKQ6+U8k2W6W6BwNO3qfeSxEwJtYEEdyEjLuGQMZvj+BLqSTb9ewjILYBka2IIL4FbUq79poMVxgLmwKf2RevoxSIEEBoryvRSAmodLYFUnGbQcSeuRjKDmxT10W8vc5TM1F27cNC2892+8oEZlfL+THhYrqeRwpGTNiIdfY8E8dJSDLq1JLbt/L+Via3ng1qzXyZpXpDYKUDeFKAhP/8U4RWoolamogGs7GybmMVtHYY5DUqK/55ZWNQ1gbDoooPZ6E+6X897lQc/vmThO1qDB7whROQKd4LpG6nTSkFpdqg2pOf/GQ8+clPvhV7JG23w3wPeMAD8LnPfS7+HQDU+973PhxxxBE3X89uo+2aahZFsD/wOqRt5SD6NQFAZQ0apzFjyihEn8kqFL0Kg9mJhOQyC2sV5odjDLIKA1PDkIvslAngSlssNTlGTY7Fpoe5XOiWPCmwDMhkMuhVMm8ph0K3Wo+ebjCTl9CqffIMOgetnLBS/nOCPOk3lXjHmNxbJ2QWzcTI03rI2FKS/t1UWsJBwYOpUeBKyaSaSTyLDQODEHagzlN9eFoOLfwVMyEVQ/nizEg+M71awi89K6+ZBty34IxjKCy4jItZJ6MZcjQJTcGQquTvbBmoZwWoND0pomx7sh6UbJeVCNltznBBCO/DcruaF1kJkArviYU1C1mF0VIhUPeJUWh7ghPAFZYLnkRefM6Go2YqlN0BAb865hVwhbesMCzAUyEaaYbtR2ZFtwWAo1YJiHYIZNuwXHz+CqaYhCgaB1Iw4dEhEhYpPbwUkFLr4RQY3GndnWwydMzvc0p8HsKSEkJuHwra7bbH1jHf9N/zyKygALnxyJM4eXho1+/YJky1YC4aCVr/JrBikeUKjvKaQZmVbNfM20Z4ds8Utl02NRn1zU6MJHZ4sJQZK8ySU1DK4cdHvgGZsZIFnNfo5TWUvz8QcQRaC6OesINOtjGpvLM5MWqfqLLkReeDvAIzUDuFXl4jNyL+f+AXT5BtQtgqox2++5gbNpW8XTS+GV57QLv44osjG3XxxRf/1tet1XabmTrttNPw2Mc+Fj/5yU/QNA3e9ra34cc//jG+853v4Bvf+MYt0cfbVJszE4xdjllTYmyzWOJlYo0HODYK0CsnzFVlNRpW0F64mfmbTKYshrnU2Bs14hgMCFBaqgusyifYUfVQNgYzpoJjwup81JatcQpLZSFeL6ZB5d3OS1+93WkBSD3TYKkqYlmHSZNBa/HAaliKHRMxbK2h8gYms6hL45/0XRQCZ/0G9URmeGooZt9Vy776fCAeOowMgXsuPrkLMGonjcjeUBvCCC1MLnWjo6eQ82n1zpKEiogBLX5C7JQ4JjRSeLkMdgMGwspAQBBZgMk7gCtEt/NsERivk79d7sGJF69LPUIlJVMS4q1llQKIERYIQMfTikn2HUw22e+3nmFhzEbCpAUj0ChKD35K/jPyu6pn2xBhELIj+T6yFgo4+B1vBg898FbeqjMwOKrdZ2Cy2qw0v5wvIRMzA9OkAR+SiwaujLZ4cCjHEgAek1BKLMDC+f0G/6jwPlxDadsVg5kCayKAtLCXzMJiXfrUE8QSwYcLW41Xmw2oEi+rNOOOmUDDINym1mIggKQAYKaATEcLNDKgmboFWmDw2Mg5SoTtwRw0ZdDCRKn9w0zQMzpLsLWCyRuRCQQGLgFvbqLRXz2J2kNmYZwUgKo2YEU47HOvBTNhpqixXOXoZzUy5WCdeERVjcaamRKN1ejldcJkIbJPjgm1I6weij1MZTUKY9E04r1XNRpEwH8+9lT88ZePg3UKmbLR225va39qv8v6e0I77LDDsGXLFqxfvx6HHXYYiGiXYnMigrW3zvWx22DqwQ9+ML71rW/hzDPPxJ3udCd86UtfwuGHH47vfOc7uPe9731L9PE208685DEYaI2xEzDT1zUmNsOoEV1A5TSMM7GGn/Kuv44JCxMR+5eVgfGAqp/XWNdfRq4l9DZqMgxMHe0UJtZgYGp5+mtyzGUltpYzWJWPMfFWCYvjnrgNgzEsKnlaBKFqDEZVjrlignGdwXohb+00vvuY03DEl45HaQ12LPdhnWhDXENALmwVFVI1XisH1asxXipE76UKUIMYeqpGrS9N5EmZo0gcQOs91CQp8dQ6TKesQL1lgGy/kUzsTD60h0So7AGE85PKoPYTs2qNIjOGcw5UK7FD0KIfcvtXwIKBywFVCUhwGnCzQG+bhPbIIgq9qSG43EWHcJeLJouabikWO2yF9GZJxXBgWr+vmXGSRWgYqm6dzF0uKzYzLmYa5tv89i0QNEyp4Nz2xGi0nncwywk5nd6bAqESvvb+UPIdR2QWwolAe75C+Cu4n0/X15u+B7bnFBJmtWEbKrJV6TkE0AFPkV1J+h5E7UACoEhQVtBYtQArsE8MxS3bdqfz3tSCODB++eSTxK5herxSRswm15gVFip4OUWg5NnAOKa72A4IoGHdKYPDI7EooEHTOVekWIoPh7HyYx7Yp5TFNYbRTIByoQfdb6Az1xqY+rEr5ksoJcXMpVYnw3kWTfljmSkmUkUBhJmixKjKY3+q2mB+MEHZGKydWca4yiSsCNFKWSZk2iJXDr2s9hUWHGbzEqU1GHgx/KjKUJgGD/jCCcgN9rJRt+N22WWXYd26dfH9H2K7Saad9773vfHhD3/45u7Lbb5dV89iVk+w5Jmh0rXDL/5TFjvKHmYyuXEt1TlWFROpoZdVGGcZGptjrj9Brhus7y9jNpugtAZGWeRavKqW6hw93eA3y7NY21+GUQ7LdR7rAa7pjSLIWjUco3YKo9FAnhghgKlhYL4/Qe10a59gNcaNwX3Ofx0mlcSdiBi9vMZonEMZYc6GRYWFUQ/1xKCGlJcAgMk4Rz5for6mD1UT3NhEA0IVHM59o5BBFtiNRvRNdmKgZyQcKYAqsAEeNK0toyliAFIg8buKtd/QbrcZZwDJE3yaJs4Z4Arq6IFowYCcB0iKoCeig9IlIRsxdh4sIKbp+8kwkAfhsBRLth0ggncFuFV1V3ejVCdLjxzQDBkqlH0pxGfB5f6RlAAYFqd3r2FqhohFmm1flhPtUwtMAiNSr7IdpkyPklCSAuzQxqy9NGU/sEtUeW1ZMP0MXQ/jFoe8BQ0xpd62EzhFRoviKQJxzO4EPKvI5I1FKQrQY9/S/8kzXKpFkuS3H1hQdm3YV7YbOs+R2gt6K2byxp3cMfgEgF89Tcw6ybNs3Hi6FJwcP7rAPwAqbgFh6CMzAcsG6DcdxogGDXgs2a3k7QqipURYjgFlfMkdR+j7Mk8Mb9C77EGP8eFzR16vxnGMi7yBChIA/xClFMM5wmxRCYvUGGR5ieWygA4hT99memUndDf0lRO2L/cx1y+xOCmQawsNYFJnMRw/qvMYHhx7ltz4sGSu9/oZXm/bQ9il36UF9/Tp939IbbfBlNYaV1999QoR+tatW7F+/fpbjWLbE9rp9/kkNv3kcVibLWPJFli2cvPYUfaxc9yD1g4Hzi7gsu1rpNK6tzLomQY7yx7W9EdgJswVE6wpRshVA+uz6QwcerrGqMljJt98bxwNQfumRtlIoeVQumZU56i9gLyxCgujHvLMYjTOAZIafctljn1ml1F5Gn5pXAAMNL7YaVY06GUNGqsw2tmHKwjXbJmX8Je/ITeVhPbsYgaaL0HzFdzIyOSQsEqmaHwWlxKjTyZwTWL46TOLgqCXdfK0zzJBulpHgTAA2EYjCJWD4zpsmN3Q6nQA2LH/KWihxKhSbQiLxZQy1fwAIYxG6F0HLB4oGX3VPEPFEjYezCRaGwAg9sBoXgxIoT0QmmjYWa8x22riPlyowUeAqpS4laetagFYZIo44stuI88KKgGx5EjGxAvObS8twYLWTyqE0nx9O7BkQAZxeMpKTe8v/t8BVx5w7cIrLDqq+8LGgTkKhYCZ0FpqJEBwxd8UrpFdjEECQJxntoJzetoEYCdMlve5Cu2yp78GB3/stCgOBxCBDKhlfFrARCByiFmvuxgvAoMHrbdTMKiNiyRAKoY4O+wdAC1Fh4MnlPO/86zfCBtsCXaUSb3MsF3FGMxNUNYG/aJCY3WnqkHIuuv78lPjOocmjiWxQjLLUplHB/NtSwP08gbWCQO4XOYY5BLmG1cZjK/QAAijbZ2CAlAYi7LRMRxod3kx722/s+5pDwFin/nMZ270sk94whNuwZ5cf9ttMHV9plhlWSLP811+t7e17dh7fAGbfvI4bG8GaJzGwJSYyUsMMtE0Ldd5fMqbVBmWTYHaaWQeWB04uxBLzzhWUOSQKYvaeX8oJXX+Gm7f59oiVxY93aByOmYIKmJUXh9VTnLkRY1xmaEaZ9CZw86xhBZDWvLyJJdwlReWV4s54K3GnFNAqUBz3AFSIAE5MrkzbKWl7IT3xwpP8yH7irSDHlpo5eQpmiCAg6VsjNT+akN3SokOhC0Byxpu0HrrKONAiryxHCWMgQcRjZa6csNavjMMTHQUUIMZrEjKsyhCE5idhIQhK1l9LhfwYkYEl7P3dvLFlv04oCERtxuWmoPpREgQM0sPbOpVIrbPt2kBPw2JBosAVcvEFAXw2k+ggGTBKQZragXloTHFFHloFod5S9GUsxN7TAXVeetNhFID2kppHqcks2/atNiTNqTEfHXjR86QDxW1CzhJRIhJBN6IFggMWBv6S0upKM3ixJAI3zv2Al74zvBsV9QRuRjq65QuCkwQtxYJYXmlWAC5z/iTIsaiPwqhsYM/dlr0eiMloe4guo9MVdBLURiXltVKw2tBIO4ahcue9hrc6dxTYasgNPPHOmiSPibMEnNk0YpejUue9Hrc+zOvj4ki6XHC16hMH05M0bSglmWss+TBRCuH3HvShcy+2lsdWEeofTqmUVL0fFxmUkWBgMIIqKu18zX6gNqKHqqxCqHYemU1NLGAKq+XynWD2k1fYMDT/7/n42MPet+Kz/e222Z74hOf2Pl7WjOVOgn8wWum3v72twOQTr///e/HzMxM/M5ai3//93/H3e52t5u/h7fBduw9vhDfn3nJYwAAhWpw0dYDsTQpYB3BaAetHNYOlrFc5+ibGgNTYy6bRE2UURajpsCsNwEVANXAQcJ8S7WAWwV5egwC9Yk1yMki1w0yY+MNtxxnkQ1gJ/48ed5gsSowLrOO5ggM5DMV2Ek2zqrhGAvEKCc5MFHQq2rxjIKPqGUWrtZwE4PRxMDM1CJc935AoWBqmoKdD+qYHRgmOu29qppSR3GtswRXapBhqG0Z3KrGp4OLBsdWmYCMwMAwWidsBnhnotsiHzpxEloMGiNVipGl7QtDxX6i1xVQrZLsumbI0CVFRkjVEhKkmsAkoEVNlMzvFQG5g/Y12Wyl2huC5jh5sgKynUr8r2blO1d41/tG2KQQAmQCOGNY0/pMAYj6tNCCI3nM5vPaHSbPulE7qaZZdmBI1iPJl+xBcKqZbnU/8ufGj5zRAhluARCM67BIIeuuGWXiuJ1sIzSlJKwLoBVlJ6Ez0unNFejqtCjuJ7JVLODr0qeciEP++dQui8QEa8XM1jY6GorGiwat3UGweGBuw27xOOGZpuS346zq1BKMYIsB61lcKaGjWsBTaqh+08nYi8eqHLRmn1ThcMmTXo/7fva1AFRkpYgYVWWij1uHyQJ5gEgwebu8jJuMZXigCoAqsEkA0M8SMbzXP1U+g5aZMMgqTLwuNOuVkQ03ysUwXtkYaHKwTFha7mOmV2FVb4yxv4dN66X2AilptxcBesjkA4CvfOUrOO6443DqqafiiCOOABHh29/+Nk466SSceuqpv2Urt2wjvpH+66E69OWXX4473OEOnRo6eZ5j48aNOPnkk/GgBz3olunprdR27tyJ+fl5LCwsYG5u7hbZx/EX/2+sMcv4f7+5O+byEluWZzFXTLBUiXNwTzdYrAsMswq5spjJxCXdKIvKGgxMFQFW4yTzb2KNhAh9Db0ApCrvfg4IqNo+HmBSGYyXCijvj+MqDV1ImY1er8aPj3wD7vovp8SJDPAsgc/0CZNeljVwTmGyWEAXtvMdgPg0z1YJA5Q56F4DZVwMSQTzvpBeHfYFyBzVVAaxuC/QMl8TmSTUSMJgbmBBPh3clRqovatlLFScMC9BU2TEX4kzjk/wqiFkOwn1DIMD0+TXCwDLTIBqVoCMZPqJJ1WwMaCa4AoH5VkG1iIAtwOpQUjeyZ0bBVSq9XHqOWTXZlLyxls01LMseqkAHJQANFhhxEKYjzOGKpWwYGHSz/z3mZPxCIPac8LMhcwyH2JDTa0WSrVjFddLxeB+ncCQpWn+EZRNgScA0T6BfRhIznd73QSGKAIRRyK2ppZViazPUgY4QM1XrW9V0iJbCnRsCcJ3zioJByehPa1dDBe3GREcQ8uBDVI6AEZqxwBoQZhne2IpnOSYQlPGtQJ2lt+K8qHNOGaEuI0QAg3ALLqzA1FAbhPQNdo+AMU6ln6fWqxJ+sMSvbzxgvM29BbORcigS7Praqvj9+Mqw0yvjK7lc/0JMmXjw5EiRm01SmtEbmBaALZz3EPhARkRYzTJsXZ2GY2VZJeHffXVAKQPA1Pj/Ie+Y+XJ/QNqv485I+zjLq8+Fbro3fAK19NsOcEv/v6EW7SvN3e7173uhfe85z2dWn8A8B//8R94wQtegEsuueRW6deNZqaCgv4Rj3gEPvWpT2H16tW3WKdub+30+3wSALBon4TNo7W483yJi6/dH/vNLkb/qFAKxigXwRAgdayCCWfjdDT8DM7pjVOddXq6icALtq3eTlqKD4NJdBQsTEBjFQ7//EnQKoOtsxYQMcEMhZlqKg1TWJSTHEo7ZANhnVQaYgLArKBzi2aiRMDsCK7WKPq1v7n7iZxanxqgZS0AAB502VomuPAkD+ddzI2wSOx9meIETQJIlBVwE0J1YgkgoSq9RFA1wRZiNxCsBhpf2Nh6jygmQI8JxTaxTahnPBPk9TydyJqGMFKlal3PnSxndmg0q6UTEoIk0VMVXrdVqqgNC+aYdtbK58aDKKYYkqN0Em9IgBR5gEgQQTyhBZGQ91yT10EFoOQnbdNO4LIstxM3x5w4YV5sy9DEcxVE6FMZa2k5lnBsMWTl122tK9ABUuH6SC0TQJBMN5+wkPpBTbcI0rToo4KZJ3uxeepPxU55Vsp1wZcPFwpTphJwEow/2/1Lhp8kNhB4ij1LjEL93ypjWG/fEYX3pYb2SRypxsVZhaxo4vgo1dqD/OSJ8gAUvOEmSzny2RJNCLlDgNRwUIL7sj1NcpH1TCPF0asMDvJbD/cVxYwHfvEEABqWCbm2WBj1MD+YRCBFJKab6YPUMK8iINPkvNmvuKYPcqnJV1mNSSUJNktlgUxZ/OnXXgFAx/vZHzqQ2ttu+XbppZdifn5+xefz8/PYvHnz779Dvu22qu9rX/vaXiB1E9uxF/3lb/3+lHv/K/btLaLQDY7YfzPW95awtljG6lzq+eXKihO6B0OOCQqMpbqIjNSoEauFwEoZ1ZaACKagQdQJiNbJJDXuUq0KM6EuTeI0LouwD98ZX4iWNKMaZeJuHpoHPG3qOeBq0TuRdtCDGqrXIB9WyP1TqVaSvRMKokYdFbUGnAQBczqTcjIyuXOr+wm7d17Q7sM5FMI67WEKAPOrk/XAxwmIUCW1fk+G0cx59sgzPa6QzDxqgF8cf4xM6AEI5BIK1BVBlwQ1UdAT2R411GaNKUDvNCIg1wyqxKSUJtrXAlQx1BcKLquJAvdtq9lKNDfx2I33tYJn4BIgw5qBiRZ9WBgL/15lnn0IJpDGIdR0A7oFeNNaiBGgRRDl2bAI7lrA1+moZ6+CLko8m1pgAXhxeCDhQl+oDcUFYKaGdTz2sH76ks+wYpuRoVG8gq0Kffnlk0/qfBw0eoHJImL84i9PkuNQDmnxcaA9xphokVv86mkndJbRxsGYUNhZlol5Ej7sKfXxbBx37VmrYJoJyG/2p0e9Dnf/1/8DAJiMclirYHoNlPKlYXQ7Hj3TYKaoMPDrjyZ5rN9ptIPeBShtnIpi821LA/SLGjvHvQikZnuSUdsz8vuzVmGpzLF1WZ5w+rmUsbKs0FiFSZ3BshRFNlrc0DMlXnqllaSZbz5qE772yDfjMd94+Yr+3J5bCPP9Lq89rT3gAQ/Ay1/+clx99dXxsy1btuCVr3wlHvjAB95q/bpJ1gi//vWv8ZnPfAZXXHEFqqrqfPeWt7zlZunYbbFtuu8ncMwPnoqzDjv3epdRcFiTLePaagZDU2K5KTA0pbimG3idVO79p+Tm39NNDOsBrZjzumqIQjeYLyZonMLWeoC1vREAxILFvazG4rgHOzYyqVIbjtHawRRikleTB0o+zABHqCrjiw2T1yIR6nGGYqZMUsrlCZgAqJlKWKVGykmEJ+lQaiJl3Kb1MvHYlENVGuRFI1If4+BK49PlGfBG6mBCvZSDjISeUm+nWAsvsC4+DAMF2AFDTQh26MAZg42DKqxotzINqlUcn1Am5h4nnQXjgHIfLxBv/PZiBl5703JG9hM9oBhQSxp2joFc2DrkruvZlKS9c+6gRlrCknmbNaYmLRDoFiD2AMOHaFVgBSsJZbFK+tboGG7c/OzjsPEjp8fx6VgOcBi/IDA/3evTPLMUgCuxlFTxwvAQxkqBVwhTpYxQsC8IIaSuK7mA9xhai1o6B0uAma26TCbCdtoCuS1QZzhIqGxafM5O4dKnnoA7f/yNuNO5p8btAK0APXwWQBh5LVXYX9pn501jlXGoS4O7fvIUwP+mwvGnfbC+wHIAbPU4i4++rlbozVQSofUgqKwyEIn1wb0/83rUdQZtXNQYMgOUyXUsIUJGr6hbsMmEneMeVg/HHgjVnXvEcrUyuYiZMOxVGE1yZMZGZ/OlsgAAGG0xq6USw9alIXp5jUKLBjPXNo5RWRnkWYM1MyNUVvvzQvj+Y9+EP/v6Mfjyn5wV9/n/Hv7WFf24Xbdw7/pd1t/D2gc/+EE86UlPwoYNG3DHO94RAHDFFVfgrne9Kz796U/fav3abWbqq1/9Kg499FC8613vwpvf/GZ87Wtfw9lnn40PfvCD+MEPfnALdPG21c467Fy86qKnAACO+cFTcexFf4kTLz4qfr/pvp9ARhZr8xEK1WBoSgACoq6ZzOCiLQdge9nHz7auw8R6p3L4kB4rNL5EQ2UNlssci1WB7WUfihjz+cQXVjZQwVcGJMLzzEEXFpk38tPGot+rsHo4Rm5sJ0WajAM1hHpsfEjCs1UkJVricooxHJTx76iB8mHCIFCdVN4GgNtXunzamkbHUBP57MAYRvJgkI2wPKqwkrmkhKEhh8iQsALYl4yRUimIDFXcrWKYmRo6t91SI1pCiYBshxoBVnosgI2DR5YSYJUaNosZJ4GchBSpEcYquy4TwBeAkGLY9VWsjQcF1GsayeornOieAG9P8FvuiIwIpAQABuQkf6uet2cAxFbCA52NZ28CrPLj17I9zMKIhL8P/uhp8n3IonPwcdCWKVTGYfOzjp/STMnr0qee0Pk7tvCeCU2p8Yu/PCkuB0gfbCXXQrgesrmydccP4ExxJ9ycgpwAXlqQlMRJAdzp3FM7rFQH1CUlbwITJRloLaubvsIxhQeIppZsNePZQJWwftNgkxnI+rWUhVGM4fxEHMn9vi7681N8VQQPNIMmckcPzcQg81UJwrHneQNjLLRPcim0FD5fN7cUf+cNq9jva3fOYK6YYDZf+VseTXK/nmxrrphgmFdorMLWxSG2LQ0AAGtnliU7ucoxzCtUVmNcShix35MH8klj0M9qfP9xb0LmxzQFUnvb3gYAd77znXHxxRfjs5/9LI4++mi87GUvw+c+9zn88Ic/xJ3vfOdbrV83WoAe2gMf+EA89rGPxcknn4zZ2VlcdNFFWL9+PZ7+9KfjsY99LP72b//2lurrrdJ+H2LCXbUTLz4KW+shMnLo6wo1ayw3BS5dXAvrFLYuD1H7m/cdVu8Q35ZGCiNn2mJh0kfZSJhtkNfoZxVmsirqpxqnsFD1sHVxCGsVrH8CNlro9SJrUJgGPVOjsgZLZY6ykvBhNcrAtYLuNTC5RVPrVoCLdoIIf+uwz0Q8roxPPbcKSrEXoLfHn4b2UsaKGWishq21COIDM+A1RRwMJgkCPBIRtF5KiFjiQJ7I3D8h8XOyYsJZrbYgS3B9J2Aj2Agohl7SIjxfDp2SYsj1vM/c0z5MaIWVSmvisZ8onWkxUDUv4S1VKcnUU5CahAzoRRP77/o+7FYLGGPvMA4GVKm8yJu6dgiQ/cUh9GEwzgQQs2HoXgNXaVDmwLWKgnKoRONDwcKCuxYAgaVz3p4ihPNCuDgJKQESfg2aokufcqJnaJK+JgxNWKfx4a1otum79Msnn4S7fOKNHcH6dNKDbMdfR46mPgd2dfdLzTzlA+r2PYxHeDjgdoADIEv3FfRdQWOljUVTaZAWk9ug1woMkrMKJreiC/T7spVG3q9ReJG4tSpi02Bh4LjNeh0vFgAI/dlJTOww2sJoKfDNLBnDq4cjyfZlqbvXWClbFY4tlIEZ5iUWyx7GVYY8azCa5JjplciN2JgsjHvItYVlhX5WY9vSAINe5e8/FbYvD7BqMMa4zlDWRmr6mUbsFdIahSweU8O8xNce+eaVJ2cPaL9PAfpdX/G7C9B//pY9S4D+h9p2O8x3ySWX4JxzzpGVjcF4PMbMzAxOPvlkHHnkkbc5MHVrtTfd51M465JHY1szxKye4Lp6Bgf0dmBdvohvX3cw7r//Ffjv0Tx+/sODUM8tojANMl/ceOtoiHGZoWk0ekUN429yoyaTosVZhRFnKHSDfecW0bDCtTtnUGSN10m4KDgFEGtkae2gATRGg4mR9ZqomwJkEshzMfAM4YQir8FMGI1zYZG8NibLfOHUiYEz/z97bx4uWVVeja89naGq7tRzg9igoIDMiiBfAiKDOEfz+akxBo3R/IyIEIwJjp0oYHAgmkSTqMEEJ2LUSBQBRcQRBwziQIgBBESg6b59hxrOsIffH+/e+5y63QwNDS163+ep595bt+rUrlPDWWe9613L+rZfE5RKiTJsm/3CGIEzkVqUI+XND130MGLSUy5mHFQww2A7XhNUUqvOccB1DNhAkLmmA8AZXE1O4MwBalGinqCWH6sJCRGbBJgMMWxYd5pWmhwGY0n6f3AjDzExTqDJs0MDsmxqwWt/Xy1Is8XRGIa2gBQcouCe/ofYWqONIk4eOg9u4oMBMTYHhqY3g0kquPfYsi2mxG8vTKTRg3swAs8S1ZzW2nrJuHTbgJUw3cbAsPe/vR1c+NYdEP24gh0VZSg2IusoHvc/9/nU2/Gz57+JAFnr/dGekqMcOtP637ZgK7QMY7tvKdMX/260Vs7wbc1GfbVblpw7aEteVdYCwrN/jCNOKTIPsoLAntYtIJRBtZBC5Jp8oPh4jFL4jNEELGkYh4s5nOUQqUavW6CoVMy0tJZjWEnkWQ3ODazlqI2A4BbahODy4Pdk49+jWmIqGwGglp8FQ5pozA9zio5izuscgZlsiGGdoJNRmgLjDpWW6KZVbBVO5gTw5gY5nP9belBZWw7B7cMWSD3U9UB1Tw9HzRQADAYDXHnllduVGp166qm7ZE07DKa63S7Kkuje3XbbDTfccAMe97jHAQA2b968c1f3G16n73cZALJOmJL0ZZbKGses+V9srTuYFV1M7jmHXNW4eXYGgjsoabD1hhmwlSUxCI6hrCnPr6gVZD4EZxbTyShqrSor0F05i36VYusgx1SHvuy04YCkL1TjaLIvkQZSGWgn4iTOoEyiX1XQpcB/werwZV1IoOSAdGDKopeVSJXGnXYS9UjBhANESyzcFgm3f2dLvgFYsGjwE2FcGlgjSXytmhBcJ5rJtqBXcsyBrShh+wqOA6IvaJIPIBsFDYqQUQYwAmLEoBYp2Lia9jfLvZFm0EH5VqHz02zh2B6AVGSqgj9R0DQ5MvpEAGJxYg6wObUsoRxQUDvRKhfbgtuwUW4c2MTJuqBlcsS0hNFDq3krf88vnjma9BOOjDlbIAcgIXY8uPPA3Djc9OIz8aiPnx1RYhBmA/TeuPGFb8SjP3k2MUCt9jFAbGR8zsyDD4QWIxsDQ4w5PObTb4tAD4y80UTwsAJpqeL7hLX6jPE6ROfzpVqrsN54W9Hs1DZjF+qGF7wR+3zq7a3HQow0CusONgtWM6SZhrEc1UhBpRpCePCleSuE2yFJa8/g2piRGdYWwO2onyLp1JiYGkXtUgA5GsQ8M+6QZzUqLdDNDBJR02e8td75IbEcPd96G1YKkznJA6ayETHaRY5pD66KUkVQOJEW0U+q1gLdlNp9gzKJ+3G6O8K3T3wHjrz0TMz0hpgfZtFrylgGwRy+feI7sFz3sfzH9QHd/2FW//Vf/4WnP/3pGA6HGAwGWLFiBTZv3oxOp4M1a9bsMjC1w5qpI488Et/85jcBAM94xjNwxhln4KyzzsIf/uEf4sgjj9zpC1wusk4YGjqrs45DMYOUa6xIBzho9e1YkQ5x6PrbsPfKzZi9dRpixCFuzoFfZNCGx/FmwS36VYrCUB5WJsgINBMaklmMaoU8Jc2TiXoShlxVSITx6e9hgopageRlwzEYph440aczaCgACj4VIfBXkCh2y1wPmxd6pMGJLZz2QWKJRqXVxgm3CTV2wAsTfj7SBRUnlqlsfKbAHdhUBbaiBGpix6AcXa+b8GAwh3rSwSoL5if/RBEc0cnMs54k2wReEcBq5/FVq0383Uq6tIEUc/5nTfopMNeKbwGCiN1lNgIuVnJvGuqfuyIRuZOOtFThOuXgErrEybrW5J9jBBJpYg8IBpaRjop6oNYbccm+Dy0/54FZ0BFRhh1tM7iZN6+jwz6fejuENBBB59Pssma7jFpgcYLQv/aBnQnXh3zGEH4dtEHMt5AZIxdzAvjNtgMIbL+/lvo+Ac3jhd/B3JjfGi2MQQhL+rEWIGv/jGHP/rG5sqgqCcFtzK4Mu5h7A05dC8isjoArnFSEFp2SxCaWpYJMqd0mBWmpjGUYlQpZUnvWh9iucJ9RqTA/yGEctfGUB7WTeQnt/aNGHkgNqwQLZYa5UY6tI9JAzRU5RiWJ3lf3+rCO4a5+L1oxTGRldDdfNTHARF5iIi+xtd/Bfp/9SzDmInALgE5wh++etOtMF5fr4VGnn346nvWsZ2F2dhZ5nuOqq67CzTffjMc//vF417vetcvWtcPM1Hve8x70+30AwMaNG9Hv93HhhRdi7733xnnnnbfTF7hcVAs6h+IGihkUViHlGpOyQGkltBOoLeVYPXbfX+CG7z4SXJPhpNGkg0iEgRLUWiuMhGQJOrKC5AbSC9cBIFfkayU4R1lLSnH3UTeh1cKZi4yBsfQYwUG5KNWYYJl0GgbdvMQc64Am/iSYcCj6KbgyNF7OHcpSxSm/pYagtL1xjcv4Qd3FA78uCRzxTMPOJ5HBYYkBSkXZgCW1XphhYKmFSENOoARbWQK/zCKDBQ5qrzlAjoiRCi00MSJgIyvA+um+Yg21cpzwwcZBV8SAaoVBukUQiAptOA44QaCGaZA7OmtAHSvJIgHKZ9O1mCwwNAaehnlBPP3PKReF5mRs5cEqA03ZWQZo7qc4gUhnOf+cW8xVfA4BSHDv0WRbkSlowBUXJBBnwk+r2dBKa7Uhl4CsGHnSKgYg2iF4QBRuHzV5QRCPhgkKrWQHcs2Pz6G1YSENufCzZnvt91uYQg2ttDBZF0J/o+eVfy+mnRrliJiZoPECvGeW3/emlFB5DcBBSm+OGQCS/0wFcBG0hLUWmJgaxTUFrWRozTnLYEHaqf4ohRQGStJlMEoh/L6oKoaFfoZup0QnqaMeyjoGWA4lDOaGeRS2hxOq8DMw1AAwKpX/H6e2XlLBIlgqGJ/rR89vUCWUoOAYJjs0WTw3yJEm5GeVSIPaCHTUeLtmue5D/QYyU9dccw3+8R//EUIICCFQliUe9ahH4dxzz8XJJ5+M5z3vefe+kQehdpiZetSjHoWDDjoIANDpdPD+978f1157LT7zmc/8yqY5/zoUZxbzOse8ziGYxcgmSLlGyjVFPVjhp/iEz28D6p5DJ68gPO3P4UhXBZroi7E0zEJyi5l8iImkhPLZf1JYKEGZfkEbYa2PkmDw/lP0pT/VGUG1XIw5azyjpvICuarR7ZBlgso0VKohszq2WOpCRhBF2inEdd9dZZ2KmChJ+q3g8cOYA0sMte4SC3Q13CT563ADuEUFpnlkhTAScazfrGm+0JkD7EwNXnJw3QT7Br0T1/DxMi1BOQO1xPxkYbGbjiySTR3AgWJ3P/HogGKNje0wOA+gWKOTiuyVBbmWB+bKAwwCe619FKbZ2mHIwsFlvvcYROERiPqlaL+xoNsJz6W9/1tAI3iNhecRAHSYzgvi6SZ7bpxR2s4mxxnGdssXFKzNWs8zRrC0tuNa92t1/pptBYbInxC0gdn2yhoejzXOMm8DElp2DePmPDNmHUPWqfx7sbFfCJ5o1Aal9ycXBMKCVioCthYrGz2o/H1+9Oy/RMjMi0amnv1TyqCoFIwOQnIxrh0zHEoZ9LoleikFDROQoc+24BYcDpN54fcv7eOtgw46SQ3rGBYLsjwYFhTQPtUpsGZqEYKTNxRA+zW09sN2OBxWTQww1Slill+e1mMDJpmq8dXjdh2r8HCt8DZ8IJeHWymlEKK31q5di1tuuQUAmXaG33dF3S+fKQCoqgqbNm0ay8wBEH0flmvn1nsPJdH/a37wYvREiZTV+GU5hUlZoPZUfU+WKIzEno//BW78ye7Yc/9fUhvABBM8B8ktMqmj2SdnDgk3PqaGgMSgTmAsRyo0lDD4wtHvw7FfOQN9/2UajlK1pi/NPKsghUWiTDzIWa+56iQ1ilrBOWAiK6GkgTYctRbQVpITtfXMVvu43WYImFsy0TfOXjgHb9FA01BggC0ExFDAJt6AMjEEVqZr8NnER7ow8JLBrirj48lUgzGgmgnmhv4bx7CYu2clfMQLg00NqgzIbhdRdA4LsIrDdQ1Y4YGn9IxRRtqnYrVFfidHdhdHuYoE7uD0OK6V7+YYPU402Qw2EMoBqW2MMV1LHG19DiHgQZ2/ngNMWWKlKtHsYwdip2IUjGv0VdJ53yXWZNd5nyUuA7jwLuiOgn+BwNg0gEcIeh2Ez4oLQIde63GGql2BMVo6IdpuCbdB11LA5fzzCxOHYSLRGA4pDVwrRHcpMxZBWRCF6/Fzz9DSk4kZ2zdhepXYvcZ3Kui3OA9TfLQ/6roBIrb1/MK0a1VIXPd7b8VB//kWatEVCZJEo/LTsZw71DWxVc4wQBF4ksKgHFILcM30Ygw3D8AJAKbSAv06QW3p/nDATI+86Ka7IyyMMmztdyDiFKCE8FOAWwcdjCrVrBcOc8OcWCpH+zWwTrURxGIHk+DWazSq1XZbrMu1XNurQw89FN///vfxmMc8Bsceeyze8pa3YPPmzbjgggtw4IEH7rJ17TAz9T//8z/47d/+beR5jg0bNmCvvfbCXnvthT333DPm9y3Xfatzfvr0Hb7P3x72MWSczuoEcygtOaJ3RYUJVWD3zjwSYbDvQbfgkb05rO8uYNILQ/tlipEXiCbeWya4pc9VWfwyr03wy3HoVymOvPTMKEgPX/KhhUeaKmKkJrMCu03Po5fRmW+tBYaVQmUE+gXFQ+SqhvaJ8c4B1XwK3Q9fyDu+D4W0kN6YkM76PVOgLEzXgE3WEUiBARhKn5PHYuhwOzQWaFqJIjVA30fsOGrjaZKMQGdAtUqTS7kFeUEx7yllGWyXLCZcz6Dco0K1tka9W9W03JTF6BGadFSphRjwhnKXxGBZD6BsZkkP1THEMkkPpHxbzmnPWHkz1Rgrw0lPFeNmEkMH90qAKb+tsF/CY0dhNWIYsXMUbdLO0QMQ/cJizpyjfR/+z4WDTA1NvXkg1U0rauUGTdTdnBqP+TOFvy1DNUjimprJz9bt0DBRnDmaUJX0+se2Heh37dtl7WrczP2ahW1eFp+F19ZahbURO0RAfMzFnzukqYZS5OsU/J2M4bDeFiA8VqI0rc27uneyCpxbTE6N8PgvvpF0j4JOXgJ4Cp9FpQySRCPvVsT6cIvhKEXeKyEE6SG/feI7kAiNVNDntT0tyz0YloxayUv1TNYyzHSp1Si4xcIog+A0SDLTHRJY5LS/LUifGTzvnENkrnJVx9fLOYrHSpYMISzXDpTbCZeHWZ199tlYv349AOBtb3sbVq5ciVe96lXYtGkT/umf/mmXrWuHmamXvexlkFLi85//PNavXx/ptuXa8Tpz/4vv1/0MGEorsT6dx8+HKyF54zMz8O7o11/+aOz+jB9iUhaYUiPc4FahNgJKGAy1grZklcCZi1oHKEQxajDyk9xidtRBVWaYyMv4xVhr0kQMRilYXqKbVBCs+WKc6Q5x5/wEhHXRULC2Yfzan+Uan6eXWmqBSGrx3ZdqWyiEiawmoJYRm8IdsDWBm6zhNAf3ER1MM6g+g+44mEmyk4geRl7bo3oV9CCJ4cQAaaCCXQEYIOcFTM/CSYtyFZDe5dmpEJjsW3AsTPVpRgxQECMDKNfXEH0J10riiV5NPniamCgLpzmYcmRjUFEkDOXhNdsDENuEgG8PJpZYtgACmIveXIGRYsq7k4O1Jv8apicCloC1Wq2z9vXx99AiDMBUWCRKR20fOPCT52zE/v+xcZuW3Ta6KX/i4BxD2iubg3EAiW0LjNb9rW1OAMJ2+ZJsy+3VPp96O6wll/7au8IDxPYsNfYMzFAQfxsPIOjzYaJnU1hHI2b3NiCgzzMAjIoktiFpW8Tk5KrAqCaxd2CDOac2YV1KqFT7aCmgrsUYw9tNKwyrBFPZCCd89XQAHKU3+xWMAI+xHLWXCQSTTcEt5gb5WBt2sUiRKDohGtUKk1mBrYMOJvMCM/kIFgyJ1BhVCv0ixUx3GNkwwESAG4ZipG8zcuZQ1OoeX5Pl2n490Fbdw63N55zD6tWro4PA6tWrcfHF9+84urNrh5mpIP562tOehkMOOQQHH3zw2OXBqq1bt+IlL3kJpqamMDU1hZe85CWYm5u7x/u89KUvBWNs7PJwmzjc+OPnbHPdmftfjL5JsaD92aMVmK9zbK266MoKhZEo1hiMjAJnFj1ZoSPr2ObryBqSW0wnBTKhUXmQFQ4yM+kIHVkj8Sntu/UWMJWN4BxN8HWSGp2MJvxmekMKRmUWlZEY1WpMsF7WEsYyJMpg6yDH3DAnTYcWJMrtGvDEQCgbvXCWlo1nsg0j4UC/K2VgtIhO7MHLymmOdLKE62m4moMPBNjmFKxbk1ZplYXJHFgn6LxIzxJE0s4xyM2SfKIqBlE0bT7HAT1Bpp7wuWnoaThJ3lNIbNRMRVAiHJi3aQhtO9cCVXZSg48EMUPcUatPOTjlY2385J1ziMySq3lkulxras5x2gZzADLrb8sQNFMI7csAQrhrgFT4cg3fsh6shGk5Lh0ZrkoCifFcasnPaOIJRObKWh5H/DlzeNznNt5te6cNPNrX8dYlRhL5/1nHkCY1lDRIkxp5Ru9DY3mLTbXRaDIwR0vdx8NzZcFioPX8Ays11pL2E621FjH3Twrv46RFfF+HDMq2JooxinUByDZBcJrSy5IaVS0xmROQylUNzhs2OOzqbrdEltTI0yqad2aJJgG60hhWCVb2BgjGnR3ZJBQYR8a9tRXYvNjFVg+kGBA/h5w37CGBpiFGtcJMPoyfzURoap36+3QTWsugSiCZjc8zgKbaCvAW+v7ace9cnuJbrvtUzjnss88++MUvfrGrl7JN7TCY2n///XeJn9Tv/d7v4ZprrsEll1yCSy65BNdccw1e8pKX3Ov9TjrpJNx+++3x8quCYu9rbTzgc9u9/v2HfRQp16isBGcOs2WOoVb4n/nV6FcpxEyFW/vTmKs76OsEmaf2F6sUQ62wUKVYqFNkQqMja0wmJYnRuUXSyj/JhEYiCFTlfgKotpQsH748Qxp8IojiL40kzZXSFArrvGOz/wn4A1DlW2Re6xRcndvi2qVAKlT7EMy4hZAWSRT+0sGxLiVkpwZLbPRlcn1FdgGJ1ymFg79rfoZYkACi6M5oJvA4IPscJreA4aRD4g7VI0pUe5QE5hyxPsyzWPRJcxDzEnxAoIkl5K5up2vwBRm6dg3JVFAAMlhr3N6DJqd5DMVlssWWeIDEEwOW66h3Yr512AZJY+09oAFbgBdrIbbUAAJIN7zwDQ07459nA8Ca32968ZnNcwfGGCHnRchjLuFLtErW8ggO2hXaYksv1z33rREscW49I9QsiwfbAN78PwjR7ZLHpmlVAnzWa8WCi3nczdzB1DT6H3RI4frwfKgNZ+PkW+n1RWGwIqzReKNKlWjfIiRdoZImBgqH+JVEGFTaM7yeORMerDnH0MnJ22kiK7Fmoo+VvQHmhnmMnPrC0e+LADOc8ITnP5EXsZU32Sm22ff9IsXWUQfrJxZQeXYrhBpXRtLn32s0Z/IhukmFYZ2g8sHFYXpw/cQCUqXx3ZPOxjeOP3ebx1muHajfsDYf5xz77LMPtmzZsquXsk3tcJvvr//6r/H6178eZ599Ng488EAoNU7PPhiW9Ndddx0uueQSXHXVVTjiiCMAAB/84AfxpCc9Cddffz0e+9jH3u190zTFunXrdvqafhWqdgKPm/glbilWYDIp8ZM71qGuJLlRW4ZfbJrBHXOTOH6v6zGlRujXCQrjsFBmYCxk9dFBQAKAoER4ya0HVQTAuKfqc1lHbUVtmnZCbb0QXdaoDFBDoDICeVKjrCWcY0iURqVT6EpCdUrUpWy0NvBj9l5HRQxMczBsM1LbK9nKilOZRjWg96TTHMYB8IaUQpM3lBhymEkDJ5tpwTELhpC1lreCi3kLcPnWmOsZ8EUBt5I0OTLT0EOF5JcJynX12BcV4xbOeJdw4cA8eLK5BR9xOO4ouibm6JFXFEIwMEDEkaasQQoMbsAgzwwFCS+NMWGNzskZvn0A5fVOtN9ZY7BpGXjS7FtjRDSlpBs0aIWB1hJYjEd/8uw4/QaG2DYL1Z5I04ZHB+ylAEr69iCHb0d7oOs8IAhu+4d84c1IFUNRKaSq8W1qv74iaOpcswb6XyNuj+DCAVxZmNZyosjcP75QxGRax6K/UmjvBWuP8TU0P2OUUqsFGITZ5N1GXlKlZ6e04ehmFYzjWNEbxla7UJQ4UGmBLKlRVhITeTk2BbuiQyyScRz/50t/HgPS5/odrPBiczLqRTTtXRjSd8SMF6Eby/CI6Tl6TZil8HMrkMk6aqQCwApDL2UtIbhDIjUqH8SeqwqjWi2DqJ1VDxQQPczAFACce+65+LM/+zN84AMfwAEHHLCrlxNrh8HU8ccfDwA47rjjxq6ngx+DMTtfTPjtb38bU1NTEUgBZB46NTWFb33rW/cIpr761a9izZo1mJ6exjHHHIOzzjoLa9asudvbl2UZHd4BykD6Va3zDvkkTr/mhZiQBQY6QbGQEvtgGOADYFf0hhBwADfY0JvFXcUEhkJDO+7tFDgyUWOuIt+pjqAoGW0FJLNkn+CP2MFV2cSDCp2trur1o/kfTQvWqIzXxjhgVa+PUZ3Q5JIFpjojlLWMH2TrY0PMSELkGsbrxRNJrce6lmMH4qXTX20mCwBE4uNNDAObTaLhJjOAXPTByJaBd2qKEpGWjB8dATpTCbB5CVmSp5NVoIOrP0ab3EIMOfiChJ2piNCRjlzeOVA9oiKtkmP0WEEnM6ci+8QsgJmKomBGnq0L3lFA40buPPpZCqTQ3M4BpIeSNma8tfVOABDG2gJrF3VKDD6cGI2Y3HrBufDtP+ZF16zJyQO3sJo3TuBhOZ4xawcNhzZcaH0BBBjKWsRg3cByGi9qT6WGcTxOf6bSQGseAY8QFpmqUNRNSHamtNcAsQje2u8PegwbHys4+of3dwAw1scwlbUcp0DRgEZraMKQDDTJ06nymXMhrDvk4AWmLYi0g0M5lwbGMnAPxozlUK33ubEM3bRCqWUzFcka8XemahjHsTjIwIVFKg16aRWfa2U5Mln7zx1N1FVGRF3jdHeESgssjjI4+DZedwTryA9qcZRitt+BkgaJstg06GFddxF3DXvbtGCtY6g0nUANqgQZ6PuBtFwO4BYKDsZxfO24d2K5luv+1u///u9jOBzi4IMPRpIkyPN87P+zszelt+gAAOjTSURBVLO7ZF07DKauuOKKB2Md91h33HHHdgHQmjVrcMcdd9zt/Z72tKfh+c9/PjZs2ICbbroJb37zm/GUpzwFV199NdI03e59zjnnHPzlX/7lTlv7/a03/+i5eNuBn73X2/1yNI09OlthHWmEyoWUNDIjiQMffSsSbnBHMYkN3Vm86+AL8f9d/RJw1kVlBebKDLNljjW5wYp0AOsBVsINLGPRmyroGzgcEmEiyAk+NYVWdIbqD1qSW0xnIwyqFFIaJMJgvhDQRmDtqgWkQmPN1CK0Edg6yMEcg0wMqloQkMl8WKxrxsqDJqZ9bAsH1kRplLUEA1CXAlxaiIRAgVUCYugn3AJr40XdbqDgJIEC2a1gagGuDNh8SmaehgKMwQlQMcvAayDdLGAyB901YKUA69UekDD8/OQ/x97nngfHHcyqmtgaDzhi5AtzcJwB80nzXDIb1xWAFPPmneCMgo8D8PFsErNko8CCbYJrWmfOMnDVsEqOcZi6ad2NAdKWySoAcNUGQ/ST++Bd5g0r26P+5IDetG/hKMalDeaue+5bcfDn3xxZmaKS+OnvkAA9bIN0RPR7aG/pFgOaCIPvPfNtePwX30hrYkHcLZB6IBWmzwBqGwvuUGsemc52qG6wMAjMp+AWP3nORjzucxtR1hKp0igqFYEOPUHPcClikmotkCh67wKIQeEAoiGokgbWNsxbEJITM0avWZYYcOvi+75xOycARTmIDXuVKY25QY5OVqHbKWMuZ3gNNy/0sGqSzJVDSw8AlBeWT3dHcI5hYZRhpjtCrioMqhRzAzowTXi/qeue+1YAwO9+609gHcNti1OehSJQFoTrShhMZgVqK9BLS0jPeCth0K9SZJKm+JaB1M6t0K1/IPd/uNXf/M3f7OolbLd2GEwdc8wxO+3BN27ceK/A5Xvf+x4AbHdqMLBhd1cveMEL4u8HHHAAnvCEJ2DDhg34whe+cLcuqWeeeSb+9E//NP69sLCAPfbY4x7X+GDUfQFSADClRrhtNIWVaR97r9qM/67WwVl/pi5qrEoG+MVoGsZ/mfZkhdJKDIseMkkah8BCpVzHtl8mLAqjoK1AZQWk/wIFSBtlHG9EpJwORkv1JxNpgalsBMksJtMCgyLBoEzQS0psmp/A6sl+PEN3jkEkZCxpNRkMUoI9gYiQLea7RgAa0XFRKfTyEmUtkXUq79tDPke8CI6ZjAw7W0JjaAZmONhUS5RbCTDDkMwx2IRuFyb0rEGMe9E9S+L0Xk0HT+4A7bDnv74DyqaAY0huS2AloHcrgUVJwu+xqTua+mO6EWvDG3W6ELhr6ajKOGu6ap7ap3Yjg6tInM64BVpeW8F7yhpikISyMQolsFBhP4adGqYiY/zJ9ioMAbTaVrE16Bms4FkUvKaeeMkb4JwkLRAzkMLi4M+/GVLQxF2ekh7PGN6YOsKhqmUERUwaHHbxmyhSiTd6ImsZikoiS0jHF8BX8DRqT4gGM9ilnkcBhDz2M38FKZqJU8b8NKpx8fbWEqgP/y8rYo7yNGTdEQMFDnCvJ7z2WX8V7Q2M14MJRkMIU52CwoVDe9lri7TlKLVEKokSlYJY3wEnED7dpay8dvsQAL5x/Lk4+vI/2+ZlI9G+idmboaU3N8iBLpBIDQegl5foFymksDjs4jdhZWeAyQRIPGDrJWWUAwzrJA6vGEuvi3UMW0cdzOTD+P/aCnSXHc53fv0GtvlOPvnkXb2E7dZ9AlPXXnstDjjgAHDOce21197jbYM7+n2pU045BS984Qvv8TZ77rknrr32Wtx5553b/O+uu+7C2rVr7/PjrV+/Hhs2bMDPfvazu71NmqZ3y1r9KtaKZIBpNcSd5SQ6soaQBtVQAbmBtgK5qPDo3mYYx/Da/3oR3nvohXjtf70IKrcYGYW+TqPQm0SqPArKtRUovNYh6Kisb8OEVHnjeDzj5nDoqWoMVIXfBzUw0x2hm5SUBSgMEqHxiJk53Lx5hfcRAsCYH2F3Xp+F6D6ta5qMEnEqqjnYD4oEiTTksKy5jzDxIb3BagCIP+W8gJ6mfqJbVHAzpO9hgrRL2CrGvmhY2AZHNNJ0PR1BjzMcMDwKskXduu+c13DxZlvMR7+4noErSIhPbFNrmeH5OQ+Y/AEa3JHdgWPkBRVwmLebALxezIC2K+ggamPsD2IbcOxcxAvKg8CchgcQtW08CN1bgvSQOxf1QV77BND1ASCUXusUxNKBnQmPz+GgHQnFEx+bA89i5WkJwWx06m5Yq5ZthaO8Oe6fU2izBcYr5NU53zYl8XcAUmTTAAD7/8fG2P4TwmJU8hgUnnhWyTkeHzM8vwDKAvCxYMgEAT7BLB7/xTeCw+F7Tz8Lh3zhzaT3co0FAgBc/TT6n3N0fyksBLPIkxqV92natDiBiYxkCOFzCTS6rG8cfy7+z5f+HIqTxky7Zh9Zx8AceUgZyzHdHWFxlIJzi3mvkRLcYlgkmMgJMAlGAyl3DnsAgPW9BWwtcmjHYZwHm/77YuuoQ7eXBmt7izGiKqQsXHrM32C5dm6xRkVwv++/XDun7hOYOuSQQ2Kr7ZBDDgFjDM5t+yrsqGZq1apVWLVq1b3e7klPehLm5+fx3e9+F0984hMBAN/5zncwPz+Po4466j4/3pYtW3DrrbdGw69fhxoZOlCvSAbo65SEr5pDdjQSodE3KRQzqJ1A6kU/7z30E3jND16M0tLLL7mJU3jB0K/2jJR19IU8rBQySa2U0B5JhIG2Ln7hSj/yzr2uRDKLC5/0D/jdb/0J1nb68Qs5EQaJMvEAoGs6qAZ3apHaRkDLAM0cASQ/oq59/leiNMpKRcxT+UBbIQn0ceHgVpdwd6WAA0zidUmekUm2EGCq9yzIbNKRkze4gygBm5LOKmTdMUeAyHQsbGbBNAnHnfUxKdICZZO7ZwXGol4Co8SC5kwzuIKPa6VCtYGcZ5pc4shyoeV9FeZxmRd7B81Texs0OSniJCATgK24N9NsWoS8vdbANrXaYrE1yJocu+D1BSCCYMCN+VMFzZCxjMBUAOc+rJe23XpPlyoCIGu96NzH4xjLIZhD5bPftJ8SDa1gY0grlSV6rIVHa2kO7uQCDr9N+v9+n/3LKM4OjBP3gC5oocLUnJIGtX+/cW+NwLmD5IgsU3ieAfyBWzzxkjcgkwTsGKOBj+AzddjFb4rB4ZnUGJQJZGJR1MqDQY5uWrX0Uw6ZrGOb/YqnvHvsdeIgbVZoxQVWLIDA7550Ng686K3R8yrc1zmGblL69nyOygqMavr83zXqAgCmkgKVFZgddZDLGtpyTKZFHEbpV2ls/1nHlqNiluvXvu6TNcJNN92E1atXx99vvPFG3HTTTdtcbrzxxgdlkfvttx9OOukkvOIVr8BVV12Fq666Cq94xSvwzGc+c0x8vu++++Kzn6X2WL/fx+te9zp8+9vfxs9//nN89atfxbOe9SysWrUKz33ucx+Ude6KSrnGbNXFbNXFUCtsWDkLNhKYmhzil4NJ3NRfSXoqrqG9aeaf/OD3UTses/mopeA1H8w0Ginmz279F3CbbQoWCh1ZEzgSFEkjGQnYKe/P4CXf+SNMqhEyUZMbe0J6itXdPqbTAh1ZQ6UazlKLKU19Vpg/UHJuY/ZYkmjvgk3xE4nwrtKC4jxi1pdvvzjrdTg1A69JY0QeTqALB+opCzeXEDNWexfy1GCwB0W12ISy97hmEfQ4BprAawnBx9pmIVLGtsgl4WKoMQCYnqYcPkvtO7XAoRY4krkW28Ib4AUA0B4cSDLwDDE3sIjO41bzyKDxxERHc8owJGNOG54n/Ci/Y55RoutC249zF323xkX/aAKphYtskPBDD0I2TuNjGXIsiLxNDOm9+mlnwViO0gOTqpbI0xrdlNy/00ST0NqbS8Y4FM9sAcDKiQFy79WkpImtwrDWpaagQVsU2sTOMTz2M38FxhwSaaJ7OTmJj098cu/6LYVFJ6vQyaqotQosVa5qKL9GE9rfnhVzDhFINfvT4QdPf3t8HwHAyE/xOdewu+F37kFUKmhKjjOHykg89crT8NQrT8NMOorP965+L37GE6mjXnHd1AIOu/hNUNLgh898WwS2Ulis7A6iH1XQQnaTCtPpiExE/QRfeP1KI3HFU96N0kgEv6lCkz1KAHRPvfI0LNeDUG4nXJZrp9R9AlMbNmyI2qQNGzbc4+XBqo997GM48MADceKJJ+LEE0/EQQcdhAsuuGDsNtdffz3m5+cBAEII/OhHP8JznvMcPOYxj8HJJ5+MxzzmMfj2t7+NiYmJB22dD3WlXGNttohpNcR0MsJNm1cCHYPZW6aRCIM1WR99k0Awh9pxvPL71G+2jmNCFphUBYY6iVN72onYHiA9FTkmC24hGR0gMqFj2w8gL6oAnhJOv3ekb0WAofIMmLYCme9/TSeUHj+djPCoVVuQ5nV0Im8MA7cNTSXAQmfYi6OMtFT+QA4ggihdSjAOmAUFJ4hhEiVIk1QTAOE1KKZlkgxNRe7H9YYyml6qOQ5eMjBN29A9CzngkH0PZjxrxJiDG9LzLNeYRpfVau2FbTIDsIKmCmOIMej2IZYGLDBhLe2SZWClZ05Cey/837Wy88IEoWuE4EEsHrYtUhN1TmBkRhlE5NVINc+LN2ApBFEHl+6o1Wld1642CAuvIWNAVVOmnDYcj/vcRv/a0p0TpVFrgX6RjG0rkxqJ1C2GxQuqffYbtQHJZiBR2jNIQSdEzEuaaKRJ0yJuO6O3rQ2CcDxo9hKl47aksJFdCxmTjDkc/Pk3o9YCxjF8+8R3+M9YY7VALu6+Fago85IzF+NVHv/FN47tq0QYfPOEv442DyJ6Z7k4nceYQyKa/wfQZB1DJslIc3Wv38S/+FZpv0wxqFIkwmD3iXk842un4gdPfzsUt1jVGWBU077fOupgWFOoceo/86vyQfzcA8BxV/wpRpXCU688Db2kxDeOPzeedCXSR8t4p/XlepBqGUj9StR9avNddNFF93mDz372s+/3Yu6pVqxYgY9+9KP3eJt26zHPc1x66aUPylp+leptB34Wr//h87GgO+jXKR1QfRba9besQ7KnwZ7dWXBYKGZh/Jct98BoWo2QCo3SyGZE3GscOrKKX9ChVTGpSiRCY6iT2OoDSJQumUXlAZNiFkqQ2L0rS1RWIhM1urKEdgJbqw42j7pYkQ6we2ceP9+yAvusvgvacWwddVBoOuPOkxqLoxS9rMTCKCMPKQfUhYTwbFXttVQOiFYHzjLogQQvuZ/G86wUI5aJFwxWAkhN86USfhqG7C4OXgFOUkhxEKKrRU7tO9+WjL5NDKRj8lYFo0fWYIaB92m/Oe6ieN0qatfxgsNKAlT1pIVa5JG5IqG8o+0tASqs5kDIMwuAyjJAwPtZsSaE2BKg0hWtg4uW7xRY1JYBBHR0OZ5XF8XpLcDXCJ5bu80DXda+X+tnmIazrccCCCCblvYpgBO6LUem6qhVKmsZ34e50ii0RCbpJ0DRKYtFGltVpO0zYIxBcRejbIIlAYD4dwQ8PLTvSM/0g6e/HYd84c1RE8VBn4XQPgzmmuHxqlrikC+8GZyJyHxZb7lQW+FNNyWUMBFgWsegWANsw/458tIzAYi4zuh/5vflqE5IgyjryNpxOBRGYq7IsaozIFd4ppFOaGweUIvuEZPzmC06ZPZbdPDNE/4a/+dLfw7G6HO/vrdA7UfHsK67iMqz1puGPUxnI//YCl1FaQuC0z7JvF4sFRq9pERtBFIvDZhOtzUBXa7leiD1v//7v7jhhhtw9NFHI8/zex1Ie7DrPoGp3/md3xn7e6lmqv0EHgyfqeW6+3rvfx+PkVmLoReSP2LlVtx8x0oYwcE0R0fWUZPBmcXIkLheMgMBBwOGnBNbVFsByQxyblE7Ds4kCqPIO8qfmWai9uxUTf/zjFSYBsxFFXUn3Jv7VVbSdpVfi/OThvmApgXBcNC622Edw12jLmWCMYdeVmJUKeRp7RkBnzEHh5tefCb2+tg5KC3FyCSZJiAlLIzmsJUAqznpjCpG7TqDJjOPBv6oAjByDFYzYLKGm01hckTmyPs6wia+dcQB1pdwE41BJODZMx8gzIeComC4o4lB/3i2EmAlj1YJLnGAZqimLFzmNUSWUXgxqEXILIMYMZiO85l8rGGDmAMEaCoyCOUdvAO5g678gd1w0rkbDpHqJu7Ff3xNKSAy3cSroCXyb4M5NNoamtrzrFv4vwcEbXG1c8BPf2ejj5Chv7NER80TQC007hgm8yJOsSlBzBMH8L2nUeTIQf/5FgAUWwJQWy1ogQKTwxjp5ozjEfAzZrwQPqyNmKVuXkYLhACMGAN+8PS347CL3wSAeZaK2N24H5iLzyH83zpGFhIMyJI6WiAED6tQTWZdkyBgQScngV0KZqZjDutwsMwPgAiMRbOUWiJJyLBzVWcQW4IdWaPQBHpWd/vxpGlFNsTWMsfzv/UqrOvSZ286HcXp3t16C3QiZQUWywwr8wEqD0hX5kNoy5HAIMmHKLREoSWe8bVTMax76KBC6nP3EmHw6aPej+Xa+fWbKEDfsmULXvCCF+ArX/kKGGP42c9+hkc96lH4oz/6I0xPT+Pd7373LlnXfeJerbXxctlll+GQQw7BF7/4RczNzWF+fh4XX3wxDjvsMFxyySUP9nqXa0nN6w5yUaEjS0wmpEE6eMNt2Hef2wDucPWtj8BApxgZou4TrpHz2n/RWgg4SE5TcGSNQH8TMKrRkRV6ssR0MsKkZ7FS38rLRI1M1NERObqp+/sD3pvKb9d4M9DSSGgroC3HXJVjqBMSs5Y5BlUSD2iDMsFuU/OotcDCKIPWAkIZMO7wqE+cDWcYTEkmksbwaP4JoAFKmhGgkS620EIkDDNo9EKWRdsAACjXaWJ2eHMfUVJrMJh3uq5pQEZonQXswR3sTE3GnFM1MOvbVnMJZLcGMguXUcwNqxnF26S+FVYIEpl7PVXI3jMdfzA2jIBiFK7Tz2CsKRMTJyBjvIltpvG4JI8IJkJ7jxgtcLKlCN5ewHirLkSttI0wY2xK6zay9bjkPE6/H3jRW+P+tZZjUCTUVvNtO8EdsoSAfSpJO1d781frW2GHf/ENzcScCy7ojcdTruo4CJH6Vtd4XIx/W/j3S9Tm+eekTePUfvgX3+BbaSYCMmtJP1TVEp2kjhOFgvusQOZiXEyz3ebzqi3Hd086O3o/9cuEhj+0jOzWYuFPeEQziNGeuCXzTYnaCrIiAJmc5qrGHf0JJLzRL3I4FFpCctIpbh52sXnQhXMMm72YnBiqHHv05gAAlRXEEJc5tpY5+lWKlfkAADCsE3RkjTuHPbJMYRYLZRZDzLXjmEiLqJvkcPji0e/Fcj1I9RuomTr99NMhpcQtt9yCTqcTr3/BC16wSzHIDvtMnXbaafiHf/gH/NZv/Va87qlPfSo6nQ5e+cpX4rrrrtupC1yue6+eKFErgVJQOLF2HAk3OPjRt2K+zMCZRSo0hkZBgECUcQKKk1LaOAbhwVXKNQRzEMwBlsCXYI6E6cxBgM7Oc699SrmG8booxSwMWLyNDTosKyLQCnqszUUH1jFs7vfwyOmtsGC4q9/DdGeE6XyETf0epLC4sz+BPCHwt9Xk5AzADTlxZ5raVl4fFMxEdSWJaVIaGHn9U0FAw5NwsIlD9YgaruZgqYGQJk4VAg66FBFIAaRlGtOCTxoyR7UNeDPzCZlrOoApNLl43IGtIg1Z+MlTDSs5eUXVTSuPlV6LpRwBKu7AKw6b+LZgZscAnPdQQOhDcmFp7ZahLiiyR6WadFChkxSicYIovBKwWsTTVB5E60vbff6RgqfY0nifYMgJkNXAgRe9NercBG9MWOPt/bacI4an9G7mSBBdz4OIOzAzqdJRhxTYIOY1PUoYlEaiNqKxDHBuzHQzmpr6bXSSCkWtvK4KY+080vu46DklfejvqKYJ2mGl/NSfQpbWsJZ5fRWLk37WMYgWy5dKjSMvPTNO1iXCwDiOTlJjWBEL3PHv90JLKJ8oEHSLIccPoHZaYKbC7RkDeqpCv04wW9CBZl13Ebf3J8ltfcnRcyopMNT++WgKJl6oUnRkjbWdPu4adUno7k+CJtOCWGihsVil2L27gKS7iC2jDnreRypoKysrxoKVl2u5dkZddtlluPTSS/GIRzxi7Pp99tkHN9988y5a1f0IOr7hhhswNTW1zfVTU1P4+c9/vjPWtFw7UIprqACA4JCLig4E/otcCYOhTjFX55SNJSoobj27ZJCyGos6I8bKAyTjGDjoC1ExyuhTHmgBBKAC+5T6cFPJDAzoMUMrJFgvdGUZNSGS0RnzmryPNfkAayYWMVfmKLTE+skFrMyGmExK7L/qTjxycg69tIRxLOpiAEQQkWc1ch+fEaaIjOYwNYfIdSPE1iQgB4hhkgMCUyIzSKZKimBpTVhFA0pBeikrAZOS1YHjGPeyZCS+diMJpyxYTe1VOGqnwYGiWbyY21mKXAlrDj5R0SU9tTSJ1xfgNQP3Ngi84uR/xVuPK/3zcywCLFOJsVYfQIJyoSxUqmktLTE4QIwaAIjEoDdB2hayiWjhtfZTRtP+Wxo4HJirgz//5rGpNe5baMHlXLRChxNFj99JqhgfI7xHVdAyKW7QTcY9zGJcCWsm/AJY+O5JZ0ejWmJ9/Pu6ZVSaJRR7FETdgUFzngFKvK5JGzopGJQJhkWCQZGMsV3dvIzbTHxIMT23Zl2Ck2dUeyo2eGAF1qvjWbnwvIXfl0Hr1fa14sxFDVSuiB0OYOaWxWnMlTnWdRcjs7W608f3nnY2VnUH0dJiOhuBM4fFKkVPVVio0hiIHIZKVucDrM5Je5XLupnyExpdVcVBlVRqFEZGg9+OrPGlJ5+Hz/3W32G5HrwKbb4HctmROuecc3D44YdjYmICa9aswe/8zu/g+uuvH7vNS1/6UjDGxi5HHnnk2G3KssRrXvMarFq1Ct1uF89+9rPxi1/84j6tYTAYjDFSoTZv3rxLPSJ3GEwdfvjhOO2003D77bfH6+644w6cccYZ0QNquR66OnP/i5ExjZ4o6OycWUwoOiBqR2fThZEwXuRqwVG3zPQMOFYlfczIYXRDD+2+AL4CaAogikCWz1Tz2005/V8xi5FJMDJJk8sFL0qVFQY6heQGmaihHceKdIReUuL2ualo7tdp6a6mkiIKghNJbTXBLbK8QqI0dMgAbJVQFqYUxBoZBmQWetqAGQJI9QTAVpYQKmhpGvNKq6lVqGZlRBL1tCEbA+7BlQLQNTFI2I0knCB2zAkH1qUDDhM0SReNNFvmoS4YSDpq8YXJOaYskJKPFW2EvvFsYsErBl6y1jeg/8kduDJeJ+WZK9cAquAFVZcy7hchbbMd5qByWnNRqrhP2nv17mSdQV9EdgKNZ5O1PHqJhQk446fjaHKOWmNSUIs4vAaJoPH84M8UdD+hjOXoJeUYSAnv5ZFWqC1N1D3+i2+kCVY/9VZbEa0JQoUWXWhbhvcr88xs+H9gf1Kl0ctKMFCOHd0XKCpF709hxtg6xU1kxALTBcC7ltP7OUwohspa+q/wvBcL79nk3cUls1goMszkjRjcOobCBw2v6fTBmMOWokNZer6d99xvvhpzRY6VnQHWdPpYrFLMVxlW5sPYMg0C/81FB5tGXWpF6gSTSYmOrDFXZhhqhZ6qsCIdoifLuKZg2MuZWwZRD1U9xG2+K6+8Eq9+9atx1VVX4Utf+hK01jjxxBMxGAzGbnfSSSfh9ttvj5eLL7547P+nnXYaPvvZz+KTn/wkvvGNb6Df7+OZz3zmfdJcH3300fjXf/3X+DdjDNZavPOd78Sxxx67Y09oJ9YOt/k+/OEP43nPex42bNiARz7ykQCAW265BY95zGPwH//xHzt7fct1H6p2jUcUBHBnMTHmfEyUu4QRNerg1cOcb+lZFFaRuSe34NAYGUXAiFvwOMaFsS99+qK30Z/KOg7uAZbiJpqJhjNdgAxGc1HHFmAmamgrMNIKqyb7GGmFSS+gzQT529y4sAK7T83j5tkZdNMqTk9RdIVFzS0m8wpbFrvk/O6IaRGpgamEF2vTms3qGsYB2c8TGNZMBJpaeAsBCy79SL0GyrU1eGrA70rhGJl+glGLjzpr3iG8o2O3zRYSbqDAJysyyywkmDBxDVYLMG5hS9pvTBHYYhW1/JhzNHWYWtiOAVugjyjTpJ9yadPmc5qDJwauFjA1jxYF3Jt0hjgZMAAGERwGTynmWTWjOepSQOV6rLVnPIMmZPMe8E8zWgkE80rBqQUXp+S8bsgFlsUH88bQ7MgCkbD8iZe8AYJbDMoEqSQrAuEBfa0lklQD/oDfr9IxawPGKEC3NsJrqEi4HcTmja7Jorb0vuymFQrPWAWGi1puBKhC6ztEpJRaeosIhom8wLBKkCraX5O9Av0y9fowatOFlpsUJrqC154Fy1UdW4VtTVSmyOm8bdkwKBN0kprML70OSXCLlZ0Btgy7WNtbRGUEhlpFJo0zh7WdPmYLytlbmQ2xpejgG8efi2d87VRYMPTrhE5wVIW5MsNkUiIRBM5WZCPMlRlWpPR34kHcfJlhJhsh4Qb9OsFkUsQEBc4cASpJbNWLv/MKfOyID2K5fr1qqSbp/PPPx5o1a3D11Vfj6KOPjtenaYp169Ztdxvz8/P48Ic/jAsuuADHH388AOCjH/0o9thjD3z5y1/GU5/61Htcwzvf+U48+clPxve//31UVYXXv/71+MlPfoLZ2Vl885vffIDP8P7XDoOpffbZBz/84Q/x5S9/Gf/93/8N5xz2339/HH/88bt0LPE3ubgXeipmUFoJyQ20N86T3GJ1px/F5oDXWHkAxuEgYCNw4sxBcWKXut4rSjsBDmK1hNewLK3akVFiEJhzeADHNT2Wa25HwIsmtwojsTbvx+0kgvIBBXPoyAr7rrwL18+uxoreELP9DibyEqUWWN2js++FUdrEisT2lgcRYQzfMkBZCH9ALjZUFFosCHRw6eKoe4iv0XuNqF3HAKwtgF9mAHyLL0TUeM8rEnCT5kl0apgRfaxMISk4mQHaXwcHQDahuRgKIoi6hnRdCWnVxKIkd/UQHwPAeRfwMWKKwftVeUaoFrFtFwAfHOUUMrgoQneWk6bLgcBcAGJ+4zq2IpvXmAFRZB32eQA1QSMUdFNhO4kHARw+r84iAqpcUZvt2K+cAcEJXHSSGiMf35LLOorLA7NkLEMibYT4QXtk/O9kW8BaU3StOBWMA7BgShu0SOF9HWJSOHO46qnnAIC3O6D7DspkbDKvX6ZxorDSAok08e9cEfM0qJLIVHFhMJVR0HBpJDqyxrBO8LXj3onDLn4T2Ql4QNhNKyhhUNSKfraY2NXdPkrf/lbCIBMaCyBgtrXIsTIfAgC2eO3Uc7/5agx1Fk13O7JGv04iC1gYicmkRGUEeqqKlgicOQy1iu3EwIBpK2LgsbYchZFYkQ7R1+kykHqI6v606pbeH6AM2nbd11i14Ou4YsWKseu/+tWvYs2aNZiensYxxxyDs846C2vWrAEAXH311ajrGieeeGK8/W677YYDDjgA3/rWt+4VTO2///649tpr8YEPfABCCAwGAzzvec/Dq1/96l2absLc9nJh7qa01siyDNdccw0OOOCAB3NdvzK1sLCAqakpzM/PY3Jyclcv527rXdc9FdZxzOou5uoc83UzJbehO4tJ2fi89EQZD3ABVAHEcJHmSUTR+cgoL1QPLT0TbwcQIxWsFxQzvsWnIHlD16qW+DxMDc7XOfp1GhmBYOZpHcdQK9zRn8ABq26HtgK39qejXw0A3LEwCcEtpjsjCGYxqFLctXkC2JrATWpy/gYBi3jUFY1xZfsdn3cq1LWArkUDTsJPEEgyW1PwEYcoGBl9SmKtmHIekLDox9T8bDQxY4/pADtQQGaAIems5KyM0qf4cjDQBKJqWnFQIVePxauQGQJ2PiOQpwa25hE02ZZuy2pOQCvcn1uYWkBlOj5nxoipEtKO6ZOAcePIwEoFUBWCfEM7K7R3YyyMa7e4PGDzhqucOXSSCmUtW3lvTfsusEXt7QFA7aNlQjkHFIHxaenCrG3W2r4/AEhOAxhLxfSJIDuDMKUWhOsxoNghxtkwBnRUFQ0ujSXNVTDkDMwcgBjLknntUaEVRrWKNhCVlpgfZpjqFHE/dVTls/xocnHKez31qzQ6lC+UGdZ0+ySq99cl3ODOETmgr/bTeJw59L0p56QqsVCnmFT0fTDUKmqlCu+sHoBWYL4iAGMWmaTbah96bsGWLRDw0BwzwmMc9LKzIZLsfm/HVAWuPf8N21z/1re+FRs3brzH+zrn8JznPAdbt27F17/+9Xj9hRdeiF6vhw0bNuCmm27Cm9/8ZmitcfXVVyNNU3z84x/Hy172MpRlOba9E088EXvttRf+8R//8X4/n11ZO8RMSSmxYcOGZS+pX8HqmyzqmFKuMSFLOnO0AneVE5hWIwg0o9Ypr1H6lkdwZgYI8ATApBjFtZROxbP2AKTaIEpb4c/waSKwK0tYxyFb7T7u/QgSoSHgMJMMSftRZ5grM6zr1NhcdGObr1+ksYW4e28e/TrFrYNprO4Si7X71DxFVjiKIlm7egGzeYfCeS1NxCWdCuVcBhaMOZmL4bzOAVleRYdsxh3qQnpLAR9F40Xh6BigYnCCoVxfARzEIinbACh/U7uYgE9WETxReLPfuQ6wpSSWbFNCeqa2S2c4yIvmYE89NTIbpYMra0TnQDNiKG0TRMwAximomDEXnwf3YJLxRhDPg88D85ou3rT1rGNIWoAJQPRM4tz5AGATHevD+wdo7BACiApgIvhGacu9XooO1mVNbTEGAlJNvlwDfoxlLfZovB0XgGumapTeUym0n1yr1Re0dwHw0PvfQTvybjKeYa0gok6ptiIyZiF8OwjSU6lhHItAqjICuaobSwc0wtSylshV7T8PDcBMPbjaOupgMisw3R1hbpBjqlMgkzTZN1elWJEPsWhEfF6MOQzrBL2kxIp8iC3DLlZ3+tC+lR+0UuF1COsLkU99TWsOInLpncotIwF6Ycg7aqgVptMCc2UGDofphE7MhlqhgsB//vbfYrl2Ud0P3dM29wdw6623jgG/+8JKnXLKKbj22mvxjW98Y+z6F7zgBfH3Aw44AE94whOwYcMGfOELX8Dznve8u1/KfTTdPP/889Hr9fD85z9/7PpPfepTGA6HOPnkk+91Gw9G7bAA/U1vehPOPPNMzM7OPhjrWa77WRsP+BxSXiPjNUorMTKKJpJ8xIuA9QJx43VMHCmvI5BSzKAjSnRE5T2jHEY2gQG1P8J0oLYiisPDdF9gnPpmPAJEMYNJWdCEISP/KgJqHNoKdGWJniLwlHCDyaREoSUSbvColVtwx2gishwJp4P61lEHj5iei0LZfplGtkQGN3afqeYcI0H3oLEw58Ki1xsh71QkAlaaxNPAWL4eGOl6QsuOj8iWgKcGXBrSSXEvOm/5U/GJCnZRxam1AKRsIQlICQuxpYlrGSuG5hPpGBmCdgyQGrDEB/05Flt6zjufM5+JB0eTgow7mLppJVrDyT/KhH3g2aVWIDJjTQ5fezk0mdaIyBNBbctMamRJDcaAHz37L2kzcUrNAx7LotP3t098B7Xf/OsWHqfyNgYB4AZGqs0UBR+qUMYxD7jgxdr+afifUliUtSQfKdZM6QWBe9R1eTAW9GPGcQhmm2EEb/rZS0uMavKBKrXEsEpIkO79rkRoGW5HSE6hxTVyWWM699NzRUoWDlZ4M02Kj5nMCt8OtVjRG0IKgzmve1rT7WNulKPrTzYGnl3qJc3ZfWCsAGrtTaUFVmZDdFUFyS2GWkXwFPZrcExPPJMcgOtQk01DIgxWZcP4+ZTcxgD0EC314u+8An/0/ZdiuR6+NTk5OXa5NzD1mte8BhdddBGuuOKKbSwKltb69euxYcMG/OxnPwMArFu3DlVVYevWrWO327RpE9auXXuva33HO96BVatWbXP9mjVrcPbZZ9/r/R+s2mEw9b73vQ9f//rXsdtuu+Gxj30sDjvssLHLcu2a+sfrjyG2yPGoBQlU/4QsvaCcLh1exfspRgAnaKrC3xmvkfMKGa8JgHmtEwAYsAiIAO+mzhzmqg6s43G6jzOHniijP1VgtLRr+U45humUhKySWcwWnZgTGM6AQ+01M4vdJ+aRcIOeqpAIg1GpUPoD3YreEFJ6Lx7vhE4PQj/I94n7KTICZ8MiwXCYoirJkylJdQRbAJD0KqAvYBMHmxC4CuaKYxN5njmyhoN1KbhZDyW1Gu/IiBVznu1yALi3WfBWC1a5GCUDy2B6GtHd3HB4GqsZwLNeC8YcnOWwWjTThYY3IK8lNAc84GgDOQ/4Ani5/nnkLh6YD4BARbAoGHkvqBBkC5Aj+WEXv2lMj9S0gVsgqBXhEtpzglmo6FCOeP+2Majglib8PJMVhOnGUVSLbaHSEFKcJQSojWuZanI7dlt6fJoivPppZ0VABVCsTdBFLRZpnDyUwiJLahj/Hg37tM0WFVqi8vsnRL2UXmdU1CpO4eWyhmDkW3XpMX/j36oM/TKlyKYqwfqJBQzrBItVinW9RVx+7HsgmUVXVai8JhIgkfh8kceYGM4c5ssMHVnFbTdxTxoczkdGEVO2UKfR7FRbHn9PvCkoZxaTqkAmdExBmFQFPnXUB/CxIz4Yn99yPbQVNFMP5LIj5ZzDKaecgs985jP4yle+gr322ute77NlyxbceuutUc/0+Mc/HkopfOlLX4q3uf322/HjH/8YRx111L1u7+abb97u427YsAG33HLLDjybnVs7/AlYGi2zXL8aVTgFzmz0dgLgJ+LoS792Ahlqr4cySDn9D8zG9mA7BiZlFqVV/qDRgKggYufMoW+SyE4BwMqUdBkLOiPxuhURrnNmofztJrx+q7SS9BnxLLfGmk4fW4sc67sLuGVxBrP9Dg5YewcARENS6SfEJLNYO7kI7Xgzgs4tTC1R1cIzQc5HyHimyt9XGwFdSaxZsQCdlZhd6AKOYbo7grEMudLYUknUhQS6BlYAcoHDCQ671h/8uYOtyM3TGUaslbCwiwnYZAWxKIktWlE3E3u8cWIHEAFU6NwxA5gVNbXvHMhUVLkI2Jx/PkhbwcUIQKkRWBOtxOGsa3RgNQefqMmiwLc2w2sZat/P/NXY39tzO3eOwoqVNDH8mBzMMcbsMA/SRlriSZf9BZaeuwV/JQBeLyS8QWcDwtpriQJ3IPowQTZRLAAiY8nhAO8RFZipeL2vcL2xDId/8Q20XeanCG3jyh58mcJ9g+N48J+CfwkCs0YiebITGWlFHlmyhrYcU9kItRHolyk4HLqeWfqtL78+snLdhJikmZwYoel0hEGdYL7K8H++9OewroPpbBSZqACeEqkxk46wpehgZTZEv05QGIWTv/tyFJpafpOqRMI15qo8skySWVRORLA1mRTNAAHXKIzChB9GCckJ2gpIbnDyd18OALjgiA9juXZB7aQ2332tV7/61fj4xz+Oz33uc5iYmMAdd9B389TUFPI8R7/fx8aNG/G7v/u7WL9+PX7+85/jDW94A1atWoXnPve58bYvf/nLccYZZ2DlypVYsWIFXve61+HAAw+M0333VGvWrMG1116LPffcc+z6H/7wh1i5cuWOPaGdWDsMpt761rc+GOtYrgdY1nHUTnhxOcdAewM+Rh47tROY1V1MySEMWDysKWbwuv0uxbuuowmKoG0CSFcFIIYVj4zyAlsZWSY6k6VMP+t4bC9WViLnNYyfANRxMsj6ViNH5bf7y+EkMqHRERV6qsTt/Ulw5rBbdwGVFvjpXWux/+o7x55v0IWEiTDLWWQVAK9N0gyQlgCIP+jnWYVc1dRWyYvok0QO2Ay15chVjX6Z0sEx19CloINrziLjIzaT5imSSWvLBnhwB7c5jRonrgyMkUBOYvEoefIgJ+AFu6qKIIox0G0VfVs6L3RmygI86KvoJ+Otth1DFMXDs2BMWLiRBO/WMKUATwwsa7X7/FLaI/lAkJk1AIr7fQQAaaJjxt5SmUNotzEWROLEFrYn4IIuShsRZwSkaEwtE6njJF8wqxw3aGiAVvCjCutX3JIFCFx0GF8azhyKWDAWnwd3xOqGXMGou/It4KD5CuA9TBhK4VkvS9spahXZH+M45oocgpNzeKEVOglZCEypAtpx9FSFoVboyBqLjjRLAIULc+awIqPJPOsY5so8ss5bRl1qC/r/z1cZ1nfoBGNVNgRndPKQSe33k8XQkK1BYRTFznCDzUUXQ62wJl9EZWV0VQfopKy0MrbsaycgRIWRVTj/8GUQ9ZtUH/jABwAAT37yk8euP//88/HSl74UQgj86Ec/wr/+679ibm4O69evx7HHHosLL7wQExMT8fbnnXcepJT4f//v/2E0GuG4447DRz7yEQghcG/1whe+EKeeeiomJiaiHcOVV16J1772tXjhC1+4857sDtb95mavvvpqXHfddWCMYf/998ehhx66M9e1XDtYp+93Gc677kT6sndkvNluaczVOabVaOw+gZEKFVpv7f/XTqAjqOWlHdkeROEs16isRMI1tBUYmARdUWFRb9tv58yidgI51+iJElNyiEnRwVbdwa1bZrBycoDpdAQOh7XdRQpQlhV2m1jAlqIzNiHWbNOBOxdbFXcNe8gSDWs5bK5hNR0AbU/H1lFZS6zoDAH/mS18lIaUBlrTlVsWuzABvLAwBahhawY+EsCCghMA04BZWYNFuwEGt0Dbc1M1MK/gJjQ4PAgCgnQrtvBYmHKb0mTFIOhozLdI2BW1b1E2onnmACaJVQo5hM4yODQZg/BCbudIdG41B+/W1IJseUYFwflS01MgiOo9O+QZnGCQKoTFNc94GwDg4M+/2bvHN2AlCJ0ZnDfB9I/nGKQ3tgyC9OA+HowqAbTafoE54pC+Ndi2OqBtenPMFpAOOqxQAja+fyLjIjWqmIdHbBNFz/hWKnNIZeN+HqwTjL9PsD6oQxh1nJBsHqP0E3GKG2SyxsiL1CfSAvNFjkRqzFcZZlLSUk2nBfp1AiUMJLf47P/5ezzpsr8YM+Sk2zWf45l8CA4XtyO5xVzlfaP8d0Dl2eqOrDHUCXqKjDY7okJfp0i4RkfWXoBOBqV08pRAMOc1lxTZYxxDh1O8zYee8JFt3jfL9dAWc96b7gHcf0fq3ob/8zzHpZdeeq/bybIMf/u3f4u//dsdH154+9vfjptvvhnHHXccpKT3trUWf/AHf7BLNVM7DKY2bdqEF77whfjqV7+K6elpOOcwPz+PY489Fp/85CexevXqB2Ody3UfirPGlHBtuoA7y8lW609AO4GhIaATGCrrOM756dNx5v6X4pyfPj228drV4RWGNgEHnVnXOiG7A2bRNwnmaxLJcrg4vRfWYx156UzKEQxoamiVWoSARemZr0N3vw03L8xAW4GEa/RUic1Fl0avuUWlJSoj4tk6QO7u0bPI0d+MORSVhANN6mnDYQ2HUDaaV+ZpHTPcUqFji3D91AK2DLtjAmgWdDZ+O3AMVtLB1koHvroE89qpOI2XW/DUr3NlSaP5NScmCxjL+wtBxmZKe5BDKIvPKtiVFbX4OAhggYCXqzlYZgggKQJPzjJ6jhbg0reiDAUZgwEisbC6aUdtr9gSQGUdxckon3cIYAwIBRsEKcJUXWOMCXh/qRY4CplyvCXU4P4AHfQ24b7fPOGv8fgvvjGyV2qJs3i4rbE8gqSg8TGWbdO+DEAp3M96IXyIIGozUrBNPl/wrGpvKxEGo1qRcNwDJQvSzlFcDL2MwQ8r7NetI9Iy1ZYj79TIVE3CcGabHEE4TKoSd4264AndbzItsFDS6HuYsJstO1jlrQ6icLwmMfhdoy5W5wMkojnR4cyi0gqJIh1jsDEoPNNcGIWV6QADnUA7jq6soP0JWUg/CK9R8KjjwuI1P3gxDBjef9hHt/+mWq4Hvx7iNt+vQiVJggsvvBBve9vb8MMf/hB5nuPAAw/Ehg0bdum6dliA/prXvAYLCwvRcXTr1q348Y9/jIWFBZx66qkPxhqXawcq5TU6gvQNk6oYE/uWRmJkEwjPEgHA6/f/Is7cv7H6r51AYRWGNonWCQZ+qkmUSFmNXNTgPtS4JypMyAJTahS1G11ZkRu7314qNBZ0joFOyXUdFhmvkfIaKddYky5iw+TW6H+jfb4XTfFpbJjcikxoH5rMx8a7rWNjLuvakGlizEPzbt+cO0x1RsgVefB0ffRFCG3tyJpMCYUhLZBneZxjqEcSMAyu7QTOqa3mjI+sCa0tZRqBumNjX1YRD7Q0PGDwvlj+oL1Vwa4gJpCnhoBUoLJ83IwzjIBUEJj7zD8W9PZ+upAL17idB+F7WEsLJDj/91LA4kCTelKY2OpqnMtZDAIGaLxf+qiY0HJTwpBzt2ekAlgSjCJkAAJxqdBjsTBPvvx1Y1N32xOzO8fGhOvhMWnqsFlDeI4kQG/yA9vbCP/PpEYiTXR3D9l4NgIlYqimsxFNM6qazEVVyNRz0QU9VePAP5MaqdRY1RlgvshJT1Wr6OfEmUMiND511Aewe28es0WO53zjFBq2aE3R9asUK7IhtcW95xOAGEq8Mh9ioU6xyftLFUZB+8Dhykr0ZOnb6xWkn/TtyAoDb5MQ9s0KNcC0GiIVlOGZiwopayaFSyvBmV0GUsu1y+oxj3kMnv/85+OZz3zmLgdSwP1gpi655BJ8+ctfxn777Rev23///fH3f//3Y46my/XQF03dsTiVZ1kNwxlGRvnxbQvJjHc9d9uwUGfufzFe98MXIPfTftQWoSm/ANBqJ9DhFfomRUfU5PtjCXCRHmp8YqodIQOQ/mredGBQQMCiwysMkGLTqItEGBQtw8+VaR+LOosTSFFc7L/wCy39QYKur4zAVGcUXaEFB/K0xGBEbFxYV/TU8ecSIbB1bpBj9WQ/OmfLpEbtW39wjEKMLeASBzlTwART0MBKOUSncQCRgeKzyTgjBUTNk53UYSaM1jZTNZN3mhPw8m2nYAgKBthSxNZhvP0SURH93TpfagnDw/2CXsqN3yT+fvDn3+xBlI2gZSnoMo4DhsBEEIkL1uTdiRbz0n79gv4oMDvhf6WRyGSNmouomwJzyGSNysionQqRQkGrFkBQs3+bn7URkc1qVxOa7CLAi07pQeTupwDJFoJA+kKZxWijBBTSbLyJaGDhrJ/0DGvqJSW0/19pZLQl6YgKhVHo1ylO/u7LMVv2MJ0WkMzirlGXpih1w/jS50TG9Sfc4PbhBDjIkNM6hlXZIBrgZj5VoOOHRaT3zgpGuQAg/ZuCImtMNO41jqEnanC4ONzSEyVKp/Cugy/Ecu3aahG99/v+D8f6xS9+gYsuugi33HILqqoa+9973vOeXbKmHWamrLVQSm1zvVIK1i6ViC7XQ1kZIxuDlNdQPsZloFMMdYqc196iIKTOW5y+32XbbONdB1+IBU1thbcccFE05wz6KsUMFDfEToHG1CU3pKngGqWVXldFb62erKCtwJayh5FJMFt3samexLzJMat7EJ4Z2nNiFpOqREdSyHFHEnM0pUZYmy1irspiKwegs/0QcxFAlmAOiTToJI3ztLGN0orDRW1OcG0OmWdzRY40oZbGhJ+wSoRBL6uQhODimpEjOSc7ArI4aH+bjYOM6FnFHZxwPh6GTCTdygpuVQm0dE5jmwhic+YfI1gx+AtAk37O8OZv2xy4yQ4BACN26sYXvQFcWjARDC4bpqrN1nDuYmQM0EzQCa8FEr4tJXzkj/aCfSksrnrqOdFbqb3dAIiCv9Hlx74Hlx/7ntg6CuHC4T6p0JEFCv5hS9uQqdBLmKfx4OOwhvAz/D8wcJmsIwiTosVkekaUe2ZNeCsGANG1fLHMMJWNkCkdgVOlJbThcX+1W5yM0aSdbq1FMFpPzwN5zhymkxGsY9ijM4eeLCG5QVdVWJUNsTIbRm1VZQQWq0aXWHhgtjofjLF3QdBO7uYJKiupjScq5KI5APVEFbVViQdcKdceSJUo7Pj3vQFHymos169AuZ1weZjV5Zdfjsc+9rF4//vfj3e/+9244oorcP755+Of//mfcc011+yyde0wmHrKU56C1772tfjlL38Zr7vttttw+umn47jjjtupi1uuHatFm9FBDsQmhTFmAP7MtIIBj95Rd1fvPfQTeNuBnwUAvPFxn4/AqLQKyn/ZToiCPKRA03nBDT18SYfJv1CZbw0u1hl+uHU3bK27qJ3AosnAYbE66WNDdxbrs3msy+ZjLmBo461Ih2Pj8pnQEVxVRqI2Ah1VNd5IjqGTECDL0+aL3zlqdy5WKQp/v2iAmJZR4zWRlaitwKhSsIaBpxpuugYyg2SmGD+lW8o6AZHusXMJWtpouOmaLsGEkjX3ZX667qbfP7N1B7T6g+E6avnRLD+BKFs3DxIZLH9b5xgefeFZDbhDw0618/QSbzMgBVkepEndgJGWtsc5xJiVYG/AW2AotM7G1uPLguHYr5yBoy//M6S+dVtbYqDCtJt2ITqlmZhzjvyXQmnHvf+UiYwSgAjAAERWbHttwpEP+g1sFWM09Rreb2FbAWQpbrFYpRFwVUYiU9Qa1kZgIi2i63q4rzY8MmJtVq6rKnRkjZ6qYB1DvyYReOXtBmrHsanoQVtBU3h+X/frBKvyARbrFBPevNNY0iGu69AJx5q8j+mkiK3ywsioy6q84e7AJNEPTjCHBU3O5lNq5Fv4DgOdQjCHvtdY1o4mgi043nHQv2Noxw16l2u5Hqo688wzccYZZ+DHP/4xsizDpz/9adx666045phjtnFFfyhrh8HU3/3d32FxcRF77rknHv3oR2PvvffGXnvthcXFxfulzF+unVev3ffLFIcBsknQTmBkKJ/vjmIKQ5tgQhRjeXz3pYw37IzeVK0K5pxk/OnIsNMLxefqHEOj0DdJnCiS3GC3DoVq1k6gtBKzdTd6WVGEh9fWgL7UA9OVcIOfz81ET6pCN62OIEAPB/9uWsVpvDBtRqP6jai4NHSmvlBkjU+VP3iOatmIqRMNoSxkqpFOltv2wlqndyHwOBzQxYoKfFUJN12DrSqjjQH34uRwQSHi9vb62DnbvggMCA7osGhiZPxjcT/hJ5QhUNZizKzm8b7BmT0EOwP0M0zpjbXKELRIBIK+e9LZ9P5yfMwjCthWwG4sxzeOPzeCq28cfy6kD+R2jmJa2pOhxjbXNRN3JoIFgNqIIaalfbGg+37tuHdG9/5EElBirduFv0OFx4//Z007MhEauapQaQrzZYxsFhQ36KgKvaREUav4Him0ghQGiWzYql5aRkA2qAh8fOnJ57XyKHV87KH/jCzUOfp1hklFJxOSWcyXGea9CN06hqmkiMMYM9kotvwmkzJO/nFGQeHE9LJo05AJmtoLLTtirOkzG/RQ2o6b6pZWom9SAlSW443XPg/nHfLJbd+jy/WQV2jzPZDLw62uu+66GBkjpcRoNEKv18Nf/dVf4a//+q932bp2GEztscce+MEPfoAvfOELOO2003Dqqafi4osvxtVXX32vtvLL9eDX0DZnkkOj8O1b9/RfrhY9EYz37A4BqrcccBG1Dr1Teuq/gMPjUOuPXM+DqBUg7yttBTYXPX/mTV/ggXUa6BT/vbCWss2Mwk/m16G0Muav/WI07dc7/omXvkUiucWwTqANR1nLaHNg/bg7AAxGaWw9LY7SKBZW3ETQ18SRMH9fAh3acO/8TdYJSdI6QHt9UONzAAAkSr/pxZ5ZiuwPIBRpjoQy4P73MVaqo8dab0tjasI3HxO2uZ/XUjnH4nXOUtuP85YA27f2SKRux4AUHO2vWgvUWoy1xWK+ngduT7zkDR6wssjQtL2pjrz0zLj/ATKiDPv06Mv/DMM6IXDrBwa+dtw7CRjLGokkIKW9h1OlJb55An0xtrMBQ0WWEg0IevLlrwPQtPYCoxXc28N7SXCLxEfBhNadYDYCbcZIjN4vU6RKQ3nzTyUMsaBWoNTETAVWLLT6ApAylmPkbQ6Md90vtMKTL38dmWMagcJIyrvz7dLQBrSgk4PZMsemURcz2ci7kDssVimGWmG2zLFQpTHmJQxTWMcxnZB1QuPtRicfidDRZDdMIQL+hAgussq14xiYFEOjkHKNkVHxu8M6jqFN8Nr/etE2r8ly7YL6DWzzdbvdGJK822674YYbboj/27x5865a1o6DqVAnnHACXvOa1+DUU0+9T66ly/XQ1On7XRZ1Ux1R49DdbkNPVliVDGJrL2P6Htt826vX7vvlRtjumaqM15iSZBaY8wqCOXR4Fcepu173MZ2MohEgAFRWwoLjx3PrMKkokFnAYUN3FrmoMSOHmJEUhDytRujKEjPJgKwWLMftwwkknNp8YbTdgkEbaq0MygRFrTCqFJQ0SBUBlUSRiJ2iSCjiQ3HSWAEeVNgm4Hap0Do4egtuYS35OqHtuulrr4+OM0t2K7ESrOWtBM/4tFtvARS1418AxOm/EGRMgMr56z27ZALLROu0lgKfGbcx2Hj8ubgxUNUGG0DjLcWXMFWZ1Oiljd4mAM7AEroIRpu2X2hHdVSFyu/z2gocffmfUTacVi2bAhc1Rr/15ddHYB2MPAMIAsbdzIMwHAASoVHUinygWsafgSkLYnPBLQrvUO78UEJtBWorsFBm6CaVD2CmFmhRqwjCAxtmHLmaBwYqk3Vk+mh/1RDcopuUcX2zRYf2naUpv4UqxUKVRlA16/P4ptMi/j8A/9X5AJJbTKcF1nUWwZnFQpVituw0onQ/DBJOatr7K0zhARQDVdpG31haSZYn/rYCDiOTYFIW6Js0slnaCrz30E9guXZ9/SYyU0ceeSS++c1vAgCe8Yxn4IwzzsBZZ52FP/zDP8SRRx65y9Z1v8DUlVdeiWc961nYe++9sc8+++DZz342vv71r+/stS3X/ayEaUzwAj1RYE26CMnpS7MjysguZazGe/97x0Dw6ftdhtftd6m3NKi9rxV9wZIhJ4UkB6AWpgUDqOpritAIwuM9J2bRkWVzoEj66PCKROlcY122gK6kNQ90ioUqA+cWM960cKHMmnBj73QdWi9h0ir3E3mTOWlaOOhAHQ6yVTBW9GJjYzkWRhmKWqGoFIxpxNRBuB1G7GMwcjzDY2NMzY0vegPMXAKxooKZS2KLLWwvACouGxfz6KLugRbz9gYsWDE4smMIYCsAtKWTerSG8d8Zp/8LaePPcFfnWIxQAeBH9Q1dlI6i7EI3rbG2q3mbAYrTe6HN6K8PAvR2jhtNyXm2xFspNEHJNK2XKj2mO2KehQn7S/LgXk+vacinNLZp4QHElAGIoCkVGpNpEUXiwUl8wrfLtONIpIn/D2vXliOXjZ4sgO9uUqIysmnxerAmmMWgJRhPhcbAG3hK1mi6qhbwW6hS9OskOv03GZYEzDuiwmzZwVyVgzOHFekw3s46RlFSYOjKCpkgO5OuLJGLCsq3W63jkN4BPRdVZK0Ec6gdj8Hlc3WnyeHkBn972MeWmanl2mX1nve8B0cccQQAYOPGjTjhhBNw4YUXYsOGDfjwh3edI/8Og6mPfvSjOP7449HpdHDqqafilFNOQZ7nOO644/Dxj3/8wVjjcu1AnfvTp0Ex4wXiBSQ3mFIj1I5jaFIoZiBgd5iZatf4ZJ+GdQwTgvL2QpZfOCsOQvhc1JhOiMUibUhGNgqOY6AT/LKYwsgmGNoEhVWonUBXlvFA09cpFusU6yYWMZkUGOoUHVVFjUyIlgEQgZR1DKUWED7qQ3KL3E/6LdUGCW5R1jIK1ystYgvMWgYbJ9Ro+7wFqNrWCNiaRHbpUZ84G2KG6GgxU47FrzDm2Z/I4AB2a9pMg+nWR7OlwWLcgStDQMuDrWiNYBic9Xoob16pCwldSHBhPZOGuB1di3jdNuHCjCJZGAvRL4jam6Bjak/ISd8+bLdkA8gA6Ppc1tuIxcN0pfSRM3VgDi211RKp42Nox6P2SnAbBxCCAWeYCmxAXQNQGXOYagVnh7ZeaK8l3nV8qCkGRnAL6f2wwpozVUewN9IKuaoxlRTQLQF7eK6hBRqeX66IzUulhhI0pbdYpdha5hG0DrVC37dCp1Na66psAM4c1uR9LFRpBE2zZSdq0AIg68gKPdU8x9xbHwSgpJiNIeMBRAW2Ofw/2Kf0POiqfban8a3Z8w75JE6/5oXLzNSvSv2GtPne9773oSjovS2lxIEHHggA6HQ6eP/7349rr70Wn/nMZ3ap3xRz9+YPv6T2228/vPKVr8Tpp58+dv173vMefPCDH8R11123Uxe4q2thYQFTU1OYn5/H5OTkrl7OvdZ5152IFbIP47UN86aDRZNBO4GeKLBKLgIAMl7jjx5z/9jE919/LIUgewf1MDodp6Acx1zdgeQG2or4RcyZa4Tonm2qrIy+UptGPewzeRc6okZtOWbUEIVVGBmFubqDoXdo7sgKCxUJcgsjI9NRe8fq9b2FGPJcWYF+nWCkqe0T3JyDViaAl1GdYFAmyFSN2goMR8nY/wFEAMWYQ5ZozM11yGF9UwK7roSbS8iHarr2bBLQJBi7OJXHhY3CeNfyPYraLcOiJiqwXwFgcWWps8jJnLPRQ42364Sy0KWAyjT+5/++Gft86u1xys9ZBikN6lpAyKB9aoCe4JbG/h1lurUZmLYZZttHqpl6M9GZfKnJZtATKW7G2n+1Ff41UFBeiwVgTH8UpvICi5mrOmqMQgXPqsA6bvP6tdYeWJxU0MlAmKzTftBh6PV3oRUcNHqJ/32olQcwNSSnVlvYT9rxMZE9gNj+yxUNTgTQ2fa96qoq3n9N1of27fSFOkXPm2xSGDG16j5x5D/hWV9/DThz0aC3LeJPuY76xPD6Wcdjqy8X9VhmZnM7jlxUXpCexM+x5AS6lsXn91wPxTEjPMbj/99ZkCq739vRdYGr/+2Nv/LHNyklfvnLX2LNmjUQQuD222/HmjVrdvWyxmqHmakbb7wRz3rWs7a5/tnPfjZuuummnbKo5br/FTRTAAGmnigwIQpIZjAlGpfyB8JMZYzafKGNR55DNorUFTOYlCHR3sYv8ZRrCj92DIs6Qy5qFEZCW4GhTrAiJW1VOBjUVkCAvvQnZYFM1OjICv06jQej4CadyxpbFrtIpEYm6niZVAVWZQOs7yxiTaeP3LMLozpBoRUGVULgqVIQwka9EYDY4gMApcgZfbo7wmReYlQqchUfCbjdCnIbnymBFdU21gSA1w6JoF9q2KhQARDZmkcmqs2cBaYpACwAkIlpGLHW7YQ381S5BuMOe33snKiPcpbBGg5jeGzztT2ZAgsUWk6VNy0Nov66xSaF1lgqNAmaXeNI/7Xj3klr8MyO4JaE5h4MVX6SrjSyxd7UETQF13SArBrCbWorvDUBjf5Pek+wYIZJ+3KceQw/YywOa25XaBXtB8LJwFCryBZNJGWMNQoArPKO4okw0RtqMikxlRaYSgt0PWMa3sfBviO0KiW3MW4nMFjCWxcEg9rCqGi6OZ2MkIka/TqF9q25wig895uvpn3g2agAiLqyxKSk60ofSh6mbblvoSs/0Sc5fVaVt3/gjHy+2gMqqY+kESAz1r+49v9iuZbroazddtsNn/70p3HzzTfDOYdf/OIXuOWWW7Z72VV1v6b5Lr/88m2uv/zyy7HHHnvslEUt1wOr39v7O1BMwzgOAeu/CJsJvoRpcNh72cr264KfHQnBLG3Df3kHAGUdp8diFsa/tcJjhi98yU2MoKkdx6Qq/Bk4jXTfVfRwRzGJTeUE7qwmsaBzOkO2ChOKXKETf+AujMRUNor+R3ut2kKP4Z3YATqYJ9w0wCodYK+JWTx2ZhMeM30X9p7ZjN27C9h9ah77zGzGoPT+OQweXFEbzRgOIUiLJYXByokB4Bj4RE2sjoXXNzVA6oYXvgHBNBNAjLWh3z3I4hbWsCggD5YJMYrGX5hwcV1wxEqZmtY01gb0XlWh9Wc0h0xMtIlg3EEmOq5RcOs1U5RJZ7xuailf3W7fBYan3c4K3lK1D8qNk3WO44qnvBsA8NXj3gUAzeutVdwPlZ8kbGwQ7NjPGOvimaoAuBaqNN5n6P3CAghrA7NtnoO3P0iEjuL5UMH2gawESC8WgoAlt+h5u4GEGyzU5NCvLQGfYCLLWvtmMi3Q8cxX5Qcc2qxatILgjV1CYaQPLKbPTWVlbPFJRgBKMouV6QCpv08Y8shFjZGlJIGO10ulPmA8sFUNqDIUHWXG90FbIxVOvFJx/783lutBqqAdeCCXh0G96U1vwmmnnYZHPepRYIzh8MMPx1577TV22XPPPbHXXnvtsjXucJzMGWecgVNPPRXXXHMNjjrqKDDG8I1vfAMf+chH8N73vvfBWONy3Y8Kvk3keu4wowYQcEiYRodXUEzfyxa2X4I5WP/5E7DoiQKl1zgZD6YAYsUACkkunYLxB7XaiehjUxiFTNTQNYEqyQ2GOkVlBXp+XBuAn76js+tpNSQWpOpEpiC0XX45PwUAOGDm9ngQDTqWUEttFigo1oz9n/uAY+MdrWEBcIdaCzgB5EmNuWEOmWjUpfSWBQAcI3A0SCC7mowyo2YHfnsE0qz1/k7cwYQlOcDB5/1Z+FMdr4vy0iwuLIwR5CklLYwm3ZM1HFIZr+9ikEFcLt24QahDI1YHsWNJy8k7RMc4xzxwtGOxQyG+JbbJfIs2tNYkszE8OjAxT778dRDM4divnDHm89Vm3pJWoHJgxwIYkswCnK6vtI+a8dvRjkfH9AC87u71bq8XQAxn5qApuo6sUVhik5IW00aeUDU0E7HVFlrT2rNJ5OtUY8ELzYMIHgBGNbUMg1i+anlltQOhpX++lRFRrD9bdrAiHaIwAhOqwLBKsCJboNaboxZpYI4kENc1IQsyzvU5mGvUAkqrMKu7ECGA3EpYxn1kjoFxFJ/D/QmYdRyTsoihxwCiRcJy/WoUe4ATeQ/kvg9lvfKVr8SLXvQi3HzzzTjooIPw5S9/GStXrtzVyxqrHQZTr3rVq7Bu3Tq8+93vxr/9278BIB3VhRdeiOc85zk7fYHLteP1Lz87aglNX5PvlE2gGIEUs3RWfgcqnKlWTJIrOmtNYzGN2kkUTkIxg0WT+TxAAg7KWdTMeDNRiQlZYjoZoa9TdFAh4RoJ1zSu7YFZLihgNSTW105gUo1QGIWFKsN0MkJPlVjhp/wAxEkl4dkSCzY2St+YEhIAnFAFaYS8ZipRGlZwVFrAenBjGYNlHIMqQSo1ikp5Voo1ICV6HDVWCiFXL/ERKHQdicWt5XFSDwCc4eDSNMwUfItPOKiM9jPPNbXrLG2DC0AqEwXl4aUNoCi40zPm4NAwP21bBCUDyGgm0UI8irHktfW9p5095iXVbqsBBEpCzl6bUQp2CSE2BczBevZGGx6BVNRgefuDYJUQthkNTkGM4xVPeTeOvvzP6D3itUi1FRHIBWaorZsCiCEjgGdhXOOYHpzGteVjjuWhTd02CeXMYUIWGOgUkhvMVTkSbtCRNRbrNHpfVUaimxYotIztU9I4lZjzur9ooyA0+nUC6fd9KMkstNeWkXbLxGGAoInKWYWRSSjUWNTo++BiCzJZnTd5/OxasMhKcUYu54I5LNQZptUQtRNec1VFreUQSeu+y1Eyy/XQ18TEBPbbbz/88z//M/bbbz+sX79+Vy9prHZYgP6bVg83ATpAYKqwKjqhh3w9mtzRcdrv9/b+zv3a/sf/9wgYxzzjRH5T4SwfAAqnIngrLU1HUXCqRd9ksaUwV+foypJc0MsuOrKC9G7MI6MwpUYRQIWJI+sYfj5aia6ocGcxgUxozCSDCIqABiBpJzwjxuOZfsxd82fw4WwcIHf0oU5w4/yKRnRtGUZFQu00ILqEc+4wGKYwmjegx2uSgmaKcWrxKWXiAT0wP8abaxqfrTdu0EkidOaNQbmwsc0XWK7QOtS1IJNO/zcXpKESgsCSEBa1bkJ+GSM4xSML5eLzCbdpfyMEQTpNyhFgbv7n3cUDg+i1UsE/qjQyCsbD7QOo0mZ8TW0mKkzoZaqOf0encjSxL6mgybh2yyz4WLUrvvasYTqDt1QQz0emiBuKdWHN9UFjlQhNMTLeZmCgUwwN2ReEFl5lxpnQRBiM/IRgYKYyoSObFSq8L4Oovbk/nfws1BlWZ31/osGgmIUBiyxvEJwL5tDXSUwiCG25jqjQ4RWGNolsVmklSqcwNAprkkXM6xzKhxyHEswh51X8jAsfS6WYxin7fgXLtW09lAL0J/zu2x+wAP37n37Tw+r4lmUZrrvuul3a0tte7bBm6nvf+x6+851tD8Lf+c538P3vf3+nLGq5HlgFYNOepiKLgsYSYUcjZca3P85qUWYXi2fj4Uw+YxoprzEhipgHKBmZHk6rIValfWi/jp4qfcuNJqgSrmN7qcMbk8hwcBsZEubOJINoJkigafx5BWA1rp2xMP7MXjAH49uInFn0VIHHzNwVRdOMOXTykkCUoPH/olRYXMwJSKExqqQpuwb0kB2BG2NVAohJFYnDpbc5aEfUhODjEKbMpW0CiEUrFBgkjOfCwmoOZzlMLcC58xfvFC8Mab5abFFgzZzzxputkGTtpyKtHb8eaMTqbYG8RZNnF5giCzY2qQcguocDpGuqtIggKWv5NtVGUAC1Y2M6qvC4AGJAdTsOBkAMMA63DeuKZqQtdlJ4IXgbZA21QiY0OpKGHcJz0Y5HTzILhi1lD0Pvw0S+Tjqya8G007hm7W0Qqh0nQ1ovXg/6P8kteqqiSUEwzJY5ZstOnGCdr/I4DRsE4ZOqQE96o1yuydbAr1t6LWM4GRnaBPM6x5QfDkm5xqQYoSNq3+oUmJIjsk9hLrb8aidQWFpT7QQKJ1G4bcPul+uhL2Yf+OXhVgceeCBuvPHGXb2MbWqHwdSrX/1q3Hrrrdtcf9ttt+HVr371TlnUcj2w+sPHfAMGlNEX3I0V0xAgYfjSs88drZfscxUEc0hZjYzTF3HYZmgRTIgRXXgR2TCAApJn5MC7LZMTtvJj2oobTKsRVqX92KYLbQiApgZHNiEdjTca1J55494jh3vQSKAr+GHZaF5I23HjTs/MxetzUWNClljT7ZOYV2lIYaGkiRNxbeATW2rCIenUkImByjXSvEaaakhhGiE7QzS5BOh3wW0EVMyL10POHuMWIvEAquWITu093xaEt2zgaDymQPqssDbRygsMLFTbgFQGqwbXOHcvdX+3GP+bnrsbs00IRYaQDN2kRG2E9x5rmCdtBCotI+sVxOhSNLl6YQ3BuTyUcyz6iwHYxrah4y0ImAczwYeJo2HQJGtanLoF1oIwvDAyTpkG1qsyIk7bFUYhERra8ti262tqz3VVBeGnDBU3FHTs23Q9VaGnqshCDXUShe2cOfTrBLMlteOC9mo6GZFZLaNIGONZKRuZVvID64kSArQvaS0GGW+E58G+ZJXq47ZyGgsmj5/XlJHB5+pkEbeV0y3g2QyYhNSAMGzSN/efDVmu5XogddZZZ+F1r3sdPv/5z+P222/HwsLC2GVX1Q5rpn7605/isMMO2+b6Qw89FD/96U93yqKW64HV+68/Nv6umPYi9CZLr8ADO6u88H8PhwBgIOI2SYtFOicFEzVKoT3Q4eVY2zHlGgs6o9YdGCZkEUe1CdTQ2bVAM7IdmK2gE+HMgTvnXdfJYFDycTG5dhyTXMOA0Vm9F9oG7QkQzCh5i8WwWJEO0VMVbhtMgjGHoQcn1jKavvNTdu2fzpF/kxQW3Hs3BSdu7Q+6zjEPzJrJNCksNGsN1rgmT08mesyTyARdFHcRBDjHIKSJYnRnGaQiNorLxt07VNBLMW+UKVs5fLQ9RPDDW9e3K5hqhsGCUMEaQft2V0dV0I7HCJlQ2nKkkoTjAUTVvvVH7A9VOz7GWA7uAUpgpUKMEEDTZsH0EgByWY+13QLIqq2I6wmWDokwkRltg0rJLfp1APA2rh0iZN5pDLWiKVNhouYpTBl2VRVjXoZakV4qKSGZjYHE0huQVlZgOhlhtuw0lgq2CfO2YMhZjQVN2qaUa8zW3RgLU1qJBU1muFNyhL7JkLIafZPSZ05orFTkM8dhMSEKbK57EdiRpQnpwHJRYUYNUHoQJsJJA7OR6VquX4EKE78P5P4PszrppJMAkB0Ta2l/nXNgjMGYXfPe3GEwlaYp7rzzTjzqUY8au/7222+HlDu8ud/YuvSm/fHUvR4c8Pknj70C/3j9MREcWMcAxpEwHc9GJ3iBC352JF6yz1U7vP0X7P09fOqGxyMBUDnE9h5NCYmxnwJesG6bFkvpz3B7ggJaB5rOwoPmI+cVFlwWGaMZOQBAoI3OtlVk1sKUEWcWqV9H6SeyKiuRixoGNAmoIfzvTTuSe5aK88ZbJzi2B63NUrd063VOjLnYkmPcwRoGxjy4sBycWw9KHATXqHUTFxJc1EMbLUzkweutuLCQ0lC7jgXgZAEFaicCEL51FFqbztL0Hj0Goqg85hL6nLm2IFtJAjKC2fh+SQIQ4y4G4obXIuw31fJJasfLhL9zVdFrW6WQYjznkDHnXealt2Sg61OhSUAeWmMtYNx2Ug9TeaEN2NZEJcJEtigAqXCfrx73Lhx3xZ+2grJ1zMej/cgjYCrakTdex1RZQeaZwkSvswCeEm6oVeenGduALACmyoioh+rXxEppx9FTJRaqjKwWqgyZ0NE4NNg29OsUu3fmAAArkgEW/YkIh0NPkvh8ZBUekc3hznISW+sOFLconYosb9ivk7JAR5TYXPfGWuQ9VUIwixXZAPM6R19nlF3JKxRW0YlR64TjXdc9Fa/b71Is164r9hsyzdeuK664YlcvYbu1w+jnhBNOwJlnnonPfe5zmJqiUfS5uTm84Q1vwAknnLDTF/jrWh1W3fuNHkD98WOvxD9ef8xYO69yBDKGRkHAYkLc/4Z5wgwGjt4+E5y8cAa+dRcqCFYBD7gcUHs2q7QythwDQ9ThFQzoPpOqQG05OBdRH3LTaBUemc3C+oNVaaUHX3U8YACIzs5BfB6mA1OuIb1oF0Bku+LvaPQlI0cCeDlhcePCSqSSQpJ1SzDuWGuKz9F0HecOGgFU0EHdMhdbhbUW3seJ+TOpRt8DNCyTEMQKSUEeUcoDglqLOCnIGU3DBVdzJhyMFuQj5Stst9YiWj1Yv5bols58Vh+IDUMrW2/pFGS7QsZdO6Q4AGnOSICeSB0tKhQ34MJFEARQC9J5zVrtQVpb0B7qiqe8G0++/HUorcBEUsbMOnAL2CYzLxMaFcZBVNivx13xpwAo0iX8X7aMNAu/jYQ3eqzMt/MWqpSAmhUkRPd+WtqRrqwNpCSzgPBtQw/QrPPZenWCDqs92BfRZ42MOmUEWASyqrimVVkf83U+FliumMGKZADrmAdSW1FYha4s0RMl+iaNzuUB3PU1tQw3VZNYpfpRX6m4xpZ6AgBQWIWBpnDlFNSiN7x5Lc7c/2Kc89Onb/c9sVwPcT1Qr6iH4fzZMcccs6uXsN3aYTD17ne/G0cffTQ2bNiAQw89FABwzTXXYO3atbjgggt2+gJ/Xev6aj1++0F+jD9+7JV4//XHjrVhAPoSLpwCt+5+s1OkgxIQ4NEOIfMWDIVVWLQZhRY7Gz2nDBoT0Y6o4m0Br2PiBh1GZ8GSGUhhoJ1AxjSJZ6scZSKxW7YVd5RTGJkEuSixoDNM+jahdQy5qL3YnhSWAs04ufGeOeEMW3EbtSE1KI+vdgK5qOPE2ONm7sA1m3endXIfOmw4oBkgGn0TvEt3ACfWsjh6H6b4OLeotYpAJmb+cQehDIQEMVO8iXkR3p06TM+NStIXxfF5r3/iHODCRP+oUJEV8rop7YXzaeIdx8HAl3ypBibIwj8HuCjWDjl47dtp8AiugCaGJQT/WscwrJOxUOE22GHMkQkqWvYHfnDghK+eji89+TxY0BReO44lsGMdXo1FswCIAKW2xJLKFosWbByCfklbWr9lTaRM5UQUhktux4w52xOAAcS1hehhuwCBzsLKMaaMpvpqDE0CDgJWPVXGtl5oOU6qAqnQ8cRgZBX6JkEuamzVHYyMgmIWE7LAL4tpAOSAPld3YMCwLlmg/cYMNtc9pJw+SynX2FRNIOUau6dbfWan85pHmoSVzEAwi6H1Qns0tijWcSwbJCzXrqivfe1r9/j/o48++iFayXjdL2uEwWCAj33sY/jhD3+IPM9x0EEH4UUvehGU+vWb8Hg4WiMsrTZDVXs2aWgTdHiFFbIPDrvDgOorP38sjOOoQYCocEl8jMIqDG06Nj0IIOovwu2GNsHQ0P06vEJHVFg0GTFDNgH3gcy7p1txWzmDjqhwRzmF3bKt2Fp3MVd3MF/nmEkGGJkkRmgEXUcYIeeMwAhAcShBvAtQCGz7wBzuZx1HHaciOX40ux7Dihy7Fxdy7y3lPaRCZp+g6TyjOdJURxYrTOIFlqkoVXy8YFUAEICynuFpC9UzVY95MUWGLE7f8RbTE+JJxlkv51mtsA3BiZ0K4vN2WHHI6QtgI2yr7R+VCHLYN5aPAa+28Wa77Qc0WXttEBVu22a/vnrcu3DCV0+P7FPQK0U2qnW/wHoFsKQDoOVNCDJAbFQAPe3HD/dpb8+CxbYdQGCozZIN6iS6jof7hdt1ZB1tEgBEcBUm9CZVGVuDAShJZrCl7MWBiyk1wtaq4yNkMm/ZoDGhiugNtUr1sWgybK56WKEGmK27mFYjcFice/Cn8Nr/ehFm1BB9k2FGDtATBTZVk8QOwuEXxQz27mzCrO5iSg4xwQvcUq6M03y3V1M475BP4nU/fAEko1ZfWwcZPrOcWbx23y9juZp6KK0RjnjW2x6wNcJ3/vPND6vjG+fbzs21tVO7SjO1w9N8ANDtdvHKV74Sf//3f493vetd+IM/+IMHHUidddZZOOqoo9DpdDA9PX2f7uOcw8aNG7Hbbrshz3M8+clPxk9+8pMHdZ2/ivXHj72y1c6yKJyMQcizuodFm+/wNtu+UsIL3BUzBLD82W1pVXNW69iY67pBMx0UYi7mdR6F8pM+R7AjKsybHB1BjFUqdDyDDmwTGYCKqP8oLU1ijUyCEJshW+284H0UfKnC2kk75OL/wkEy5RoHrrgdT1r/cyhpMDk1RJLXYIGVYjRNBzQsUKr02PxbEJ+HvD/rjT6dY9QpZOMWCtYzWUKQsWQIcW5Hn4Sx+nYAc3syrV2BxeKsiTlpG1m2gRTg/aWYizE03z7xHZCiydkL+yYRGto1tguS2Sg+DwdubUT0lWpX8BRLvZmp4BZKmMhEXfGUd0ewRJNzMgKeNjPUtuQIzJmxnNgxz4QlnLL2QsZeyN6zjsXsvbB/gg9UsEiI+9ByaMuRy3rs8cPEYCKMt1aoo44q4V6g7mNohlphRTqMjv8Aad6SFjjbWnUwIUvkPl9yJhnE9/qMGmJGDrFoMkyIgjyodIZVSd87lzu8/ofPx6QsMK9z5N5WpHYCPVn4E50E02qIWd2NJw6FU5hRA2yue7i9IvnG6374AgDAlBw2+ktvj/DGx30ehZPxBGm5dlG5nXB5mNXWrVvHLps2bcIll1yCww8/HJdddtkuW9f9AlO7oqqqwvOf/3y86lWvus/3Offcc/Ge97wHf/d3f4fvfe97WLduHU444QQsLi4+iCv91aw/fuyVpGOxKsa/DE2CRZOhbzL84/U71ofOWI2EGQ9EtPeR0hBjIKSOeqpw4FE+02+CF9FGITgrW3APoGhar8OJqZoSI3Q4tQVry1FYRe7qNZ2RLfiz94FJYEBtvlxUyEUVJwEFmnYeQGLnIF4HGmAS1go0LY26ZQj6yMk5JMIgzyqoTLcMOpvJtzTVKGuJNKkhpUGiGudzY+lxTItZAhDdv6Nnlb8uTvI5htqzQNYxmgD08TScOVjDSbplSY9kDIf2F2s5RPSeauJtGEPUb5nWcw+AizPK3BPc4tivnEFTkx5QAQSWJLdQnIKI2/E/AJmghmDi8HxCBX1Ru9oA5Wlfey2O/coZBLj94zDfUgvtxlLLCDIBP+1oeQT6wZIgTHUG/6XER8KEdtvSacTChzBXVqBfJ9uwTNyDs0nvjZZJHfP8eqpEYWi6byahLL0vHP0+AIgALWjRdKslyuHQFWRaO6VGqB3H+w/7KHJv5zEpyU/KOI7SSgx0SukC3GB10kfGa4xM4sX5Or5/g8s7PTf6OSEKkH1JgUemW8b+tyZZwCrVxyrVx4wcYI1awKZqEvM6R8rraIlwzk+fHm0S/u6/n4LlWq6HqqampsYuq1atwgknnIBzzz0Xr3/963fZuh42YOov//Ivcfrpp+PAAw+8T7d3zuFv/uZv8MY3vhHPe97zcMABB+Bf/uVfMBwO8fGPf/xBXu2vdqW8jqBHeCfl2okxQPXx/z3iHrfx23v+LzgsOqxCxuqomzKOpga7vESXlzEUGWgYoIzVUT8lmIXilBcYxrUzpqH8dF3bEyvjxAiEv4NFQjBX7IoqJtsrbmPbb0xk3mo7tv82Hshx2Hh/xa3PPQtA0GJ9Po/9V96JRBikSkNleizCBQ6oKom6FrDe9oD0TC4Cl/A34y5O5oUK4mznAjhogJWxjV8TAGRJHS0NlNJ+apO2045xWQoSYxvPr0cwG1moUG3rhrZNQMezMj1VIfMMn/T6rvC4HVU1UTCtxw9MWNBFpUJHpqjNDgGIE3ldVcX90tYolUvCicN6BbeRqQoVROafOuoD6KkysixBwxS8poI2qued+Dk8o8UbUXxPVZhUZRSQB2YqsFNN7IzFwDOj7fdoYPISrrEiGeBDT/gILjjiQ7jgiA9h3icC/MPjL0Auarzy+yejK0so36ZOGbUQ76wmUTuODq+wUg0iexdCiUPaQNjXAOLU3YQosGiyeHLyi2pF/Ixsrbu4o5zCVt3FpmoitvEEc+jwClvrLn1WWiCYTDyX2aldVcw98MuvS61evRrXX3/9Lnv8X1svg5tuugl33HEHTjzxxHhdmqY45phj8K1vfQt//Md/vN37lWWJsmzCPHelCdjOrmCZUDgFAYehTSi3S+dQyXifWcDezVaaShiJdMPtJ/gIimkUVkEwF8XlFgwJ02O6GDgyEJw3OSY4nSnPavqyVkyjcBJb6i4O6N4GAJj37s0AcMtoBXJRYUvZgwVDZSQ6ssKiTpGnVWRZJHfgMGOtL+sdpdoAa3utscBiccYgnEPtKBA25RpKGRy8+pf4waZHwFgGmRIgqLRAXUqotGnZAI2/UczCQ+OUzrmLeyW2+fzfUpgx/ydaV+OTVOgEShqUlYqtwrD9sL2ws4PvFQxZNgA0SScYeUzVluPqp52FJ17yhmaf2KZ9Fyff/E/tgR1nBCIWa5r+GmkVLQ4Acv6uNE31FbUimwlGxpthn29PB3X5se/BU688LYKqsX3AHKSfrgx/t/8XLtaR9ilkAj7nG6dgUjlMqhGGOo0eUj1VjemmALJJWJEOowVCiJnpqTIKzZdWaNuF93l7P0hm430BYpqWGude+KR/iL+//7CPbrP9v7j2/+IdB/073vyj59K+8xq14Jkl/PM2jgDPjBrgzP0vjvd/4+M+DwDY+OPnxBOVDie2a1Z3sT6ZhwHDzaNVyEWF26spzKhBdEHviApTYhR1jUOToiNKZKzGedediNP323Utlt/Y+g2c5rv22mvH/nbO4fbbb8c73vEOHHzwwbtoVQ8jZmpH64477gAArF27duz6tWvXxv9tr84555wxCnGPPfZ4UNf5UFeHN0Ax5TUU1zFeonYS//w/vwWg0RPdU8WJOJjIOHV5iYQZP+1Hl5TVSFntGRC6hLYg5fZJdP26gnZpghdRG0Vn3mS7MDIqrm0qGcVWCrlXN7YLAGKEDWcOpvVWbx98l7IY27sNrctGQ1ECEAap1BCcQoLzpMZkXqDXK6INgmixUrUWUacUthyYm9CeA8ZZqvb6pI8+YYzy3iwYEp/5lygCb0sZrgCwrDcNdQ4xYzBooQJL0/aRCiAlaKuCo3kAPj1ZRRCVeXZJefF0sEQIwM5Yjom0IACiaihhkMkaX3ryeRGkyNZrEMDGU688bRuheLAwCE7lgUm6u9cstPfCZFzCDYYmwWzZjZYDbVAUQVgwBPUgTPqJxxXpIL7HpNdDrcvmkXCNjiwxIYsoVr/giA+NmZRecMSHwOEwIUt84sh/wnsP/cR2AdM91TsO+nds/PFz8LYDPxsz8mbUIP5/UoyQteKbgtXB0tp4wOdiC3Cr7gAgXdQtJbFUK5M+eqKEBY+RTgTSePzO6JvM+8g5FK4JO1+u5Xqw65BDDsGhhx6KQw45JP7+9Kc/HVVV4cMf/vAuW9cOg6mXvvSl9zqaeF9r48aNYIzd4+WB5v21Vf5A45J6d3XmmWdifn4+XrYXnfNwrpfscxUyVtOXotc8NK7GzRfi8x99NT5zw6H41A2Pv9ttHbXhRiTMwKLRqAAEYgQsurxExr22yrfUFDNIGUXQdHiF3ZKtSP100IQoInjKeI09slnM6048wKVcY1qNsLnokcC2yrG16sSDvHYcc3VnDFgJ1mhi2qxUWy+19CBsHIuATPkswVSQoaj09yVxe5hy84HJvHE414aj1iL6O3HmfNYd95OA2CYSBq4BE8RSIVortNfZNhGl9iFvtFB+e86yCK7aDujOESMVpu0AD7wc8MRL3gBtyefLOcRJuHKJgWVgpDLR+DVlnpXiaBg451mTfpXGtln79bj0mL+J/k5h22F71jEM/NRbaDXmreDjcAGAjs/1G5v+YzbqooKJZgCO1K6ssCIlID6dDCNAi55SntGaTkZI/Htl6M1lQ+WC4louOOJDOP/w85FyjX954ocjOPyXJ34Y//LE8S/3f3rCv+CB1MYDPkfP2bfggOYERPjJVYBYqHcdfOHdbuctB1yE2gnsnm5FR5S4ebQKgjncVs5ga92BYBZr1EL8rDwimcUqtYhN9SSGJo3DJqfvd1l8/HAitlwPXf0mtvluuukm3Hjjjbjppptw00034eabb8ZwOMS3vvUt7LvvvrtsXTvc5ltcXMSJJ56IPfbYAy972ctw8sknY/fdd79fD37KKafghS984T3eZs8997xf2163bh0AYqjWr18fr9+0adM2bFW70jRFmqZ3+/9fh8p4DeFImLpos+gx09YjAaQjmuSju93OxTcdgJW8YaiM45GlsoyhcjKaWnJYJIxcmGv/thOMWo2ZzwZbJRdROLJVyHiNKTGEQRcJI01VSLXvqRK3jmaQCI1+nUZzxNVpHxbM2yXQWHjeDklGI44vrSS/HTS5gUBj3hl+F7CoXfM/gFqaK5IBHjkhcCubxrBKyHrAu55TeDB5VulaxOw9XQsflsxQDxXgwVQyWdJu4uSo7rwhp7UM4HTGUxqOVJIAvDYCuapRaBmBRtBjBbuFGIzMwmSgG2P0275O9LefdJQ6gizTslEIYvg2QxU0Q0EULrSNaxCMwotpWq5GoRU63hU9eEcRY0T3LbSMLFNoo9VGROar0BKZbPRrEUB77yfVCiwOYvDMtwLbwCt4OmmboO8YVqRDzJbduF8kt1iRjiC5wceO+CBe9r2XQTKGiWRAwB0M3FE25FJg9N5DPwEA2wCoUBcc8aG7+yjtcL1+/y8CAN513VPjddxrtkI7795q4wGfw7k/fRqMz+XbqjsQzGF9Mo/NdQ8zagDjpPeaSmkiUBQ0/WcV3nLARTjnp0/HlDDx5Gm5HuJ6oBN5D0MwtWHDhl29hO3WDjNTn/70p3HbbbfhlFNOwac+9SnsueeeeNrTnoZ///d/R13vmI3bqlWrsO+++97jJcvun4fGXnvthXXr1uFLX/pSvK6qKlx55ZU46qij7tc2f13q5H2+BQ5qfWWsRsbodWsLVwFip+6pnr7Xj3HEhptiK6DdxgssRBCaW8ejuDuIWmnCrtFuAYimngCdcU/wIrYXggdOqFzUJA6OzA2ZRmaijuaHtRMY2oQMPcGjl1SowIZkvEZHVPFMPE4AtliQ0DY0oGDZfp1CcRq9L2sJ7fP7onhbCzBGgMp5QGNtY6AJ4ZBOkUg+2hSwbVt9AJArL+LnFpmqadzfT9ZZz2K1zTDHbA+EiY/bnuCjtTd2CbQPnQdPdN+6lW1XaBkn3UKLLgCbyk/VBdbKWI5CK1RGIhEGk2kxZpoJwIcGyyj+Do8folS046isiPcJjFPbaDMRJk7IxYt/P1ZGjLUBw2OG6/7zt/8Wc1WOFekgRspwOFz4pH+IbNT5h5+PC474ECxYbO1losYnjvyn7bxKD2391Y+fjaFJo8XImftffJ+BVKjCT/cqrrFK9QFQ+58zR4MgnoHq8BJr1bw/6aKhEYA+o0ObwIBjYFN87sZDdvbTXK7lAgB85zvfwRe/+MWx6/71X/8Ve+21F9asWYNXvvKVY3rnh7rul2Zq5cqVeO1rX4v/+q//wne/+13svffeeMlLXoLddtsNp59+On72s5/t7HXilltuwTXXXINbbrkFxhhcc801uOaaa9Dv9+Nt9t13X3z2s58FQO290047DWeffTY++9nP4sc//jFe+tKXotPp4Pd+7/d2+voebpVx0jcFcAAQkEnZOCC+u/zAK3/+GHz953vHvwWI0WkDKwUTW32ZnyAEMKap6voAZAAxXiYAKMEsaidROPrCJxuHFDPJkEw1PTPSBNTSGL32I/lDozAyFI1hPXNkW48FILJxxjWj/QAdJIIFAIFBFp9X+D2MzIewXvodfhqPRW0o9wyREBZSkjdV2iuR9sox0Tnz6+FLgocDSIo5eH5yjEATGo8nYX3IMpl+hscMXW1qM7L4d22FX6+fFGxbFwgbGR7nGEojKVPQchRGtjLjktiGDXl97QqgLrTQgog9XNpmnOF/FNlC7dW2ZqptZxB+D07mS60tmsm80r83GlfyAN5e+f2TwZnDQk2DDQk3+NRRHwBAIKpdH3rCR/CJI/8Jnzjyn3Yqw/RA6i0HXLTd33d0GxsP+FzUJ/ZEgaFNfEveA3h/UkSWJHRdxnRkxV6336XxhKywahlQPYT1m9Tm27hx45j4/Ec/+hFe/vKX4/jjj8df/MVf4D//8z9xzjnn7LL1PSAB+u23347LLrsMl112GYQQePrTn46f/OQn2H///XHeeeftrDUCAN7ylrfg0EMPxVvf+lb0+30ceuihOPTQQ8c0Vddffz3m5+fj369//etx2mmn4U/+5E/whCc8Abfddhsuu+wyTExsX5j5m1S/t/d3kLEaHV76VpbAvOnAguND//PbuPSm/e/x/tSaa4m6w/QbSJQq4Ag0wYx5PDVfxnXUa02LYYytCKPdwWV5SgyRsRorZB+PSGZhwbF7OoeVaR+FIYNEgA6Wt48mURqJ1JsuNlqpRgNVWw7tdVkp19BOQDvhmasGMAnv3h70IG3vHgpktphOiG0JE3G25b5tHfMxMw5cuGjAyVpAon0J4vTgSs45AaMQJRNab4H9aTNPSnojTW5hLIuALETShPvxFktTVDKyVe1R93DbYMUANOxU8IVqM0mJ94CK1zOLXlLG5zSVFOTFJKh9KJmNdgPh98Bs6RagC7qj2giUWo6xU9pSKG9gpILfE73/HDqyRs/bF8Tw5pYIPTzGfJ2DM4dPH/X+CM5e8O3/Dy/49v+3zfv9Jd/5I5z83ZcDAP7o+y/d5v+7qt5ywEX3G0i16/X7f9G/t2tvL2KxaDMIuBg0XjiFKTHEWjk/xh63W41huvfC/z38Aa9pue5DWffALw+Tuuaaa3DcccfFvz/5yU/iiCOOwAc/+EH86Z/+Kd73vvfh3/7t33bZ+nZYM1XXNS666CKcf/75uOyyy3DQQQfh9NNPx4tf/OIIUj75yU/iVa96FU4//fSdttCPfOQj+MhHPnKPt1majMMYw8aNG7Fx48adto5fpwoGmsAQAH1ZGu9fA1BkzFP23L5vB2mLdNwO0ByUA3AKHlZwPOqiAGyT6WUctQg6vPIGoHS7Wd1DTxSYFkNkrMLAptg92YrCSXREjYGoIzsU4j+04yiqPI6p104g4RqVlVDO+vw+HfUlwemcs2b9oW0SDhjtKJEQkVM7gcdP3Ywv3rE/ilqhl5VNVh4AUwvvPxXAEjy75NuAwnqvJ/KSCu02JWndTQgxhR23jSn9TvYGlSy2qEIt9YtyDo01gmff8rSOTFxghNiS09TQjjOWQZtxm4ShVqg4hf0OtRoDQiNNlhgTSTkWMdNVVXy9eqoaY5MC6xUBE6dJu6H3MPrSk8/DM752KoGnpIigCgAWvG4uGIGGuJZMaFRGoqdKaCuiEL3dCuyICi+66pWYSUawjmNr1cGnjvoAXnTVKzGl6LqBSfCxFhtVGomTv/vyu9VGPVzrjY/7PN7738fjtft+GedddyIKJ1E4CWs51qp5zOoe5k0n3j4Y8oaTsYzTCdbA/nprTn+l6jdIM7V169YxvfOVV16Jk046Kf59+OGH79KBsR1mptavX49XvOIV+P/be+/wuqo73f9da+29zz5NkmXLRcWWjbGDY4opIRiMIRNKJgWSXCC5DAm5kEkBEkLaJLm/wNxnMjyZmxnCJEAmDUgncwMhkEKc0EwMpppmsI2bZEvGRVY7bZe1fn+scvaRZLAtyZbt9Xme80g6Ze99is55z/f7rvc7a9YsPPnkk3j66afxyU9+sqbac9555+31yBfLweMDRz0nPVPKC9TICiZsk6rq0p6QAZz62ykf0TfFIIwnSy6fjqUpHTBVLY/Epgol/UwOeqKc8WkMxj564wwKPIW+OAOdng7IuXpZJ0BrZrdMuNbp06rqsbXYoJKs1Yw1KiMF+iMfevaeHj3DQY1nTC8b50YcDolJoDLxPQaRIY7pskwGd2RcAiEC+XwJ+WwZKS9CygvheyFSToSMFyKbClDnlzEpXUJduoxJ2VJNlIJuhzLV3tMBmGHMEHOCQuChEMgxPWk3VMfElfCqbaNpPxVT8QwO41XfFqRwFEKv6KuOq0nO9QNg2o5azFEiZDVJCRSdPJ52pUjLebK9Vo4cE3pJiawaadN4OXbMSj59LFrslCMHfUHVL/n+v11lKmDl2DX5T0lhpI/LtA9FNXB0klcYFl7qURmgOcUrYHeQxa4gi/9efBsuXflxNR9PGtO5IPjHpz9qKlbl2B2W3n64oOfs6cwo+QVH/t+ahSagGIx9fGL+I3IqgRpyXv0yQuCTYOQdWCz7ybRp07Bx40YA0v/87LPP4rTTTjOXDwwMHNT5wPv8jnDTTTehq6sLt9xyC0444YQRrzNp0iRzpy0TGyl6uPFIUMKVUZybN8+ROHFmB06ZuQkAcMrMTXBJDI9oj1FViOmWQZ3KjZLhndXKlWwLSuEVg6I7bMCXFvwRjMg09CnOABg4dkZ1GOA+itzD+vJU5FjZzNzrCbKmTZNxAvgsNB/yLuFI02orkEIulddDjPUg5FgQY4hPLjGniZafjpPQJlwGWSVpzvYj7YSoS5UxJVvApHQJk9JF1KXKqM+UMCldQoNfQp1fRj4lT1oAeCyCS2M0ZQdrBga7lMNLrF7Tq/a0wVuniCcTzoFa4ae9Vmk3NNWnKKbw3cgIL0e1E/Xj47HYpK47aoWcbjc6pDrSJZkennwtlUJXjUqhZiWdFk7JKAOfRTW31cc+NLE944SoU8IsKRDrvDLuW/Ids72cG0jxhOrKPf38UQj0hWkTl/CbxbeiGplAsTPImrbwB1d8GgAwEPnwaIRC7MGjMVr93ci7ZXz0yStAicDPT/3BHv83Dhd8EqHCXaRoiAp30cgK0gogKCY5Bdz86jsBSMN6LKhZzcdIdcblfRuOO2jHfyRAMErP1MG+A/vA+eefj3/6p3/C8uXL8ZWvfAWZTAZLliwxl7/wwgs46qijDtrx7bOYuuyyy/Z7hZ1l/Hm+ow0Pbpq/T7cJ1fLn6t/SkP1GlamhrAumyTYVqa2MJIlRXYpPwc1Q5B1RHlOcfgzGPijh+P9efD82V6aYEFDdcsvTsmlBypwdGSAZqBV82pgNAD6TH7Dy/lCTiq4T07cWGzAQydex9kQNzepJ4iaEovaVuCTGglw3JnlFTPUHMTVdQM4JkPcqyDgh8l4F9V4ZWTdAxgnRkCobIZF2QylQKEdLrg+t2V4satqKM6ZvwBnTN+DUqZuQVkN2datQt9m0Ryv5+GrhJAcUc7XSr+q1YpQj7YXVdqISSp5TXSVIlThjtCrekvsmquKjHzMteqKEnwsA8omkb0CKtJyKRdBVIx2rYIz9ieHLeriwbiHee8Z3zXa01+rnp/4Al678uGzhCYrfLL4VDyz9Nuq8slnpp4M39evBU4b2pCfqrtO+JyuTiVWG+ph+euoPawJFf3jyHbjzbT+qSSo/nCkLGZSr2+FFnkJKfTHx1Eq/q9/yIHwSooEVTLvfVV+YHti4AD4JaxaqWMYYvcplNKdDhH/5l38BYwxLly7FD37wA/zgBz+A53nm8h//+Mc1E08ONIdnrfoI5viZncjvZd7Lys2za9p8OmBTt9ECwcy3zzfjkrlPwUMMTxnO9U9Atm9iEFOl0sKNq9V7bV6Pmf+Vp2Uck+5ChTtwSYQdUR5NTj+K3ENfnEFflMEkp4iBuDrkOOAOHBqjnEhH52pZPSCrT7ol6ZAY9V4JObcCj0Ym1VxeLzYVJy2W9PkxSOLyaiUvRUMck+1Giskl846KC9Cz6xpSJTiUo84rw6MRcm5F7TtGxgnRnOk3H9jVapgUHQsbunHa1E14e9NmnDZ1kzwWyuE5MTwnMiv8anKUiDDDhXWLrhI5pi2X9QKTTxXGDJXQMYIr2drTK/N09MNIJAM1ASDlRMi6AYqRa44p44TwWGxW4JVjp8YEDshcKH0dXcnSJAWOp9q0APDBFZ+WPijOcM/pt+DDT/wjPvzEP+KXb/8+7jn9Fng0xj2n34K7TvueCdX8+ak/gKPCOCenBjHFK+DSlR+v2U9yWPNlK680wZtbypPwsac+9qb/B4cTX1nwB5SFo4SUHIrOIJBnJRR4Cgwct645G3lWqknQ54KiyGWw5zmzXzmI98Ay1tx444045ZRTkM/nMXXqVFx44YVvOA/vE5/4BAgh+Pa3v11zfqVSwTXXXIMpU6Ygm83ife97H7Zs2fKG+25qasLy5cuxe/du7N69G+9///trLv/v//5vXH/99ft930aLFVOHIbr99mbEIEOGljoocxcD3EdZuCgLFwtSW/f6m2VZ+aH2VNFKhnvqFp8ekqqFiUti7IjyyLDAGFkZ4WhkBRRjmRfl0gi7wiwqSkR5NEKKRqj3Sib5nAuCBq8oW3gqI4gLalqD+oNYp5qbCgmqSe3abE4JN5k7Gj3YWS8Jn+INIutUwEV1REm9V0K9W0JjqoA0C1HvlpBlcohunVtGg1dCJKjx30R6ziGpHgOgq3gEJ0/pgMNiM+JFf/CbsS/qA00LJgDIpSogRBiPVSHwkEtVjBDTtx9alXETY170ZboFp2MHIk6RVUZyLb50jlMy3ynjhBgMPfM7ANS5FSw76yY0pMrIuQH+eObNNfEIuipW51Vw0YpP4d4zvov/XnwbfrP4VvPzrtO+Z6IM9DFe8vgncdGKT8FjkRFKSX759u/DoxH6wjS+c+LPzetFC7x6r1SzPUDmOX3/5DuRoiNv83BGj4liEMYn2KtM6DHkUHMuqDlPv2bzrIR3tK/B8k1zsaT9tYN2/Ic7o2rx7Uc0wiOPPIKrrroKTzzxBJYtW4YoinDuueeiUCgMu+5vf/tbrFy5Es3NzcMuu/baa3HPPffgV7/6FR577DEMDg7iPe95D+I4HnbdodTX14MxNuz8xsbGmkrVgeawHXRseWNkCV4+/dq3pKsuGka4fCPdw/y6ofRzHy6r/lMl5+FpAaV9U/qNGAB64hwytGJaB+DATp5HT5yTU+m5a0RXzpFVs4gztPq7saYwDbMyPegu14Oq+Xl6plqOBdJUDiGjEWiMWMj2Ur1XQil2EQuCOibbgS6tFUzVuWTKlK4eG226BWCM9Y1OAXlWxkBYbYE3ugVkmExuz9AAFeGiEjuocAcp5cdxErlVsQoU5TGtzgEEN2Z9V1V3dHWGg8gsLiUIkmNjsl5gWldCEDT4JewupZH3ZbZVGMvqlefEZlWgFkW6GqW9WrpylXKr2+SCIOPI1ZQZR4Y8Jn1R8nGT58kBwYH0eyWE9kUrPoXfKDEEoGYoMRcED73j3/fqdQegxsP04Sf+ERTC5EF97KmPIc1CMwtPB24m2336fsWCmMs/+uQVuHH13+PrC+Ww4O+d9NO9Pp7DBZfEyLOyGo7OTS5dMvhWVo8HTECvSyIwcNveOxAc4NV8f/rTn2r+vv322zF16lQ888wzOPPMM835Otj7gQcewLvf/e6a2/T19eFHP/oRfvrTn+Kd75Sdj5/97Gdoa2vDX/7yF5x33nk4FLFi6jDlqY52lLkz4rfCZRuPwXmzX8Ejm+YBkP4HUOWVMgGeAh4iI4D2hnNmv4KVm2dLj80QUQahE9YjlIWHPC2Z7TY5/QBkFIK+fr1TxM4wj3qniM5wMvqijEwyD6Wo4iAocg9plTOVohHSLEAp9sCJQN6Ry+chKPojH2kWIMOGJ/TLcM7ImMr1nEKfhIghDcrSXB+ZgMhQMHM9AGquoUyCbs/swo4gh8luATlHerwmOQWZocVjxCINl8ayioWqiGJEwFNiToomHURabYeFnOLhv/sWzn7w81K06LBLJbDMKBnl/SqHKWOJiARF3q8giqv5W0IQxKKaWZVs1cSCIhay7ZWMRNDo6lFyULBDOYKYmbDPpPDqD1LIuYFJQR+Mar9BXvL4J3HfkrHxIg1NJx8awKm567Tv4bKVVyLgTo0P6hsvvwed5Um4820/xWef+/CIt711zdn49PyHcOnKjx/WZnTdztZfqvRq3GrVVGCa24dQOLjkqKdw12un1LyOQjCs3Dwbp86yC5IOR3SuY2NjozmPc47LLrsMX/ziF/HWt7512G2eeeYZhGFY429qbm7GwoULsWLFCiumLBOLU2ZuworNc7B801xwUCxtXwtACqlzEkIKSJTrQeV8OcLhkwC+amVl32A+31BOnbURKzbPAYj8MI1BzPw/T2f7kIrKcpJtve1hHVrc3XBJjJ1RHlOcAWMc5oKiKBjqnSK2BXXIsQpyrAKHxChEKYScYWeQQ94pI+JMemJUpYYSgQqnSmiFqMSOqfi4JDYmbi2ktIjioImEdB1GqqIB9HJ7wRGCqVWIxJh1Q86QcwKkaIQmZwBUJUt3Rw1yriCrmDiGNA1Nq1Kb4FM0qqmASTEiP7wqwsE1z16KhQ3A6r5pRuToOXt6tZ1ZNZeoBmnBJARBmkUmXLQSOyaxPVnZAmSrL+YUaSc0oZra3J30NukKlWnTqRV1gaiazLkg2F1Oy3gIJzSZUO969LP445k3HzRTd7J6xVT79PsnV0ey6Hl7Q/n0/IcOyPEdbKY7vRjgabm6V+XF6SqVT0OUuYu+OGMWhuj/lxgUvTwjq9CE2HbfOEGEABmFiVzftr+/v+b8vZlRK4TAddddhzPOOAMLFy4053/zm9+E4zj4zGc+M+Lttm3bBs/zMGnSpJrzp02bhm3btu3P3ZgQWM/UYcziWRuUMCB4YOMCk2q+bOMxAGAElguZA+STAHlWQh0t1fh19me/bMjtGGTLSg889lSWEwBMdgZRFnJJfYqGaPd2IMfKxvgNwKSjUyLQValHJKRwGoxSJvrASRibt5XrUIpduMqfpBPMmWrluJTXeKL0Mepv4lxUWxlckJpxODJyIUaGBohVpSrkjszGYrISlWEV9EQ5NLCCHNrsFDHN7cMUdwCT3QJK3EUoZDsveWyAFDFuYu4doKpfVLYxHRqjOdNvRJNuoQ5NV9ctOw0lcvhw0h+V9Ce5TOVr6XBVzkASxwDAzOMb6m/y1Uo5Hd+gDeMU1RWAWqjpmXk6rXwicEx2G1r93cOGF78Zh3NVCpCiSI9aanTkIPHkopUGVlTz+wju23CcmXYQC2qquaFwaqYlWMYQPgYnAG1tbaivrzenvRnLcvXVV+OFF17AL39Z/cLxzDPP4Oabb8Ydd9wBQvYteEEIsc+3mUjYV/hhTlnNtkv6l86Z/YoRUlrYeCRGhgTIkzJ8EiEW1Nw2wHCz35sRCoaC8Gpm3jEihRQFVyJEFkZ7YxmOSCGQp2VkSSBH3bAK8iqfyicRpnoD6A3TaHBLqMQOesM0PBqhN0ybD3zd7pviFUCJQE+YMX6gNAuQIiG4mjU31RuQIkmt3kspwZRsZ2nRVORezd9aWGkDuvYvUcKRojKoNBQMr5RbkKEVtLo9qGdFFLkHn4ZI01CtMqxGLmgohAmw5JADol31uOkMn7xbxuxcT23G1B7cpEmDefI8oXK3kpcLQcxMPF1hCuOqqZyDVEe3qFWLyVEtyZ/JuAF9ff33PaffAo/F+M3iW9/4hXSA+NKCP6Kr3LBPt7ls5ZXjczATiL44o3LWquOUXBKZMVQNrIA8LeGyo58AB8UHjnrOeC1lxTtGWQV+Wg/VxKWzsxN9fX3m9JWvfOUNr3/NNdfgd7/7HR566CG0traa85cvX47t27dj5syZcBwHjuNg8+bN+PznP4/29nYAwPTp0xEEAXbv3l2zze3bt9cknB9qWDF1mKMHFevqEyO8ZkixHjgsv21GZpWdvEyKrIH9GA/Ry9OmZSa9FtXWG1AVIbLdF8kZfoQjSyvYGjXApyEaWBExqKkcTXIKaE71IRIMaRYgp1bGDUYpM3tPjv9IocTlkOO8UzaGb0pky63OKaPJG0AxlgKpyD1TpdLHRtUHAiCFUoGnUOaJJfuQvjBpupVCrGpUl6KhnhUxxRnA62G9uV3I5VLzNAswGHumlRdDCrz+yEd/nDaPVVolUOuE9ljIgc0AVGWLGwE4VLjIx4OMOFyYEoGUEyHlyNBQ3wlrqlhpJ4TLYlOdSqJHtWiKkVtd5Ud4zf40utVXjqQh/V2PfhZcELz70ZFbAQeDfa1KTZSBx+NJI5OD5OtYWQ0ojzHV6TdtPr3q9MFN8+GSCPdtOA5/P/slcBBkVQp6cli6FVRji27zjeYEAHV1dTWnPbX4hBC4+uqrcffdd+PBBx/E7Nmzay6/7LLL8MILL2DVqlXm1NzcjC9+8Yt44IEHAAAnnXQSXNfFsmXLzO26u7vx0ksvYfHixeP0SI0/1jN1BPD3s1/CHzbKnnZ1tY3Ays2z4SbM4rp6VRYuenkGWSq9TdOd/j1ue0+cN3s1Htk0T1VVOMLES42p3CeGEBQcM50exCBSPAmCAZ5WLUH5j747zCJFpejLsAqK3EN/5Ju2HyUCuyo5TE4NgguKgVCGf3pU+qqo8kilWVgdWEwjI8BSNESRezJfi8B4p0LBpOdDmdCrY16GmOsBY0CXrUK5Dy3eAGCAp1HkHjKsYgzrORagq1yPptQAUup46hzZktStxTJ31TxB2ZrU4aOl2EWKRpid68G6/ikAqsJJDw7W7bUoMQImOZRY/0y2E1MqxLMSOabtpyMRtNk94MwMKwYA34kQxNXgS52ODqi5f0IgIKymigbAhHFaJi6MCHz06BW4b8NxKKovVf08DQZuvI+McLyjfQ0e2LgAZeHiDxsXwoUwPsJlG48BBzOrU1dsnoPFszYc5Ht2mHCAV/NdddVV+MUvfoF7770X+XzeeJzq6+uRTqcxefJkTJ48ueY2ruti+vTpmD9/vrnuFVdcgc9//vOYPHkyGhsb8YUvfAHHHnusWd13KGIrU0cIWdXCy5LAtJf0cv89rdYrcxeMcPQkhpvuC0vb12JJ+2vw9Wog6HBMjjKXy+g9JYhcwtHm9CBWQZ4V4ZqKWb1Tgksj9EQ5FOMUIjXHryfIojdIoxw5aoQMAwdBxhkeWpo0QgM6yTwyOToZGiAUDnrjjBGVsrUmx9zoKhVQHYisx8z4qnWoK1tl4cqVh6qSpZeS6zTpCncRCoYUi9CUGkDOCUycAyUCg7H80Ao5M/dV7leu+tOPlzbpOyOsttOiKnmZfgx0OnikgjuTt404RaRmAWpxpCtT+jo6k2loNlVy+LC+vt6Xrlbpocx/PPPmvX0ZWSYIl8x9ysQe6GBfQFa9tR/zA0c9hywJEitVqRyPpP43ZHVr332Ylj1wgBPQb7vtNvT19eGss87CjBkzzOmuu+7ap+3cdNNNuPDCC3HxxRfj9NNPRyaTwX333TdiftShgq1MHSHI1pX6MEStuXkoZsgvkUGeIYB7N5yAMndxydyn9nnfA9zH0va1eLZjpmmBMSpF3HaeQ5ZWMJmWsTXOo46WUBYedkR5UCorO3J8C0eZuNgWNGCq249iPBm9Qdp8SPdUMmhMFVGMPWV6rpqvKQQizuAmluyXuYt6pwgu5Mo9XZmiQ4QTIxx5UjKJzkm0QNLZOxBcDrvS5nXCEQsXTK3oo4SjzF2EnJnbalIswo5KDhFnaPQKSNEIoWBwEIPSatYUIKtSGrkakJsVdvoUJZLJa0QW4YhQXZWnRVPM5ZBiHfapH6ea1qCaawgBYzg321XHoPcXcWoEXbLlp8+3HDr8YeNCvHfOS7hvw3FooNXWt44K0SZ1RriqQjnGUgAADFVPYAwyukrKPtC5dQbaWroPzM6OEMR+rBzctGnTsPN838d3vvMdfOc73xmDo5oY2MrUEcKpszYiS0LUqcqUFjUjmZZjQZGhMs2bqragTwJMd/r2a9/a7H7izA5ZjVKtP0oEprJBNKjxNy1sQL0xEzSyQQxwGYDJBcX68lQwSA8RAEz1BuCxGBGn6At8lGMH5djFYOihP5StvULkYXeQAQdBT6gSmmmMUDDkWVmtEIyMz0mLG20m154QTwUX6vad/tat0YbbZLCnS+R+uDLyx5Bz4nROlcYlHMXYhUNiNLhFZB0ZnVDk3jCxG3IZXaG349AYaRagLdNrROVQkoKKEmEGQOtqke9EJqwz4tRkROk5e1pISTO8jF/wWWQGSw9tF2pRpTOnkpUwAFh21k22KnUIccGcVeY1rReQaJJCqtrO9k0WFYOAixguhqdar9w8e9h5Y82RIKTIAU5At+wZK6aOIBa0ba3OyFMnAGrunJ45J03gDbRozKcAEAgHFBxrOoePBtgXGAQKwjEfrr4xbAMdUb0xdXskRpZWVPuN4Sh/O1wSYZrbJ8M1IXBUdgcCzlDvyYDOcizfxDNOqEI7ZVQBIMe9ALJ1Vu+UoEfE6GR1vZJPVqeEGeGSRFeH9Go7/VN/mFSN4Gq1Iq8NOJTnMePhAlBNQ49ScM0gY4EoEaCqkeJFxinEgqAUSz/VQJQy7bmhBDEbFoWgxZQWObr1xlVWla4cJsW2rkwBMGNmkpUo8xipfUSc4vdn/qcUbyB4YOm38dez/2PvXiSWCUXSQA7AGNH1Igz9xSMWFFlawXvnvKCuE8GnkVnB65IIi2dtMHEnY82mLTPGZbsTmiNo0PFEx4qpI4wFbVtBCYa9oUnPD1f+psjEJdTRsly5o1bm9Yv9n330YqdcQusSjgyNVYVKIKU+jKerkRQ+CZFnJaRUu02vkotBMcB97A6z4CDoj3w0eGVQIme4aTHgsxCFKGVGk4RcVoh6w+r8MOlRkvfLIxEq3EWKhKb65NMQoXAQC5IYkyGHQZvHLDHWZSh6lpluA3JBUYxTpuKkVxemWVDNkuIU9Y4MSI0TFR+O6riXWGU4cUGNZyrrBMOGBw/NgUoKHjN4WFWckpUjDjLsNtp4DqiUc87MEGktzvTP+5Z8B/ctkaX7dz/6GTyw9Nu2EnWYoCtMFLz65UHlSDFweOq9A4BZ5CLHVAkT2KnDgmOQMatOre5swerOFrS3dmPb1pG/7D3f0YbnO9rGZH8Wy0hYz9QRyNGtXXi+o23YUnqd5s0gAFU5KQjP+B/G6htlVoVxalEXQ4qP3tg3EQkUAg2siCJP4fWoDnlWxuvlegzGKgYhhln1lnEClGMXkaBoTEkfVKCERopGps3X4vciRSM5zFn4qsqlhgYT6UuSFSMZ2tnACmbYMgAT5qkFV0VVtWLlu2JqxmFFuOr+yQ+dlMqf0h4SSuTjKf1gkXkedgY5VLiDnKPiEIYYz7lQVUUiEKnqlBRUHC2ZPmwuyERhLSq1MNLVqWQLDoDxVen9JFfi6etoEQXAhHHqfQx9/WgRBQC/P/M/R/kqsUxkZFCn9Ek1kGL1fQNylJVLpDdTni9fQ4tnbcCKzXMSC1FiPN/RhuNndu7z/p/qaDfC7di2reb86S1dI17/+JmdWN3Zss/7megQLk+jub1lbLCVqSMU/QamK1K6SuSpb5LaU6VX42j/w55M63uDEQcg4AIIRfXntjhtcqYyJFD+DNmGy9DAVGr0aBidJzUv9zomeUVkVHVmMEzBo5GsnsTMVI3yThn1TknGHtAQU9wB842aEY5GNaDZJRGytAJXDWNmpjrDTTVL+0Z0XIIRSUp0ah9WhbsmIwuAMr2X4NMQVHm0QiFX7EWCocEtoRR7cNT5+gTApLYDMuldzvHjakViVTgZgQQyLKJA+6R0S3CkQM2/nv0fNQbxZKUq5wQ120tWrrgguOCxqwEA7//bVfv9GrFMXPRre0n7ayP6oHQrLxQUoaBGYJ04s6O6DfWFbX/oSlSdPMQ4tm0Ljm3bste3X5AQXYcNts03YbBi6gjGV3lPUkDJN7r5bV01b3gcBIEyUIeQFY5nO2bu1/60gAtVuwoAAhV6qb9lMsi4hCwJkCGyQtPu7UQoHExz+0z+UoXLFUObSpNNhUomckszexAzZJwQsSBwSIzdQRZl7po23e4oi1SiZeer1HKNFlFDx+KEwjGCK0MrcEmMFAmRpyUjorQRPUVD047THqkcKxuBquMUKOSMPAouByCL6mVANfAy5BQpFpnZg5pSLFcIUghjDk9WmPTKu6S4Guqj0ue969HPVlfwEV5TmQp4NUsqaWK/5/Rb4LMQ957xXbz/b1fhntNv2cdXhuVQ4B3tawBI87j2D5oqE6o5bPp/ucC9EatOoX4/EWyfhFWzqjqt29K8X9Usi2U8sWLqCObo1i6EgmJ+Wxd8IjCntRtrOpurQipRhSoLt+bb6N3rF+33frVY099cXSKQVR4LLUZ8ZV6dzAZMSnt32ICW1G7MTu1Aq78bTd4AsixAb5hG3qmgzpXDjouxhyl+AcXINWGYAGoqPfWshD5VDQNk1ShG1YcUm9ZXdZQGAPgq1ZmR2m90yb/1fcjQACkaGv+IrlbJ7atBziqe1KEy5Vw/5jk2PCsLgEk/16vr9Hw/AJiV6wGAGq9UxCnKsVNTlRqauSXvpzAGcwA1M/VGSlZPCi4A+OXbv48PP/GPVkgd5hR4yrw/eCRGQcgVsUlxJX2P8v/32Y6ZNV++kq8lPSD8qY72fTqGo1tHbuUdkYgxOFnGBCumjnD0Nzy9jNglQpXpWaI6Rc0cPd0W/MBRz+3X/pIrCjVlQUEJ0MgqqkoVq1BKYkIxJzuDKMYepju98Ils02VYAIfGYEQg61TQ6BWQcQJQSGN3W3Y3IsFUDAPHziCHYuxhe1iHvjiNPC3XrMTTZvNQOCjwlKkq6bZesmWnxVasDOJapOlRPDo9PZnvVe8UjZleizhHz+YjAg6J0ZzqMz6qFI1MSOdQKBHwaGSuAwABdzAj3T8sUHOksM6R4Kg1o0cJ4ab3OVRYOYkRNL98+/ff7Om3HOKcM/sVADLuZGn7WjSxwWqILQTKwjXvH0XumcBaLZjK5ouNo75gcHgjtAzHmtWdLVi3ZXQrkSciYzVOxjJ6rJiy1DCntZrNUl3+L0Muy8I1H6arO1v2e86W9i54Or8mEdXQpHKOQkHRyCrI0wp8EmJT0ISW1G4McDm3jguCKc4AWlK9xqBdij1knQoyToC+MI2IM2RZBQ6N0ZLuQ4NbgktiI2BiUBONIFtv8o0/EEwls3Plb+LD2n06tkCPyHAToki3++TfXK1oqt5XjUtVO5DIffg0BAdBd6Vems0Jh0PimqoXV14Uva2ab/pCVqpmZnbXVJ4iThFyZsbCjGQiT4oozUiz9fTpntNvwW8W3zqs5Wg5/Fk8a4NZiaf/Lyjk/E0KLudYqkUYAzyFgvBQ5B5Wbp5tYhL0sHMPMXwy/mLqsPRLWSYUVkxZ9ogu3fs0hE9DZGkFYSKE0iPxfvunFrRtxfw2Wa7X4oACKAggr9pLRc4wmcpqVYu72wRjDnAfZeFiY6UJZe6izinDITEKsYdS7KLBLSLvVOSA4jhl/EY5E9QpM3KSLbfkaBhfDS1OCihGdKaOMNUrAOY8jRZ2eh9JD5X+Xd7XartMj7XRmVV5Rx6nfuxHfG4SMQlUjcbRx+nQ2ERGDK1qiSGtPb0t7alK3mboOBqNQzkuefyTAIC7Tvvemz3VlsMQ8yVEDTIvCs+0rLX30EVcE+ipW/s6e8pVK4TdA5QceVi2B60BfcJgxZRlGHr1DYVcXSfN4BUUeAoMAnVEZiOdOmvjqL9VhoKqcSsEHEBWfdYHYOjnKeyIpXDaFeVMOvpAnDaepE3FyahzyugJssiyAIwI9Ee+TAenITzVMtOeoElOERlWgU9D5FgZDaxYM9ZFRyFcdNQziEFN266m2pSoVCVbfwBMS1Cv8qOJUENdoQrVDEEt4njCo6YzqBgRsiUZ5NVl1OxPt0dc9YHk0FiOz1GtyoHIR5M/UBO4qduKZASBlUwvT+ZNARjWEtQtQyuijmz0VAM921PP3/RJaFb9AVDnVT2HZeHCQ4wMDdFAAzTQcNxCPI8IBAA+ipPVUmOGzZmyjEiGhshADvAtQyBQAqAgPLgiHpbOvb/INHBpSKcAXEKwK6aYTCvYIQgaaAXbY4Y2dxc6w8ngoGj1duG1yjQUuWzr6VV+Lo1RjD30hNmafeiKkM6oCgVDm98Dn4RmhV9SNHFBcff6RWCAyp7SVR+OcIS2FtNLwuFggPvI0EBVmqrDXvV9hai2BGkiBd2lsbmeS0IAYc23eqqTyYlAXPNtkgOq9efQGFRwY7gfZhxPVJz0eSPlRSWrZskhxUlz+UUrPoX/XnzbXjzDlsMZbTYHkKi6yvO0d6ogmBwrQzh8UjKDjmty7Q4SazqbEYDuU8TCRGK0vifrmRo7bGXKMiL6zcUn8ltkllbgq1VpgBQQqztbwCBGNWJGmlZrX4Y+4SgoA3xZMGSpzJ1q93YgFAw9UQ7TnH7MTu3AMdlu2VIjAvP8bZjh9SFNQzDIChVQO5A4RSNMdgvwSTRsTl5PlEVFuAjUKBctGHX7zRhtiTC5U4D8QNHp6E3OAHwSDGv/aSiRyeiDKg1dj6DRVark/rhqGcbJ+AK1XX3S42tqvFiEoxS7mJffjil+QW5/hFwpoHbFpvZNJRPdk7f54IpPm9+tkLIAwCkzN+H4mZ04ddZGVS2VhnIuiPEf6rgTD3Fi1a6ATw6ukAKA+W1d5r1uX1cVWixJrJiy7JFj27aAEiluGmgFDSpLqSwcs9pvtJ6HBW1b4aqQUJ8QlAVHE2Vmn3p2n09CEy8w3e1DnpWQZ2Wc4Hfg6NQ2zPVfRywIuoN6VLiDwdhDWs3l02JLRyNUuFPTnhuIfXBQU1GSaeMy0VxXrACoVX+iZmafbuv1xhkzz89Vc8mGmtY9dZ4WdVrIJMfU6GR0LbIqat6g8WGpVX9ANSYBqLb/tLiSgspDo1vEVH8QLotrKlIAECduH/OqgKOoHSWTxAZyWvYEg6xk6ta/HhKeoYFp5blEzuF0lYjK04nzEXTKzE0ADswQ5jFDYJSeqYN9Bw4fJs4r2TIhObq1C0e3diVGQFQ/tLXfabQvoqNbuzCntRvTW7pQT1xQEDRSOiwtOU/LWJDqgk8CFHkKA7GP7bH0FFFwbKxMNceVVvP5AOk3qnDH5DhpgaCn28egKHBZKUq21oBqDhRXaehaXOmqVKAFmnBNZUmKNkeNkJGr++Tw5NqE9HqnZGISdNUr5MyY0UPBkFY+MEdV1qqtFJl+ftMJv6p6woYIKko4Stw1MwoBwGeyJRNzavxTXBD5O0RNpWrYjD4IZBIp6BbLUPJqIYRs38tZn1kSoonJBRG6GuUTggEODPCJN8/k1FkbD/Yh7D3WgD5hsGLKslfoKpQmVPPoxnolzk4egkOAm3aizJ2aTMtoYrJ608iKaGBF9MTSG5UlAVrc3ViY7kSkqkcRZ4gERV+YNt4NXeWRQ4wZKtxFKBxwk4uTqmlxacN7IJjMoBK1bUGgKqrcxLfxGBR5VoKnVvEBMEJLX8dVHzqyslc1wGdYULMtHeUQqdZjKJipbnFQfG7Vh2purx8zN7G/vFMGUBVHWlBp9Io9lgj71D6podWsn5/6gzd+Ai1HLAvatiJUrxcPHD7h8Ek8zBeVIQSMENTbTx/LYYR9OVv2imTA3rAP7zFcjKNzrigIGpkchkwJkCICTA1N9RCjkQ7i5PRGPFOYjVeDGeiNM+iNs3hLugshZxiIUsZMPRD5KEQp2f6iXFVg5Eu/yD3Z5hMUGVqRSehKKA5NRZf3dbh4jNVtdXXJG/b46CyqSO1TBoJWjelytV8x9ox3yqehEl2xar1VoxW0n0tnUFVN6klPVHV2nqvGwmQcKUb5CKun9NgZn0XwWAyHcPgshEdj3HP6LaAQ8FiEi1Z8aj+eVcuRBCUwX7LkdAP5/zCZ6kUeFGXBwYhdxTdqRrOST58sY4JdzWfZK+a3dckEYSLzn1zT0iI1Y0jGgrKI4RKKFBhchGikLnp4iB0xg09iDHAPReFha9iI2akdeD2sB1ygJ86iwl2cUrcRT/XPBiUcTd4gAKAUe+gJspjh9yEUDBlSQZF7Rojon3lWqs4YU7P1YlAEPAWfhojVXdU5VLqNp7cRQ3utqAompGr4q2w5xkL+naFAX5xGX5QBF8SMj5Ez+5jxb5W5awSUXk3I1HYBmaAecrdG8Gk/mPZllbgMW9Wz9bggcFU4qkfjmnaeo6IW5LY5PCe2K/cs+4weZu4qvcQIEAjZ3uMQcJOLHA7gca3pbDb5dvvKUx3txlc1UbCr+SYOtjJl2WtcCNN2qyMBfBKp1XZj+zKa3tIFDoEQHCEIQnDkKUOeRmqFnyuH+qow0bXFaXh2cBaa3V4MxD6eGZiFE+s2Y1a6Bz1hFqFgGIw9UJWSXuEO+qIMqPIqlbmL7WHdsJEwGn2+Fiw1OVOJ1XWhcFDWrUPls9K3cxOeJ22G15WpFI1M268Ye7KyFvs1FSe9P3lfZMQDF7JS51IpgLRPSsNNNAMx7b2MExoBpdt9uq2nhZQecOyoqljOLeOjT16Bjz31sTF9ni2HH/PbuozPEgBCEDACMBD4RL8eBXzC4IKO2wfQpi0zhp33YmfrfgspQBrUV2yeM5rDshzG2MqUZa/xCEEgqrlQWcRS7KgvNxu2zKgZRzMaXFC4hIIhRig4+jiUZ0hWfMrCN5EHb69bj4E4jY2VJjQ6hZo2JIXAFHcQOVbBhuIU9IQZ5AVFg1sCFxS7wixaUr1mZp6uskmPlKtW71HIL9LVkTE6jJOBI1DiiRIOD8ODPMvCNblTjHBASD9UnpVrRsNM9frBBcX2sM6sstHhn1yJrwwLhs/HQwxACz65Pf3Y6IT1oZlRDjgiQeGodqCjhFhtAjo1sw8BbkfHWPYJLVxWd7aodp88nwKIIdv2TczDjnhsFzUUumeNeP5YZEktnrVh1NsYU0ZrIreVqTHDVqYse00vr5bmuZCl/AAUA0o7jIWQ2rBlBnZ1tQIAQsHhE4I+DgRKSAFyhV2WykT23jiDaU4fUjTE9iCPelZEb5jBK4UZ6roEO8McesMMPBoh75TRF6bxeiWPrZUGk4eToQHqWVG22UBRES64MqBrdLaUHm6s0W1Bj8TGeA5UhyHryAQ9lwyQj12RexiMfIRcjudJmtvTqs2XUpEJMhW9KtIiwaqz9wRDilTHzugKWrKypatRgPRHJT1SemBxUlTJ7eoVjFKQJYcaWyx7y4K2rcgTYIDLcVGA/N8OwbEjDhCOcQL663EADvleMl7s7xitMceu5pswWDFl2WuSM/TGY57Wpi0zUE8ZOATKIgYFQVlVwjxwBKh6tQo8BY9EmO70ooEW0eT0q+XYMXrCDFzCUYw9UAhTUXGJXqFGkWMBJjlFpGiEwdjH7igLRjjytFwT0AnAjIWp/l2NSAiEo65PTLZUVTBJ/5RPQxTV8NeKcOGRCHlaxlS3H1PcQdQ7RWRoYKIgUiREhlVM66/MXROfkKIh8qyMHCublX+O8lTpSlQyxFMPkJ6cGoRHdfK6QM6twGchHBojwwJ4al8m+4rGyLIADolVu4+OaL63WPaGovrQ1mOjAKCXCyOk1m3Z/+Dfoej/3PEcU3PizI6JI6gsEwIrpix7TZ7E8Agxq/e4qI6E0B6FBzfN3+/ta3MqADBCUEGMacwzCel1JIAHjkZWRB0tY77XjelOH4rCw3TWh7dmtmJ1qQXvm7wKs9I7zViVEnfRH/koxS4KUQqTvAJiEFSEiwp3kGNlUIjEOJfEHD4izPBjPTZmaJCnDvNMEis/UyAYPBXKSSHF2lDDvjbC6wqZq0SPTyJZMXOK6lg4Qu4gRUOkaJjIrZLRCXrcjGtWTWnxpOansdDkXcnnT1f6CFzCkWUB0iyUohPCtP0CPZ7GJvxZ9pM5rd3IUIEGKhBDoIcTlAVFKEiNx2qsWbeleUyFWpKDnd4OwFamJhCHjJj6xje+gcWLFyOTyaChoWGvbnP55ZeDEFJzevvb3z6+B3oYw4h8wTAzR0+Yk/6G+Y72NQCk2XNfCTF07pw2q3JQAkxhFJTIDJs8LcsIARIhEA52xHm0ubuQpgFiUAzGPrpKDTXb4iCIBMXuIIu+MI3+0EedUzZm9iytoKx8UlpQaQHFhggo2QKk1bEuyWoUqcYY6NYeBTe+KrmarwKfhKhnRdSzEnwiZ/EVuYd6VkKTM2BWCVZH4ciKlTHCq7T0UDDp4dLHIEjC/8RNG6/V343/XnybMZbrdp5DuPSiJYYuJ6MVPCpH73z/5DutCd2y38QCaG7pQpFXM+sWtG0d131yIU/jwfEzO8dnw/uCjUaYMBwyYioIAlx00UX41Kf2Lefm/PPPR3d3tzn94Q9/GKcjPLzZsGWGWc5MIc3oPiFwIcwbVvIb4P6YPX2iZ+EJ9Kp3wApiTKEuAICrlpU0s0aYTMsIBUMdLaOJDQAAWr0e9ERZzHB7UY4dbC3WYyD01XGLGhN1IfbQG2awO8rI6hThyNCKzLJSQkqnmGv0WBctdLRQ2hNUGciztGICNz0lspgSL9K35SDPysjTMupZEYFwUBbyfieT4IeGhurEdG00z7EyMjSQKwRJDJdWj3/obfWqPRmXQFGKPXjKG5U0uUecwaMRrnn20powUItlX1m3pdnMwxuP4cKbtswAI1X/5tCw4cMNHY0wmpNlbDhkxNQ///M/43Of+xyOPfbYfbpdKpXC9OnTzamxsXGcjvDwpp4yuKT25eImWn50DN6vmpq3qu1SZIkUVbEQKIoIDZTABUUjdZCn1LxJNtAKenkGReFhW9SAZnc3MjTAAPdBicCMTD88GsGlMSI1ew6AmUEHAC2p3QgFw0CcNpUol0QmSwrAEEHFazxVSZIVLEakcCrwasaUJkhEI+iqk66G6bafr0zlZeHUrFDUidKUcGNMl4noxAR9ZpgUVFrs6XDPG166YNjcvWSIZyl2EXGGUuzi1hN/hlLsgoMgUPMMv3/ynfv8vFosANDe2j1u7bwkOgvu6Nauw1pIWSYWh4yY2l8efvhhTJ06FfPmzcPHP/5xbN++/Q2vX6lU0N/fX3OyVNGpxRRS7IQCiarJ6N+4prd0oSI4mlu6ECb8UxTVk65aac9CIBjWVaYrISLDNZvdXuTcCgZCHykWYSD04RCOYuTW7E+PmgGkqNBhmIyIYavyku08eX1qWn56dR+FgIvYCCGgmoieoRVVRRo+YsZT/qgMraDJGUAjG0Selc12tJGcqfT25IeETk0PVdVNVqZCM3ImVONwAGlmb0vvhs9C482qxiJI0aXjEK58+nJznzwaDatsWSwTjfbWbrSrqtS6Lc3wwLGgbSue72g7yEc2TljP1IThsBZT73rXu/Dzn/8cDz74IP793/8dTz31FN7xjnegUqns8TY33ngj6uvrzamt7TD9J9wHHti4AM9W8gjF8BYPBZAh3GTIaEYzeT2GGNJWVNUkHeQpiIllAIDjvG4szryGIvfQ5PSjgRWwqjATpze8htnZnXBIDJ+FSLMQDalSNQaAxkgzmXJe5B4KasxLnpbhkgg+CVS2VW0cW5m7KPIUCjyFsvBQ5lWBpqtRjHCoYTTmslA4GODphEijxq+VoQHyrJTYjkCZu/BpiCZnwIgjoJpjJWcLMlS4Y0bfxMr75Ks2ZCwIClHKtDcjwRAJhrmZHWj1dyPrVJSPixvjecQZHBLDo9GwSIRPP/sP+/28WiwHkqNbu0zWlUv4fvk494bxjGB4U7THYjQny5hwUMXUDTfcMMwgPvT09NNP7/f2L7nkErz73e/GwoUL8d73vhd//OMfsXbtWvz+97/f422+8pWvoK+vz5w6OyeAyfAgo9thLwb1eDHI4cWgHs8HDQBgVvfFqmqi31hGM3m9raUbc1q7Mb2ly7QWWUJQNVKByZQjT2K4RIASYEecQz2Tq97K3MVR/nYs3300NhcbEQkGl8aYlupH3inDUSvXGtyqeNHttQHuoyhScBHLME49TkaZvLmai1cWLspcngo8VZ3pl6ga6cBN3Wab7AyafCyPxMjSCrLKiK49WJ6KOShyz7TvACmcdLAoF1TNEpQr/Sa5BWRoIMffgKAYp0wVKUUjZJ1KjSBySIyvvfV+hJxheqofDW4Jrf7u6vNtxFUMV60EZGYFoG2bWA4tVne2IFQt/vGoUM1p7R4xcd1yZHFQE9CvvvpqfOhDH3rD67S3t4/Z/mbMmIFZs2Zh3bp1e7xOKpVCKpUas30e6izbeIxpR8WJVWQQ1AiqsvAQCIZQODg2NXarczq3zkBbSzf6u2aayAQKAkqIElcxYgi5Ssjphx9HZiDwS4VWFVTJVQaUyqeKUuAgaGABuCCoc8oAZEwAg0CBp1AviqBwVXJ5hDJPq/l6rKYSxUFMi03+TcFBoJth2nDOCDdVIwDwiUx81kOUYzXHjwsp2uT9FCjy6uDjjDKwg8C0ChkEUjREX5xWaeySgdiXQoxG8NVw6IpwVao7gUOAr73wAVCV7j7JKSLDKkjRyMRJaPGV/OLK1Vgai+VQQq8YHK2Q0l8URwonbh+jyQ/7jE1AnzAcVDE1ZcoUTJky5YDtb9euXejs7MSMGfZbxN5yzuxXAMj8KKY+wGMQI6i0eVkv1381mIYdm+YjFtTcdn9pa5FvUIMigqu8WikwMELQx0M1lkLiE44GWkJBuGigRcxJ78ATvXMw3e8DJQItqd3YUGqS8QicoT/y0eQNortcj4rnYJJThEsj9EUZ+CSUq/qIgE9LyNMSysIDV0nmSQO6FlK69ZbMYqoOPZbjWLSo0snqWmi5kG29WJnfC1xWloo8Jdt70BENctwNJ9TsTwo2Aei/1cw+3e5zSQxKBcCBmFAz6JgRHUYqj7cYpzA9JZPkufKRfe2t9+Nzqz6knl+CFOG4edEv8clnLsP3TvrpqJ5bi+Vg8WJn636tJBwqotZtaT4ghvo3ZrS+JyumxopDxjPV0dGBVatWoaOjA3EcY9WqVVi1ahUGBwfNdd7ylrfgnnvuAQAMDg7iC1/4Ah5//HFs2rQJDz/8MN773vdiypQpeP/733+w7sYhyzva1wxL1dYfxi6J4NNqq6rAU6MWUkmaW7oQCoEMceASBgcM9dQddj2XcJSFi16ewbP9M1GMXGwYnIITsh3YWpmEHKug3i3BZ9LUvSPIoRh5AKQo6SpPMqnjoXDMyrya8MtEZSYW1KzUK3MXFBwhWLXdpzxRepWdTyK4iNHE+pGlFeRpWbb51GPn0xCMCHkZKyNDh3v7km225MBlGRkRI8MqmOQW1HWrgi9F9XNUHbZstjMk7iBFZf7VrWvOxsxUD1wSS6O9oPj0s/9ghZTlkERXp8eqVT2SkOrcar+oH6kcMoOOv/71r+POO6vLshctWgQAeOihh3DWWWcBANasWYO+vj4AAGMML774In7yk5+gt7cXM2bMwNlnn4277roL+Xz+gB//4cDS9rV4ZNM84x2Sgkp+0AaqpSX9PmPfJm1u6cKOrhZkiIOiiJEhOoNJxQQAKIPChVzBdnHTk2CEY1eUwwBP4+j06wgFw2DsYzOfjL4wjampATR5g6h3SihzF4Oxh+1BHerTMkRTZ0QBsjUXCke16DxTmcoqwVMRrgrRdGoqUCHYsLgEN2kQBwEVwlT4YnAEcI2hXHufktsxVTAiqllYStRSIlDhbk31yuwbkFUq1MYh6ONK0VAJ5apXq54V0ZgZxEDsY0vQiP7Ix12vnYJL5j416ufUcniyv5Wf8WZB21a82Nk6rr6/tpZurH512rhtfxi2zTdhOGTE1B133IE77rjjDa8jEi+MdDqNBx54YJyP6sjDJHmrnwDgIlahlA5CTkesqIwFBc7R1LoZGDIVXmZOSZhKGF9dbkGb26MEUIjVpRZM93qRoQHSLECFO+gN0wgFxRR3EC6TZut6p2RECxcUZe6aag4joqY9B0hREggHWRX26RJ5310SwiehSicXypguKXIvkZhe9UhxEHgkgh7kzAjHQOzLmX7claNm1Fw/LYbK3EUjK6AvzkiPF2LT3tOPTRJThRqSk6WFlxZkuuqoW5oZGmCu/zpSJLRCyvKGTEQhpTkQx9bavA5A/bjvB4AyNY5CENnVfGPGIdPmsxx8Htw0H0vaXzNCoBoIyc0cOgB475wXxmX/2uSZnbEZj5V9PB804MWgAS4EXMhhyA20giwJcKzfCUo4pru9WFuejuleL57vb8Oa4jQpcFT6uKvylXKsjGOy3Zjp7UKeyWHHA9zHAE+jN87AU14mDVUDjDM0QAMrokGtJNSxCMzkTclQzRAMZeGqfaqhwsqUzkEQKlGlzeh6BqCvqkWhYIhBzIo93UIEZItSjrwRZqVfioY1A491jpQWWrqdCVTH1ej2n0eqlwHVVYl6xaDFYrFYajlkKlOWg4+euwfU+mx0KypLK3ARD7vdWPLIpnlY2r4WAIyX5/lgmjKGC/THPrK0gg3BVOwM83h//TN4W3Y9Xim3IOtUUOEO6pwyAuKAQiDFIuwOs+AOxQx3N3waYkdUh91RFqFgyLEypjl9iEHR5uxCCIZtUYMagBwgT8tm/p4WRFLcBPJ8EsmYA3CzEi8W1IirXVEOWVpBDApPjanhoCY0NBRysLHLPWRoYAQUJTHKwkVPlAMHwWDso8XbjVj5s/TqRKiFApqqUR5gtCq0dHvPtBLVfmJB4ZJI3ReZoXXvhhNwwZxV4/o8WyyWvUBweRrN7S1jgq1MWfaZJe2vAaga0V3IbKRkeKXmvg3Hjem+tZACqiLOJ7JiEguCOlZGKBw0OQM4Jt2FlystWDE4Dy6JMT3VjzSTrbeCMp7vqOQQCobOciN64hy4oPCInHFXjOV1OCg6g8koCg9ZEmAyG8BkNmCGLdcYz0HgK0GkTd4yADSqppmrQM8sCTDd6YNPQyPIgGrFzyWRyaGqZ8Vq+xEEO6M81pWmYUeQx4v9LYgFMZ4nXcXSz1GyKpXMjKpJUVfp73GiWsb1qk2Fznq3QspimSDYBPQJg61MWfaLxbM24KmOdmPmdBGDUT7M2JwcqzJWrNg8Bx5xEAhm9qdN06FgGOA+8rSM54qz0Or1oBI72I46tKd2oC9KoxS7OCa3Dc/3t4JCYHM8GXm3jFUDbZiWakBPkDXBlYOxjwwNkKUVBELuM0MC4xcLBFOtOFl5ksci36B2xDkzWoaCIxAufBKirH9yV1aouGtS1rUolFEJch8cxPiYtgSNmOIOIBQMEWcIBcXRue2y/SeIEZguiU2VSn9j0qv7hgqt5DFzQQBSjXSgajCzSyJVLattAVosloOI9UxNGGxlyrLfnDJzk/mQB6qtoUc2zTPXGcuIBI30C3FjkjZZSTwFRoRpy831X0ejU0Cb34NJTgE7ozyO8rejwS3BpRG4IPCYHJcScoZilJJBnm4ZXFBUuINdQQ4vFVrw9MBs3NezCL/vPwH39p2E+/oW4Y/9x+GB/uNwd+8p5rgGuI9enkZZuMiqVp/2HOmTvq5HZHWqgRXR5PQjz0oIBEOBp7ArymFzMAU7ojx6ohwqKmk9wyrDViMxyJV4A9xHPSsaIZVs3elhysnqlEti81NvR3umdOSFR2JcMvcpuCTGBXNW4bzZq8f8+bRYLIcGN954I0455RTk83lMnToVF154IdasWVNznRtuuAFvectbkM1mMWnSJLzzne/EypUra65TqVRwzTXXYMqUKchms3jf+96HLVsm7sKFvcGKKcuoOGXmJrXUPzRCQRvRATnX7w8bF47pPpe0v4Yl7a+ZrCstqvQqwlAwZGlFGqZJgBwrI0Plzy1BI57vbUFnuRFH5+TQawqBSFVtdAJ4KXbh0KooKXEXaaaSy1WSuLwth0Ni/K7vRPyp/zg8Njgfjw68Bff1LcJjhXn4y8Bb8bu+E/H7vhPw0MACmWieaLNVh0QzE7eg/87QoOqZUhWhYpxCWbhI0RBtfg9mpXdhME6psE4p5jK0YsJVY9VurOZRyfahXLXHlXGdV1fxoZodxki1cvXeOS/gv9efNKbPo8ViGSUHuM33yCOP4KqrrsITTzyBZcuWIYoinHvuuSgUCuY68+bNw3e/+128+OKLeOyxx9De3o5zzz0XO3bsMNe59tprcc899+BXv/oVHnvsMQwODuI973kP4nh8PbfjCRHCNk3fiP7+ftTX16Ovrw91dXUH+3AmLMs3zQVXM+xCMPgkxDva1+CBjQuwPpiGBlbE/5y7cszNy49smlcjSALhgINiV5Qz5zHCUeApuCRGd9CAUMgE9EKUQiQoIs7g0QiRoKh3S8g5AV4v59UQYIGAS7N61pGp6CFXAoXINpgMtCTIMWkkN5UewtEXpc1KOaCail4RVX9ZchuUCHBB0B/5KMcufBYixwI1W4xiXnabyZTSOVS6fTfD3W1WCOoEdapWWg4dA6P3pbPBNB6JEqv7pND6wFHPjdnzZbEc7hyIzwy9j3fO+AQc6u33diIe4C/d/7Xfx7pjxw5MnToVjzzyCM4888w3PNa//OUv+Lu/+zv09fWhqakJP/3pT3HJJZcAALq6utDW1oY//OEPOO+88/b7/hxMrGfKMiYsaX8ND26abzxMoWB4cNN8FLiMFdBenrE2L2tD+oOb5oNCmAiDBlZAqDxOjAi8WGjFnPQOGWdAKnhq10w4lGPRpC3oLE2CQ2NQIUCVWBqMUkixCDEnSNHIiBwpiqQAq2hPEpG3K3IPEWdIs8CIl3pHDlPWAicSDBXhmMyqiDNUuIOsI6tq+u8cC5BjAUrK1O8SjpgIvDjQqqIc9Hw/gu5SPXwWotNrxJz0DmwqT8ac9A7zPIRgZpWlbvn5icHHyZBO7ZHSFanYFq8tlsOe/v7+mr/3dkatDslubGwc8fIgCPD9738f9fX1OP744wEAzzzzDMIwxLnnnmuu19zcjIULF2LFihWHrJiy75SWMYWiWu0oC1cJGgcUHHe9dsq47FN7tHSbkRGBUDhGCISC4dT8BvgkxIpdc7C+OBUzc7txfMNWVLgDh3BEXFaGCpF8A5mcKmAg9AFI47aOG6hwRyWpV78NMiW0uJBtu1LsGV9TLGpXOepBzNLzJRCqbcrbU5S4a86jhCPLpMiqDjaOpLACMUJrcqqAiDOkWIQXBlvQ5vcYj5RPQtNWTI6R0eGmVd8ZN8Gk5n4lohLu3XDCGD5jFotlTBijNl9bWxvq6+vN6cYbb9yLXQtcd911OOOMM7BwYa2V4/7770cul4Pv+7jpppuwbNkyM4d327Zt8DwPkyZNqrnNtGnTsG3btjF6YA48tjJlGTPe0b4GyzYeY/6WUQFquC4ognFqKOsxNzGIMaN3hZPQ7O5GrFqOXeEkPNs/ExwEGwcakXFCDIY+eippTE0PylYfixDEDgo0JatcNELAHaQcaUjvDdNIsxAOjTEY+iZmgQpRs7puslc0lawYFJGqyskVf2qFniCg4Eiz0FS2XCp9TKXYw0CUQopKc3xv6KPOKQMAHBqjL0wjiwCxEn9Zp6JM9BRN3iBW7p6Dsye/Ck+1AgEYERUKBhD53OifTM0c1KNpzLEmsHEIFssEhHMAo8iK4vK2nZ2dNW2+valKXX311XjhhRfw2GOPDbvs7LPPxqpVq7Bz50784Ac/wMUXX4yVK1di6tSpe9yeEAKEjN+on/HGVqYsY8o5s1+RfpshbaVQMOyM6sbNxLy0fa0RBj4JMDe1zQRgBoJhXWkqTmtYD4/GqPMqyLkV7ChlMcWXyeUOjeEQDofGqMTyO0YkqKxaCQaHxmhwS2Zo8SSvqKpEcc3quhyTIqfCHdn2U0IqeR39ezWHqtpyo0TnQgn0Rz4iztDgFtETZtTjKZB3yugL03L/NEbAHdS7JfRHPvojH83pXgBAilQHG3sq54qBo8JdDHAfBZ6SsQvKsyW3X63u6ZPFYjm8qaurqzm9mZi65ppr8Lvf/Q4PPfQQWltbh12ezWYxd+5cvP3tb8ePfvQjOI6DH/3oRwCA6dOnIwgC7N69u+Y227dvx7RpB3Cu4RhjxZRlzHlH+xp4CcP1ziiP18N6ZGjFmKXHg3Nmv2JEnK7K5GkJFeEiRaWYOK/pZcxI96GnksGSqevRltmNYuQp0SS9UABQiOV5AWfIsgoiLgWVRyO4lKPBLSJDpW9Jm8fl/ZXtPi1CQl6tDIWCmTYhAOPB0m1BnS/lEg6HcPQGaWM8D2LHtBa5MspHgsEhtatfIrWP7qBBJanzGkO5zrMqcg+DsY+eKGfmF8r74sg2rTqeWBy63xQthzYbtsyo+WkZgQO8mk8Igauvvhp33303HnzwQcyePXuvb1epSMvCSSedBNd1sWzZMnN5d3c3XnrpJSxevHifjmciYcWUZVxY2r7W+HJ0LAEjfNwNzXJ2oKhJHE+RECdmN4ERjt1RFkent+OC6c+j3imCgiPnyn9yh3BwQZBiMmfJoTHq3RJCIf1ILolR55TNar6KcKur/Ug19JILilh5qPTvAMwKQAAmIZ0SgTq3bNqEuwJZgUrRCI2p6nLjyalBtR9u2n9aSDkkRoU7KMcuBkLfVMy0aEui4xB8EiFFQ+mrUvP2dEq6TkLXWL+U5UAwVDSFgmDDlhmY09ptBdWeOMBi6qqrrsLPfvYz/OIXv0A+n8e2bduwbds2lEpyoU2hUMBXv/pVPPHEE9i8eTOeffZZXHnlldiyZQsuuugiAEB9fT2uuOIKfP7zn8df//pXPPfcc/iHf/gHHHvssXjnO9855g/RgcKKKcu4odtKA7GPwVi2lWJB8IvXTh33/QLVZf51TM7PK6ioAC0ytgd1eGrXTHiJob8ei1CKpUhK0QhcUORYBZXYQY5V4JIYaRYiEgwhr1aykm28Zn+3qUCFgtYa1BNVK32ehhLpoYpBpOFcVal09EO9WzLXk5UmrozqQu1D+tO6Sg0YjFMmt8pVj4NHYjSyQbgkxhSnHz4JkaVVg7s8JppISpc/rV/KMpZ0bW02v2/aMgOdW2dg05YZcAnM7xu2zMD8ti4Aw0XWpj0Iqz2dbxk7brvtNvT19eGss87CjBkzzOmuu+4CADDG8Oqrr+KDH/wg5s2bh/e85z3YsWMHli9fjre+9a1mOzfddBMuvPBCXHzxxTj99NORyWRw3333gbHhXwAPFWzO1Jtgc6ZGxx82LsSacjOKXLaojvG3mqG+4/kh/cimeSirFX0DcRqADBN9pO8tODa3BU/0zgElAoNhCj6LEHCGyamCmdlHiZDmcLWCrs4pwVVxAnp1HhcEvWEGlHAjQFI0Mq0+SoRZQeeq6tHQvCdAeqYG45QSb9JvFQmGtEosL8UeHBqjFLtoUIJKizC9AtCjUgTK7Cvpu1qU64BPQ5V0XmsuT85S1FEIQ0WUvs1FRz0z9k+Q5bBlw5YZNXMf9WpSnxAEiY8bRoA48e/gKfNxQQA+EQjVZclv/NpqPae12+wr+fcb0bl1Btpa3vx6o+WA5kw1fmz0OVM9t9vPtzHAVqYs4woDR6u3C7GgmOntBICa1td4URCeaveFKkhTJnqfkOvAk32z8bb6TTitfj3eO/V5LJ70GhzCUYg8DIYpeDRpCOcIBcW89DY5pkVQZGigjNyOzKciwiSmhwlPmBZGejWj9kxx0wIkxnyeYaF5bCgRpoUn/5YfIUkhpStIlHBTWUuzEKXYBQdBkzeIogoqTQopzxjS4+qA5SFCKtkeHE+Pm+XwY9OWGSgLilAQlAUFF0BZULgECISARwgYkUKKQf4OyL/1K00LqQwhmNPaDUaAUF3XVaekiNobIQXggAipA40QfNQny9hg3ykt40oMip4oh1avRw4EVgN8tU9nvPj72S8BkObwyWzAnF8WLs5tfBlTnH50VCZj2a63YntQh95Arpyb4g+CKgN4rESLSzjWlqbLKhH3zODhOqdsvnVroaPRfigd+BmbSlJiGDHl4KBmaLK8HVcJ5zo0M/ENPxFvEAqq2oHCeKR0C7IUy4rTzjCHgdgfFncgs6W4EVlJsQXILKxYxTpYLHtD59YZWNPZjKJ6XerXLSWyMqWrTIGo/q7RFakQAhRSZPmEgKPaEnSHDPPVLcEkG1R7MGlcH6n1t6az+fDxYAkhhxXv78k2psYMmzNlGVcGYjlO5flCG5bWvarCISNkSTDu+/ZIjLJavSaH/0ZodnvBwNEVTgIHRU8ljScrsxDGDD2VNBwaw2chUjRCqCo/MQj6o7QUSGp2HQhHyBko4egPM2ZuXyn2lIDiRhCxhJiqcJl+zqhALETNZbp1F6rqlEYLMgqOGHLlYCQYPFL1emnfVBgyHJ3dDgqBHWEePU4WMSimO71m/I08JiWehryXxoLIFX2EgwsgxKHrYbCML6s7W8zsSpdUX7sxCFzCkSVKjpOqYAKAGAJMiS0GoiS7/MkB81Nf19xOyO3ESpxRSGHkEjFM9mvj+rotzVi3perR4gKY39aFdVukoKIA2veysmWxvBFWTFnGFUo4usMGnJzbiBgUWVIBI9yMgRlPlravxYOb5iMWFD4JwZVXq8xdZGgFmwuNWFC/zQw3XtffhOl+P14baELGCVHvlpBW7bfeUAqtFI3AQdAXpY34yToV87tLYyOkdF6UjkfQFSeHxjWVIKDautO3rXAHHET5pqqrALUp3VXtRwDV4E4So8EtYlulzvi0NpcmY1GuY8S8KEa4yeHiorqCjxGOWFBwEFw5b/lYPy2WQ5wXO2WukGkBExhRTomACw7XvF7l+fEQ1T7UB+USglhURVH1crUB1foLhDCCCwBcIgd6hwJG2OnzZfWJgA956a/pbDbmdgBYt6UZLsShKaqEwLBvRPt8e8tYYOv4lnGFgWOe340srSBLKzhv9mrTgjsQ+ET6gkIw5GkJsSAY4D4GuI+jcjvQE2ThKpM3F3IO34x0PwKVZl7hDgpRCq6KTfBpiDJ35fgWGslKE4Qamixzn6Iaz1HVKA7AtOR05UnP56v6qXQuFYej/ExaCOnqVIpFSLFqVSpFIyWyZGZVJBgC7qCjKOdllYU7okct+TwkxV2ZuwgFQ5m7uPnVQ3epsmXseb6jDWXhYIB7KKhoEJb4MGeQf2sBEwvpVUr6lVhN61pWpCgIGKk9AVKEBUIYo3pFEPOhJUWYbAGmiDDCyrQY1fXoCPbMZMXq6NYutLd2o3PrjJqVhocEnI/+ZBkTbGXKMq584KjnTHXonNmvHPD9L561ASs2z4Gv3mB9GiIvyqhnRRTjFGame7B2cBr6Q5n4W4pdM3R4d5CRgZkq/mBaqh8ZGqAvSpsZfGkWmmwqAGZIMVBNONdjZpKr+4CRU9FjSHGlq1qADP50KTfb19Uy/dOhscm1anCL2FpuAAA0eEXUOWU83dcOvyHEdFcOJdVJ8dV9q3ZmwiivGTpWxnJkoqtRBeGhwFPI0grytDpsGwA88JqKz1DaWrprxAojBGXB4RNqBBYfUmVhIAARKAvdThRmFSBFtfUXCAEXqmql/q04pLiT3kIYgUeJzLBiEFjTqTxZqlXY1tqFTVtmIFQVrTe6PxZLEiumLOPOO9rXHNT9l4Vb49FyWYwdcR0anUE0OQPIOWX4JMLrYR0KUQqbCpOQcQJknADFyEPOLaPOKZuVd71hWo6NAUEYu9K/pFbUDYQ+SsRFmoYmNT02/hChKk/cGNQlHFS9eXNB4KgRMR6ROVcpFsFRY2v6Izl8ebJbMMGcOvMqFAw5VkEx8uDRGC1+LzgozmhYh+6wARlaQR0rq/ExjgnjDASDr8SVFlIjRThYjkxe7GxFKCjKwkEoHMx0+sxlMQgWtG3dq+10bp2R8EhJtIgK1f8ATVStQAAuhDKkS0HlQsAFQQgBX/mngGo7MTVEjHFUhRMghdTRrV3mPlEi4EFnuQljTD+6VfqqNm2ZMbHbf7bNN2GwYspy2POO9jV4cNN8NNASXCFXvTWxftPyk9WmDPKsjP7Ix4x0H9IsRE+QRWtmN9b2T8XkejnDb3tYZ1pxuyo5TPIKZvWchkJgUBvRhVydByLNuW6i4pQM72QQYCqjikFGI0ScgRMORxA46sNiMPQx2SuCqfBRnV+VohF6wwzqnRJmpPvQXapHb5hBkzcAn4Zo9XrAiEAgGBiqkQyAlHJFnqqa6wFUuAuXRLj6LQ+O63Njmbh0bp2BslqQEAqGLAlRz0rg0GOTalebjsQGFcY5FFk1AppburCjq0WdJ2S7D1IkNTVvxY6uFhQ4Rx93EIDBJxE4YhQEwwAnaGIxYsg2oK9iF/TfGndIK3LdlmYVy1A9LxQEybuyprNZVrMwfNWgFoBayOkWpr6vAwMHrporOIcg+78/G40wdljPlOWI4B3ta6TvSZnQd8R1mOr0AwDaVf5VX5RGu78LA5GPjmIjdpaz2Faug8di1LESXBqhEjtIs0B6mmgMLig8KsfPDISyasTVaqZkmjhQHWIMVIUUNVUqHV+gBZb0a+lcKrldikleETlWNjENAFDvlMx+Y0Ex2S3gqNxO+TcoKDjytIzeOIOeKIc4EcegBZkZdKzS1YFqeKflyGPdlmYUucyKYhBooBVkVP6ajC8QmN/WhWPbtrzhdua0dtcIG0BGIGi2bW1GKIQ5VQRHUcSY3Cy3K88j6OeyDc9URSpPYgTQw7kJspSCEQKXSDGm86z0sQ4NER0qsKr/dzAiMen70idAiTUl2GIhs7Vs+rrFVqYsRww9cQYUHIFgOMrdjoLw0OzuRm+clcOKlXhoS+/G+sEmnNK4GfWsBEo4KtxFmbvYGWQxxSugEKcQxHIe3jS/31SngkSQJzWtMz3WhZuVeTThRWI61oBLwSXT04ev9gOARq9QrR7FDhwSg6l5fXmnjCKXBvRiLFPRfRqqOYAhdkdZ5Fi5uk01g28g9uHTEEWeQp6VQamsepWFi++++g5bnTrCWNPZjLJg8JWozifGLWnerCKVpD2RVt7Wum8eJF25oqQIFwJZSqFjFNpYUDWqCwGmVgRq2lq6TfwBlKCq5lUJgJCaNhcXMN4qLbaGrjo0vit1nvZvhYmVhEPF47hi23wTBiumLEcMOo5hxeY5KAtXfkNFjCytIMMq6I985FgZMQhOnbQBeVrG6mKzMX8DgM9CVLiDvFMVJbuDDBwlfvQgYgAmZ0qeXxVXuhplENwMPk5eX28nFAzg1ZWARe6hkYZGpA3GPlq83QCAEvdQiR1M9QbQVW5AMZbVq54oZxLoQ+EYY7lZuRe7yNIKQsFUnpWsql19jBVSRxI6ToCqlXEeODKEoJz40C0Kutc+qSR7m1Q+lKbmrWhSv3dtbUaKUDS1yP3v6mo1pnUKgjJ4zcpBvU9ZOZLxB7qKxJSg0iIqFARUVa3k9hLRDiNoDi2u4iFCalbLOgD1+3Vf9xkugNH4G62YGjOsmLIcccg30QhlIUev6Jyl47Od6A6lAKFEoA8ZhIJhS2ESMixAmoXYWc7BYzEavQKYW8IrfdOQcwMUuYNy5GCKX0AhSiHFosQgYp5oIxBwQkERm/YaBzWr8ZKCyqFxTYti6Eq75lQfKtyBz0IzzHhX7JqBzE3eAHZHGZS5i+cGZ2JhdiuanAG4JEJZeGbI8QD3wSBQ5B64oJjm9slWn+3yHbFkSYxe7qKBhiiLqqgAgAWt+y6kxormltrKlm4Hmr/3cDumsrC0wVwLJSqkn5Ej2Xqv3kb7t/TtkxlX+mdZELhEmFrz5q1H7+/dsxzC2LdLyxGHXN0XIksCUAgwcLwtsx6TnUHkmGyV9YYZuMoEPskrgkNmUDWmimhKSVN3LAjqvDK4IChHDjwWI80Cs/pO51Ql0R4qBm7iCXTWFKBCOamsbukk9RSNkGYhQi63l1FL0l0aod4pmb99tYKw3ikhFhRrB6chRSNsrDSBC4p6VkQgmJlVGOixNkSuOOxTwmsgTsNT4sxy5KCN1jqvyU88/6GoZkYdiujjpqitOPkJbxWFzK3yiBxn46LqwYK6jTbTJ8WlTzhC84UHKB3IeZZCAIKP4mQrU2OFrUxZjjiWtq/F8x1tAGSop89C9HIpJJ7ua0dLuheTnCK6KrJUrw3mKRZhhtMHn4agEKrdV8GOSg4AMM3vN0OcK7GsTqWojDeAMqRXZ5YlvRoyaFC+oet2oaxESfEUwiUxXo/yaHBL2BVm0eb3gEK2+GTrL4UYxKSr6+pahTuY4fWhP/LxelSPZrcXoXDgEt1CdNDAiuiN5WrGDA2QUvujo/FiWA45dHaTrthkKdB8iIqnkUgKIBfVYFAIKZJCFbsw1Hulx90AqFapUPVLAXr+IEGKCPTE6XG/LxrBBcQo2nzCiqkxw1amLEckx8/shE8ieMrAPZkNopEN4sS6DgDSp9TkDSLrVNCS6kWFO5jq9qMQpbAryKHeKSbm9wnUeWVVQQqqQ4pVZpTcHjWBnLEadlxUqesaHeqpq1IOiZFjFaRpAJfEaPV75UBjqochx8ixMlI0RIrKZestKXmdnFPG7OxOZJgURnqlYZZW4KvMLS7kwGmXxGhgcpVghlbgkQi9ceZAPh2WCYBPiJmh5xEyrKW2J57tmInVnS37vL8DvQKuraVbVpsS5nmaEFX6fC2kkqJKV65GIjnahkPOBD1gjKoqpU6WMcGKKcsRjR7KGqvSfJ7Jttms1E74NESOSVP2DL8P28M6dBQnGeN3hkrhlHMqyDsVlGIPpdhTPimBQI2aSdEIkZADijmIGVQMVEMyGdQqP5NBJf1WGRbIuAK1Mo8SUbMizyWxWi4egoEjx2S4qG79vSXdhUZnEMfmt2JaImxRIx1bHCkSopENIs/KSJFQbm8U+TWWQ4/pSjzpttbQfKWRWN3ZAl+1id9MUCUHDq/b0nxQwjCnt3TBJwwuoTIoV2dbEQKXULhERizIsE8xbMSNyZgStab0pNjK0fEf4m6ZeFgxZTli6ecp+Krd1cDK8Ig0hbd6PUiRUA0dlsJkrv86AKDOLSPNQlTUKrg6t4ysU6mu1CMc5djFYJRCmoU1CeiADPTUrcBQMDU6RpgKlq5UUQjkWGVYq80lMfqiNDaVpdV2a2VSzWVZWlECi6PeKSJDA2RoBfWsaNLPzbGoYcyyOifkT8hZgBlaqbmu5fCma2sztm1tTniHyF75o5Lp/kB17EySZKq45uh9jEgYSxqaOzG5eUtNSKgWVlyFhTa3dKG5pQtNzVvVAObaeX9D4eoEwKwGPBAILkZ9sowNVkxZjliWtL8GQFZnQiHDLV0So8XtQUcwBbvCPOqdomytkRjF2FWr9OTfGTWDr84pm9acHpjc7PfBUenkEZcDkAEpYGKVvuySWLUF5facxNy+CndqU8rV/DzdBpzsFtAXyVZcUYV3cvPBVg0A3ViRi8qbVEApH+FfXm43MuLKNe1P+0Z7JNC1tRnNLV2m+jJdiYi94di2LaZSm2RDooW3v5EI401T81ZMbt5ixFVT89YR77eu2MVCDPt6of+mgDLt733+1phg23wTBmtAfxO0Qa+/v/8gH4llPBhUox92xllMYiUUgxgeE9g+4GAgAiZnOLaHWTSkd4IXyuCcIXQD9FYEekOCciwwNTWAQpRFIXIhRAlplBBEEXwWoBCn4NESipEUPFKwAK6KL3BpjFhQWZEiAr3cQ4qEcGmMQUFR4h5yrAxB5VDjgAMuqSAE0B+l0eD2ggYxBimHp6psZe4CiLAzzKAttQuVMEQoZOuxIhxkSFCdaZbIlKoNCpVCzr7uD1+6u+YBAGY0r0V/fz96+2NMU7/vC7wQ4nXuSQ8iYvT392NK3ZrD6rUzMMDBIRALYRLcBzlVAkr/3wgUIbCtX7buD4S5O0I4qszOCOHYHcwRDhHWzv+GbNmyBW1tbQf7MCwWi8VyCNHZ2YnW1uFtz7GgXC5j9uzZ2LZt26i3NX36dGzcuBG+74/BkR25WDH1JnDO0dXVhXw+DzKOJdz+/n60tbWhs7MTdXV147afIw37uI4P9nEdP+xjOz4cqMdVCIGBgQE0NzeD0vFz0pTLZQTB6M3unudZITUG2Dbfm0ApHbdvFyNRV1dn30DHAfu4jg/2cR0/7GM7PhyIx7W+fvzHyfi+b0XQBMIa0C0Wi8VisVhGgRVTFovFYrFYLKPAiqkJQiqVwvXXX49UKnWwD+Wwwj6u44N9XMcP+9iOD/ZxtYwn1oBusVgsFovFMgpsZcpisVgsFotlFFgxZbFYLBaLxTIKrJiyWCwWi8ViGQVWTFksFovFYrGMAiumJhibNm3CFVdcgdmzZyOdTuOoo47C9ddfPyZJtxbgG9/4BhYvXoxMJoOGhoaDfTiHLLfeeitmz54N3/dx0kknYfny5Qf7kA55Hn30Ubz3ve9Fc3MzCCH47W9/e7AP6ZDnxhtvxCmnnIJ8Po+pU6fiwgsvxJo1aw72YVkOQ6yYmmC8+uqr4Jzjv/7rv/Dyyy/jpptuwve+9z189atfPdiHdlgQBAEuuugifOpTnzrYh3LIctddd+Haa6/F1772NTz33HNYsmQJ3vWud6Gjo+NgH9ohTaFQwPHHH4/vfve7B/tQDhseeeQRXHXVVXjiiSewbNkyRFGEc889F4VC4WAfmuUww0YjHAL83//7f3Hbbbdhw4YNB/tQDhvuuOMOXHvttejt7T3Yh3LIceqpp+LEE0/EbbfdZs475phjcOGFF+LGG288iEd2+EAIwT333IMLL7zwYB/KYcWOHTswdepUPPLIIzjzzDMP9uFYDiNsZeoQoK+vD42NjQf7MCwWBEGAZ555Bueee27N+eeeey5WrFhxkI7KYtk7+vr6AMC+n1rGHCumJjjr16/Hd77zHXzyk5882IdisWDnzp2I4xjTpk2rOX/atGnYtm3bQToqi+XNEULguuuuwxlnnIGFCxce7MOxHGZYMXWAuOGGG0AIecPT008/XXObrq4unH/++bjoootw5ZVXHqQjn/jsz2NrGR2EkJq/hRDDzrNYJhJXX301XnjhBfzyl7882IdiOQxxDvYBHClcffXV+NCHPvSG12lvbze/d3V14eyzz8Zpp52G73//++N8dIc2+/rYWvafKVOmgDE2rAq1ffv2YdUqi2WicM011+B3v/sdHn30UbS2th7sw7EchlgxdYCYMmUKpkyZslfX3bp1K84++2ycdNJJuP3220GpLSC+Efvy2FpGh+d5OOmkk7Bs2TK8//3vN+cvW7YMF1xwwUE8MotlOEIIXHPNNbjnnnvw8MMPY/bs2Qf7kCyHKVZMTTC6urpw1llnYebMmfjWt76FHTt2mMumT59+EI/s8KCjowM9PT3o6OhAHMdYtWoVAGDu3LnI5XIH9+AOEa677jpcdtllOPnkk03ltKOjw/r6Rsng4CBee+018/fGjRuxatUqNDY2YubMmQfxyA5drrrqKvziF7/Avffei3w+byqq9fX1SKfTB/noLIcTNhphgnHHHXfgYx/72IiX2adq9Fx++eW48847h53/0EMP4ayzzjrwB3SIcuutt+Lf/u3f0N3djYULF+Kmm26yS81HycMPP4yzzz572Pkf/ehHcccddxz4AzoM2JOP7/bbb8fll19+YA/GclhjxZTFYrFYLBbLKLBmHIvFYrFYLJZRYMWUxWKxWCwWyyiwYspisVgsFotlFFgxZbFYLBaLxTIKrJiyWCwWi8ViGQVWTFksFovFYrGMAiumLBaLxWKxWEaBFVMWyzhDCMFvf/tbAMCmTZtACDHJ64ci27ZtwznnnINsNouGhoYDvv/LL78cF1544bju40A9T5dffrkZxq1fI/tLcuD3t7/97TE5vsORRx99FO9973vR3Ny834+7EALf+ta3MG/ePKRSKbS1teFf//Vfx/5gLYcMVkxZLAeQtrY2kxo+lrS3tx+wD9CbbroJ3d3dWLVqFdauXXtA9pnk5ptvHtNE8JHE2Xg9TyNx/vnno7u7G+9617tGtZ0vfOEL6O7utoN834RCoYDjjz8e3/3ud/d7G5/97Gfxwx/+EN/61rfw6quv4r777sPb3va2MTxKy6GGnc1nsYwBYRjCdd03vR5j7JCfsbh+/XqcdNJJOProo8d0u0EQwPO8N71efX39mO53JA7k85RKpcZkX7lcDrlcDoyxMTiqw5d3vetdbyhcgyDA//7f/xs///nP0dvbi4ULF+Kb3/ymGTf1yiuv4LbbbsNLL72E+fPnH6Cjtkx0bGXKMqHZsWMHpk+fXlNCX7lyJTzPw5///Oc93m7Lli340Ic+hMbGRmSzWZx88slYuXKlufy2227DUUcdBc/zMH/+fPz0pz+tuX1HRwcuuOAC5HI51NXV4eKLL8brr79uLr/hhhtwwgkn4Mc//jHmzJmDVCoFIQTWrVuHM888E77vY8GCBVi2bFnNdoe2jx5++GEQQvDXv/4VJ598MjKZDBYvXow1a9aY26xfvx4XXHABpk2bhlwuh1NOOQV/+ctfzOVnnXUWNm/ejM997nOmzaNZsWIFzjzzTKTTabS1teEzn/kMCoXCGz7mb/TYtLe34ze/+Q1+8pOfgBCyx/lmutrzz//8z5g6dSrq6urwiU98AkEQ1Bz31Vdfjeuuuw5TpkzBOeecAwB45JFH8La3vQ2pVAozZszAP/3TPyGKomHb1ggh8G//9m+YM2cO0uk0jj/+ePy///f/ao7n5Zdfxrvf/W7U1dUhn89jyZIlWL9+PW644QbceeeduPfee81j9/DDD4/Y5nuz4zrrrLPwmc98Bl/60pfQ2NiI6dOn44YbbnjDx3ok9L5//etfY8mSJUin0zjllFOwdu1aPPXUUzj55JORy+Vw/vnn1wxCt4wNH/vYx/C3v/0Nv/rVr/DCCy/goosuwvnnn49169YBAO677z7MmTMH999/P2bPno329nZceeWV6OnpOchHbjmoCItlgvP73/9euK4rnnrqKTEwMCDmzp0rPvvZz+7x+gMDA2LOnDliyZIlYvny5WLdunXirrvuEitWrBBCCHH33XcL13XFLbfcItasWSP+/d//XTDGxIMPPiiEEIJzLhYtWiTOOOMM8fTTT4snnnhCnHjiiWLp0qVmH9dff73IZrPivPPOE88++6x4/vnnRRRFYuHCheKss84Szz33nHjkkUfEokWLBABxzz33CCGE2LhxowAgnnvuOSGEEA899JAAIE499VTx8MMPi5dfflksWbJELF682Oxr1apV4nvf+5544YUXxNq1a8XXvvY14fu+2Lx5sxBCiF27donW1lbxf/7P/xHd3d2iu7tbCCHECy+8IHK5nLjpppvE2rVrxd/+9jexaNEicfnll+/xsXuzx2b79u3i/PPPFxdffLHo7u4Wvb29I27nox/9qMjlcuKSSy4RL730krj//vtFU1OT+OpXv2qus3TpUpHL5cQXv/hF8eqrr4pXXnlFbNmyRWQyGfHpT39avPLKK+Kee+4RU6ZMEddff33Nti+44ALz91e/+lXxlre8RfzpT38S69evF7fffrtIpVLi4YcfFkIIsWXLFtHY2Cg+8IEPiKeeekqsWbNG/PjHPxavvvqqGBgYEBdffLE4//zzzWNXqVSGPU97c1xLly4VdXV14oYbbhBr164Vd955pyCEiD//+c97fLyH3hchqq8RfZ9Wr14t3v72t4sTTzxRnHXWWeKxxx4Tzz77rJg7d6745Cc/OWybs2bNEjfddNMe92mpkvzfFEKI1157TRBCxNatW2uu93d/93fiK1/5ihBCiE984hMilUqJU089VTz66KPioYceEieccII4++yzD+ShWyYYVkxZDgk+/elPi3nz5olLL71ULFy4UJRKpT1e97/+679EPp8Xu3btGvHyxYsXi49//OM151100UXi7//+74UQQvz5z38WjDHR0dFhLn/55ZcFAPHkk08KIaSYcl1XbN++3VzngQceEIwx0dnZac774x//uFdi6i9/+Yu5ze9//3sB4A3v44IFC8R3vvMd8/dIH6CXXXaZ+Md//Mea85YvXy4opXvc9ps9NkIIccEFF4iPfvSjezw2IaRIaGxsFIVCwZx32223iVwuJ+I4FkJI8XHCCSfU3O6rX/2qmD9/vuCcm/NuueWWmtslBcjg4KDwfd8IZc0VV1whPvzhDwshhPjKV74iZs+eLYIg2OOx7knQ6Odpb45r6dKl4owzzqjZzimnnCK+/OUvv+HjtKd9//CHPzTn/fKXvxQAxF//+ldz3o033ijmz58/bJtWTO09Q8XUr3/9awFAZLPZmpPjOOLiiy8WQgjx8Y9/XAAQa9asMbd75plnBADx6quvHui7YJkg2Daf5ZDgW9/6FqIowq9//Wv8/Oc/h+/7e7zuqlWrsGjRIjQ2No54+SuvvILTTz+95rzTTz8dr7zyirm8ra0NbW1t5vIFCxagoaHBXAcAZs2ahaampprtzpw5s8YAfNppp+3V/TvuuOPM7zNmzAAAbN++HYA0zH7pS18yx5DL5fDqq6+io6PjDbf5zDPP4I47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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "da.plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "570bf4f1-5f9e-4cf9-8fc8-d0c8b1356e14", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.10.9" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/NWM_1km_DFReferenceFileSystem.ipynb b/201/NWM_1km_DFReferenceFileSystem.ipynb deleted file mode 100644 index b4a5907..0000000 --- a/201/NWM_1km_DFReferenceFileSystem.ipynb +++ /dev/null @@ -1,3969 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "05681bd5-20c7-4528-822c-6ca6826714d4", - "metadata": {}, - "source": [ - "# Open NWM 1km dataset as DFReferenceFileSystem \n", - "\n", - "Open dataset as a fsspec `DFReferenceFileSystem` filesystem by reading references from a collection of Parquet files: one file containing global metadata and coordinate variable references, and one file for each of the data variables. \n", - "\n", - "The big wins here are lazy-loading of the references for each variable, and the more efficient construction of the virtual fsspec filesystem from the Parquet files (JSON is slow to decode)." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "584ab9a2-4f6b-4907-93b1-3d2b0786f601", - "metadata": {}, - "outputs": [], - "source": [ - "import fsspec\n", - "from fsspec.implementations.reference import DFReferenceFileSystem\n", - "import xarray as xr" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "732722cb-4430-4359-9014-eb9c551e7873", - "metadata": {}, - "outputs": [], - "source": [ - "fs = fsspec.filesystem('s3', anon=True, \n", - " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "c6f5f293-ced5-44c2-8231-a77e22c451e1", - "metadata": {}, - "outputs": [], - "source": [ - "s3_lazy_refs = 's3://esip/noaa/nwm/lazy_refs'" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "691c9634-cc24-407f-ae56-50d4247960a5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of Parquet files: 21\n", - "Total size of Parquet references: 0.492091486 GB\n" - ] - } - ], - "source": [ - "print(f'Number of reference files: {len(fs.ls(s3_lazy_refs))}')\n", - "print(f'Total size of references: {fs.du(s3_lazy_refs)/1e9} GB')" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b5f4c4da-27c1-4374-ba60-61315cd965b1", - "metadata": {}, - "outputs": [], - "source": [ - "r_opts = {'anon': True}\n", - "t_opts = {'anon': True, 'client_kwargs':{'endpoint_url':'https://ncsa.osn.xsede.org'}}" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "69e11199-c729-42a0-ad25-0cbbf97088df", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 5.03 s, sys: 404 ms, total: 5.43 s\n", - "Wall time: 12 s\n" - ] - } - ], - "source": [ - "%%time\n", - "fs2 = DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options=t_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs2.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "cd8ddfb0-7b57-43aa-98dc-b9a837e57542", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "04d02447-a134-45eb-978f-e0d392435dbb", - "metadata": {}, - "source": [ - "Examine a specific variable:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "ce2ec93e-a879-459f-804c-66a9f977db3f", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'TRAD' (time: 116631, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-6e252a6bf6e4556824b3940793011076TRAD, shape=(116631, 3840, 4608), dtype=float64, chunksize=(1, 768, 922), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Surface radiative temperature\n",
-       "    units:           K\n",
-       "    valid_range:     [0, 4000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Surface radiative temperature\n", - " units: K\n", - " valid_range: [0, 4000]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.TRAD" - ] - }, - { - "cell_type": "markdown", - "id": "151133ab-e6ee-4903-b23a-36bfef0286d9", - "metadata": {}, - "source": [ - "How big would the uncompressed size of the whole dataset be?" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "8dd5b70a-2585-4dce-b0b1-a2cd915c7952", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "462.28064798432" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.nbytes/1e12 #TB" - ] - }, - { - "cell_type": "markdown", - "id": "7496c3b2-ae11-4af4-952f-18c3f3a3b73c", - "metadata": {}, - "source": [ - "Load some data at a specific time step. The first time a variable is accessed it will take longer as the references need to be loaded." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "7b0a2164-053c-4f84-a9b7-172bf3cd83a5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 7.12 s, sys: 1.26 s, total: 8.39 s\n", - "Wall time: 13.6 s\n" - ] - } - ], - "source": [ - "%%time \n", - "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "26510252-7ec2-4e21-8ddf-aff2eca56793", - "metadata": {}, - "source": [ - "Loading data for another time step is much faster as the references are already loaded:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "ef01e203-f6cd-4c4e-ac3d-410afd5a4524", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.04 s, sys: 531 ms, total: 4.57 s\n", - "Wall time: 6.31 s\n" - ] - } - ], - "source": [ - "%%time\n", - "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "1f41f59f-12aa-4e4c-bf64-c61ecfe50db5", - "metadata": {}, - "source": [ - "Compute the mean over the domain:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "bd30a9a2-2264-4628-8826-8b965fe55ded", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(266.92635398)" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "da.mean().data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73fe200b-ee97-4f49-8d42-60d53d0a7160", - "metadata": {}, - "outputs": [], - "source": [ - "da.plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "570bf4f1-5f9e-4cf9-8fc8-d0c8b1356e14", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.9.16" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/NWM_1km_ReferenceFileSystem.ipynb b/201/NWM_1km_ReferenceFileSystem.ipynb deleted file mode 100644 index 871ff6b..0000000 --- a/201/NWM_1km_ReferenceFileSystem.ipynb +++ /dev/null @@ -1,3942 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6e37266f-ef99-4ccc-a93c-1e8b8e346b7a", - "metadata": {}, - "source": [ - "# Open NWM 1km dataset as ReferenceFileSystem \n", - "Create a `ReferenceFileSystem` object by reading references from a 9.8GB combined JSON file. \n", - "\n", - "Opening the dataset in Xarray takes more than 10 minutes, mostly due to decoding the giant JSON file. It also requires more than 50GB of RAM to run, more than 8GB or 16GB typically available to users. " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "2f32fec2-df41-4260-b081-d5b379eaa922", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import fsspec\n", - "import xarray as xr\n", - "from fsspec.implementations.reference import ReferenceFileSystem" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "65beb48e-6988-42e4-b12f-f22f6d56f37a", - "metadata": {}, - "outputs": [], - "source": [ - "fs = fsspec.filesystem('s3', anon=True, \n", - " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "26db3d84-d8f0-49b0-aefe-01275504bc4a", - "metadata": {}, - "outputs": [], - "source": [ - "url = 's3://esip/noaa/nwm/grid1km/LDAS_combined.json'" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "33a8c6f2-7998-4f35-a86a-263a28881c92", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9.780943801" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fs.size(url)/1e9 # JSON size in GB" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "401182fe-69a9-418b-a6b5-6be0f50dcdb6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4min 34s, sys: 40.4 s, total: 5min 14s\n", - "Wall time: 7min 44s\n" - ] - } - ], - "source": [ - "%%time\n", - "s_opts = {'anon':True, 'client_kwargs':{'endpoint_url':'https://ncsa.osn.xsede.org'}}\n", - "r_opts = {'anon':True}\n", - "fs = ReferenceFileSystem(url, ref_storage_args=s_opts,\n", - " remote_protocol='s3', remote_options=r_opts)\n", - "m = fs.get_mapper(\"\")\n", - "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "c527f679-927d-411e-b72f-5a304725c729", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n",
-       "Coordinates:\n",
-       "  * time      (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x         (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y         (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n",
-       "Dimensions without coordinates: vis_nir, soil_layers_stag\n",
-       "Data variables: (12/21)\n",
-       "    ACCET     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ACSNOM    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBEDO    (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ALBSND    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    ALBSNI    (time, y, vis_nir, x) float64 dask.array<chunksize=(1, 960, 1, 1152), meta=np.ndarray>\n",
-       "    COSZ      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    ...        ...\n",
-       "    SNOWH     (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    SOIL_M    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    SOIL_W    (time, y, soil_layers_stag, x) float64 dask.array<chunksize=(1, 768, 1, 922), meta=np.ndarray>\n",
-       "    TRAD      (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    UGDRNOFF  (time, y, x) float64 dask.array<chunksize=(1, 768, 922), meta=np.ndarray>\n",
-       "    crs       object ...\n",
-       "Attributes:\n",
-       "    Conventions:                CF-1.6\n",
-       "    GDAL_DataType:              Generic\n",
-       "    TITLE:                      OUTPUT FROM WRF-Hydro v5.2.0-beta2\n",
-       "    code_version:               v5.2.0-beta2\n",
-       "    model_configuration:        retrospective\n",
-       "    model_initialization_time:  1979-02-01_00:00:00\n",
-       "    model_output_type:          land\n",
-       "    model_output_valid_time:    1979-02-01_03:00:00\n",
-       "    model_total_valid_times:    472\n",
-       "    proj4:                      +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (time: 116631, y: 3840, x: 4608, vis_nir: 2, soil_layers_stag: 4)\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 ... 1.918e+06 1.919e+06\n", - "Dimensions without coordinates: vis_nir, soil_layers_stag\n", - "Data variables: (12/21)\n", - " ACCET (time, y, x) float64 dask.array\n", - " ACSNOM (time, y, x) float64 dask.array\n", - " ALBEDO (time, y, x) float64 dask.array\n", - " ALBSND (time, y, vis_nir, x) float64 dask.array\n", - " ALBSNI (time, y, vis_nir, x) float64 dask.array\n", - " COSZ (time, y, x) float64 dask.array\n", - " ... ...\n", - " SNOWH (time, y, x) float64 dask.array\n", - " SOIL_M (time, y, soil_layers_stag, x) float64 dask.array\n", - " SOIL_W (time, y, soil_layers_stag, x) float64 dask.array\n", - " TRAD (time, y, x) float64 dask.array\n", - " UGDRNOFF (time, y, x) float64 dask.array\n", - " crs object ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " GDAL_DataType: Generic\n", - " TITLE: OUTPUT FROM WRF-Hydro v5.2.0-beta2\n", - " code_version: v5.2.0-beta2\n", - " model_configuration: retrospective\n", - " model_initialization_time: 1979-02-01_00:00:00\n", - " model_output_type: land\n", - " model_output_valid_time: 1979-02-01_03:00:00\n", - " model_total_valid_times: 472\n", - " proj4: +proj=lcc +units=m +a=6370000.0 +b=6370000.0 ..." - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "0867e1a7-ad9c-492b-ace9-49efbcbbbd33", - "metadata": {}, - "source": [ - "Examine a specific variable:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "729e2fb8-b2d5-4968-adcd-3d0f77c3b25f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'TRAD' (time: 116631, y: 3840, x: 4608)>\n",
-       "dask.array<open_dataset-f023a0a5ac622e0f461f87fa458be7d0TRAD, shape=(116631, 3840, 4608), dtype=float64, chunksize=(1, 768, 922), chunktype=numpy.ndarray>\n",
-       "Coordinates:\n",
-       "  * time     (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n",
-       "  * x        (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n",
-       "  * y        (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n",
-       "Attributes:\n",
-       "    esri_pe_string:  PROJCS["Lambert_Conformal_Conic",GEOGCS["GCS_Sphere",DAT...\n",
-       "    grid_mapping:    crs\n",
-       "    long_name:       Surface radiative temperature\n",
-       "    units:           K\n",
-       "    valid_range:     [0, 4000]
" - ], - "text/plain": [ - "\n", - "dask.array\n", - "Coordinates:\n", - " * time (time) datetime64[ns] 1979-02-01T03:00:00 ... 2020-12-31T21:00:00\n", - " * x (x) float64 -2.303e+06 -2.302e+06 ... 2.303e+06 2.304e+06\n", - " * y (y) float64 -1.92e+06 -1.919e+06 -1.918e+06 ... 1.918e+06 1.919e+06\n", - "Attributes:\n", - " esri_pe_string: PROJCS[\"Lambert_Conformal_Conic\",GEOGCS[\"GCS_Sphere\",DAT...\n", - " grid_mapping: crs\n", - " long_name: Surface radiative temperature\n", - " units: K\n", - " valid_range: [0, 4000]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.TRAD" - ] - }, - { - "cell_type": "markdown", - "id": "3ca7794f-930f-4964-9fef-3fc30ec5eda3", - "metadata": {}, - "source": [ - "Compute the uncompressed size of this dataset in TB:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "67960b52-5600-4b71-963e-93701cffbd5b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "462.28064798432" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ds.nbytes/1e12 " - ] - }, - { - "cell_type": "markdown", - "id": "b3af81f4-d84b-4f19-a1f5-5815304c191f", - "metadata": {}, - "source": [ - "Loading data for a particular time step is fast as the references are already loaded:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "af73254d-bb31-47d8-b7eb-6d12e7735bdf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.36 s, sys: 652 ms, total: 5.01 s\n", - "Wall time: 5.96 s\n" - ] - } - ], - "source": [ - "%%time\n", - "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "e6112c50-cea2-49ef-8e97-e1dda4222c4a", - "metadata": {}, - "source": [ - "Loading data for another time step takes about the same amount of time:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "d85d7899-f31e-4970-9c4c-fd04dc7cd8ce", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.17 s, sys: 436 ms, total: 4.6 s\n", - "Wall time: 4.67 s\n" - ] - } - ], - "source": [ - "%%time\n", - "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" - ] - }, - { - "cell_type": "markdown", - "id": "4ae8eede-2838-4df0-9360-ad1263a43212", - "metadata": {}, - "source": [ - "Compute the mean over the domain:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "b6ae3a97-3bec-46ce-8377-0bd6ba6b699a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(266.92635398)" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "da.mean().data" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "users-users-pangeo", - "language": "python", - "name": "conda-env-users-users-pangeo-py" - }, - "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.9.16" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/201/OptimalChunkSelection.ipynb b/201/OptimalChunkSelection.ipynb new file mode 100644 index 0000000..d877593 --- /dev/null +++ b/201/OptimalChunkSelection.ipynb @@ -0,0 +1,460 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5f48557f-21ec-4fad-805c-3e3ed34bfd08", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Choosing an Optimal Chunk Size and Shape" + ] + }, + { + "cell_type": "markdown", + "id": "5e8da090-7b8d-4a6b-9450-9086415ca6d3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "::::{margin}\n", + ":::{note}\n", + "This notebook is based on a 2013 blog post by Russ Rew at Unidata, [Chunking Data: Choosing Shapes](http://www.unidata.ucar.edu/blogs/developer/en/entry/chunking_data_choosing_shapes).\n", + "The algorithm utilized in this notebook is based on the algorithm presented in that blog post.\n", + ":::\n", + "::::" + ] + }, + { + "cell_type": "markdown", + "id": "7dcb0092-180a-4817-b5ce-acf888b6edd5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "The objective of this notebook is to learn and discuss *how* to select the optimal chunk size and shape for a given dataset.\n", + "In the [Basics of Chunk Shape and Size notebook](../101/BasicsShapeSize.ipynb), we discussed the general considerations for chunking, but not how to apply these consisderations for selecting chunk shape and size.\n", + "These considerations included:\n", + "\n", + "- chunk size between 10-200 MiB,\n", + "- having partial final chunks at least half the size of the standard chunk,\n", + "- performant future reads across all dimensions (or optimized for the dominant read pattern), and\n", + "- chunk shape that is optimized for future data additions (if they occur).\n", + "\n", + "Here, we build upon those considerations and present a basic algorithm for automatically selecting the \"optimal\" chunk shape and size.\n", + "Therefore, giving us a method for selecting chunk shape and size without much trial and error." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b34f6618-d42a-4ab2-8577-9d82f8760392", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "import numpy as np\n", + "import itertools" + ] + }, + { + "cell_type": "markdown", + "id": "4dcabda2-662b-4e71-a4a3-24d3672f17ac", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## The Many Considerations for Optimal Chunk Shape and Size Selection\n", + "\n", + "As we just listed, there are several things to consider when selecting a chunk size.\n", + "Creating an \"optimal\" chunk shape and size requires balancing all of these things to make our dataset perform as we want.\n", + "For example, the \"perfect\" chunking would have:\n", + "\n", + "- chunk size around 10 MiB (to accomodate different hardware),\n", + "- no partial final chunks (i.e., chunk shape is integer divisor of the full data shape),\n", + "- performant future reads across all dimensions and groups of dimensions, and\n", + "- a shape that is an integer divisor of future data additions (if they occur).\n", + "\n", + "In addition to these, if we can select a chunk size that is optimal for our disk storage (e.g., disk block size), we should further improve read times.\n", + "However, in practice, there is no way to get the \"perfect\" chunk.\n", + "We will almost always have to compromise on one or more of these criteria to stay within the constraints created by another.\n", + "The criteria we compromise on is up to us, which makes determining the \"optimal\" chunk relatively subjective.\n", + "Therefore, chunk shape and size selection is just as much an art as a science.\n", + "It depends some firm rules, but it also depends on our preferences." + ] + }, + { + "cell_type": "markdown", + "id": "4f8a5ec8-49e7-457c-a9da-074a707f0af2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Optimal Chunk Shape Algorithm\n", + "\n", + "As chunk shape and size selection is relatively subjective, let's create an algorithm using some of our preferences and restrictions to automate the chunk selection process.\n", + "To take into account the first two considerations (size and partial chunks), this algorithm will focus on determining a chunk shape from the dataset shape given a maximum (uncompressed) chunk size and minimum partial chunk fraction.\n", + "It will return a chunk shape that has a size as close the maximum size as possible, while ensuring any final chunks contain partial chunk fractions above the specified minimum.\n", + "For reads across dimensions, we will limit our algorithm to 3D data only and try and balance 1D-to-2D read times.\n", + "For example, if we have a 3D spatiotemporal dataset, it would propose an \"optimal\" shape that allows for almost equal read times for time-series and spatial reads.\n", + "Finally, we will assume the algorithm will only be applied to static datasets and that we do not need to worry about any future data additions.\n", + "\n", + "So, let's take a look at the algorithm, which we will write as a function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1c4522a-387b-43d9-a9be-e4d967aaa898", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def chunk_shape_3D(var_shape, chunk_size=4096, var_value_size=4, partial_chunk_frac=0.5, verbose=False):\n", + " \"\"\"\n", + " Return a \"optimal\" shape for a 3D variable, assuming balanced 1D-to-2D access.\n", + "\n", + " Parameters\n", + " ----------\n", + " var_shape : tuple[int]\n", + " Length 3 list giving the variable shape in terms of (T, X, Y).\n", + " chunk_size : int\n", + " Maximum chunk size desired, in bytes (default = 4096).\n", + " var_value_size : int\n", + " Size of each variable data value, in bytes (default = 4).\n", + " partial_chunk_frac : float\n", + " The minimum fraction of data that the partial final chunk must\n", + " contain using the returned chunk shape (default = 0.5).\n", + " verbose : bool\n", + " If True, info on other candidate chunk shapes will be printed\n", + " (default = False).\n", + "\n", + " Returns\n", + " -------\n", + " chunk_shape : tuple[int]\n", + " The optimal chunk shape that provides balanced access of 1D subsets\n", + " and 2D subsets of a variable with shape (T, X, Y), T is the typically\n", + " the time dimension and X and Y are the spatial dimensions. An \"optimal\"\n", + " shape for chunks means that the number of chunks accessed to read\n", + " either a full time series (1D) or full spatial map (2D) is\n", + " approximately equal, and the size of each chunk (uncompressed) is no\n", + " more than `chunk_size`, which is often a disk block size.\n", + " \"\"\"\n", + " rank = len(var_shape)\n", + " # Get ideal chunk info using only chunk size and balanced read\n", + " ideal_num_vals_per_chunk = chunk_size / float(var_value_size)\n", + " ideal_num_chunks = np.prod(var_shape) / ideal_num_vals_per_chunk\n", + " if ideal_num_chunks < 1:\n", + " ideal_num_chunks = 1\n", + " ideal_1d_num_chunks = np.sqrt(ideal_num_chunks)\n", + " ideal_2d_num_chunks = np.sqrt(ideal_1d_num_chunks)\n", + "\n", + " if verbose:\n", + " print(f'Ideal number of values in a chunk = {ideal_num_vals_per_chunk:0.1f}')\n", + " print(f'Ideal number of chunks = {ideal_num_chunks:0.1f}')\n", + " print(f'Ideal number of chunks along the 1D axis = {ideal_1d_num_chunks:0.1f}')\n", + " print(f'Ideal number of chunks along each 2D axis = {ideal_2d_num_chunks:0.1f}')\n", + "\n", + " # Get 1D optimal chunk shape along dimension\n", + " # Check if the first dimension has smaller shape then number of chunks\n", + " # If so, set to chunk shape to 1 and adjust 2D ideal chunks\n", + " if var_shape[0] < ideal_1d_num_chunks:\n", + " chunk_dim = 1.0\n", + " ideal_2d_num_chunks = (ideal_2d_num_chunks\n", + " / np.sqrt(var_shape[0] / ideal_1d_num_chunks))\n", + " else:\n", + " chunk_dim = var_shape[0] // ideal_1d_num_chunks\n", + " # Add chunk dim to optimal chunk shape list\n", + " optimal_chunk_shape = [chunk_dim]\n", + "\n", + " # Get 2D optimal chunk shape along each dimension\n", + " prod = 1.0 # factor to increase other dims if some must be increased to 1.0\n", + " for i in range(1, rank):\n", + " if var_shape[i] < ideal_2d_num_chunks:\n", + " prod *= ideal_2d_num_chunks / var_shape[i]\n", + " \n", + " for i in range(1, rank):\n", + " if var_shape[i] < ideal_2d_num_chunks:\n", + " chunk_dim = 1.0\n", + " else:\n", + " chunk_dim = (prod * var_shape[i]) // ideal_2d_num_chunks\n", + " optimal_chunk_shape.append(chunk_dim)\n", + "\n", + " # Calculate the partial chunk fraction from the remainder\n", + " remainder_frac_per_dim = np.remainder(var_shape, optimal_chunk_shape) / optimal_chunk_shape\n", + " # If the remainder fraction is 0, swap with 1 for multiplication of parial chunk fraction\n", + " optimal_chunk_frac = np.where(remainder_frac_per_dim == 0, 1, remainder_frac_per_dim).prod()\n", + "\n", + " if verbose:\n", + " print(f'Ideal chunk shape = {tuple(map(int, optimal_chunk_shape))}')\n", + " print(f'Ideal chunk, partial chunk fraction = {optimal_chunk_frac}')\n", + "\n", + " \"\"\"\n", + " optimal_chunk_shape is typically too small, size(optimal_chunk_shape) < chunk_size\n", + " and may have small partial chunks. So, we adjust by adding 1 to some chunk shape\n", + " dimensions to get as close as possible to chunk_size without exceeding it and then\n", + " check if the shape is over the minimum partial chunk fraction. If it is acceptable,\n", + " that is our chunk shape. Otherwise, we continually subtract one from the 1D dimension\n", + " to get to the partial fraction minimum, while adding one to the 2D dimensions to\n", + " maintain the size request. We then reverse this and subtract from the 2D demensions\n", + " and add to the 1D demensions. The optimal chunk is then the one that is the most\n", + " balanced of these two increment and decrement methods.\n", + " \"\"\"\n", + " # Increment the optimal chunk shape by 1\n", + " best_chunk_size = 0\n", + " best_chunk_shape = []\n", + " if verbose:\n", + " print('\\n--- Candidates ---')\n", + " for dim_increment in itertools.product([0, 1], repeat=3):\n", + " candidate_chunk_shape = np.add(optimal_chunk_shape, dim_increment)\n", + " \n", + " this_chunk_size = int(var_value_size * np.prod(candidate_chunk_shape))\n", + " remainder = np.remainder(var_shape, candidate_chunk_shape) / candidate_chunk_shape\n", + " this_chunk_frac = np.where(remainder == 0, 1, remainder).prod()\n", + " \n", + " if verbose:\n", + " if (this_chunk_size <= chunk_size) and (this_chunk_frac >= partial_chunk_frac):\n", + " print(f'{tuple(map(int, candidate_chunk_shape))}; '\n", + " f'Total size per chunk (MB): {this_chunk_size/2**20:0.3f} '\n", + " f'(ratio: {np.prod(candidate_chunk_shape) / ideal_num_vals_per_chunk:0.3f}); '\n", + " f'Partial chunk fraction: {this_chunk_frac}')\n", + "\n", + " # Only keep if closest to chunk size limit and above partial fraction limit\n", + " if (best_chunk_size < this_chunk_size <= chunk_size) and (this_chunk_frac >= partial_chunk_frac):\n", + " best_chunk_size = this_chunk_size\n", + " best_chunk_shape = list(candidate_chunk_shape) # make a copy of best candidate so far\n", + "\n", + " # Return if a shape was found\n", + " if best_chunk_shape:\n", + " return list(map(int, best_chunk_shape))\n", + "\n", + " # Increment and decrement 1D and 2D from optimal chunk shape to get a best shape \n", + " increments_decrements = [[[-1, 0, 0], [0, 1, 0], [0, 0, 1]],\n", + " [[1, 0, 0], [0, -1, 0], [0, 0, -1]]]\n", + " # Use Euclidean distance to estimate balanced shape\n", + " best_shape_balance = np.linalg.norm(np.array(optimal_chunk_shape) - np.array([0, 0, 0]))\n", + " for increment_decrement in increments_decrements:\n", + " best_chunk_frac = optimal_chunk_frac\n", + " candidate_chunk_shape = list(optimal_chunk_shape)\n", + " while best_chunk_frac < partial_chunk_frac:\n", + " # Quit if any candidate is too big or too small in a dimension\n", + " if ((np.array(candidate_chunk_shape) < 1).any()\n", + " or (candidate_chunk_shape > np.array(var_shape)).any()):\n", + " break\n", + "\n", + " for dim_increment in increment_decrement:\n", + " candidate_chunk_shape = np.add(candidate_chunk_shape, dim_increment)\n", + " \n", + " this_chunk_size = int(var_value_size * np.prod(candidate_chunk_shape))\n", + " remainder = np.remainder(var_shape, candidate_chunk_shape) / candidate_chunk_shape\n", + " this_chunk_frac = np.where(remainder == 0, 1, remainder).prod()\n", + " \n", + " if (this_chunk_size <= chunk_size) and (this_chunk_frac >= partial_chunk_frac):\n", + " if verbose:\n", + " print(f'{tuple(map(int, candidate_chunk_shape))}; '\n", + " f'Total size per chunk (MB): {this_chunk_size/2**20:0.3f} '\n", + " f'(ratio: {np.prod(candidate_chunk_shape) / ideal_num_vals_per_chunk:0.3f}); '\n", + " f'Partial chunk fraction: {this_chunk_frac}')\n", + " \n", + " best_chunk_frac = this_chunk_frac\n", + " shape_balance = np.linalg.norm(np.array(optimal_chunk_shape) - candidate_chunk_shape)\n", + " # Only save candidate if it is more balanced than previous one\n", + " if shape_balance < best_shape_balance:\n", + " best_shape_balance = shape_balance\n", + " best_chunk_shape = list(candidate_chunk_shape)\n", + "\n", + "\n", + " return tuple(map(int, best_chunk_shape))" + ] + }, + { + "cell_type": "markdown", + "id": "cedb4e04-8130-4858-b7c2-385ea124178d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Examples\n", + "\n", + "### Toy Example\n", + "\n", + "Okay, now that we have our algorithm, let's give it a test using some made up data.\n", + "We will use a variable of shape `(365, 240, 150)`, aim for a chunk of 1 MiB (`2**20`) in size, and a partial chunk fraction of `0.5` (0.8 in each dimensions; $0.8^3 \\approx 0.5$)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac4b8326-e846-4f84-ba78-7ad4fd1a1c15", + "metadata": {}, + "outputs": [], + "source": [ + "var_shape = (365, 240, 150)\n", + "chunk_shape = chunk_shape_3D(\n", + " var_shape, chunk_size=2**20, partial_chunk_frac=0.5, verbose=True\n", + ")\n", + "print(f'\\n\"Optimal\" chunk shape: {chunk_shape}')" + ] + }, + { + "cell_type": "markdown", + "id": "cb9bb4a7-fc11-41b8-9713-5a7ec45f3e0e", + "metadata": {}, + "source": [ + "Nice!\n", + "From these results, we can see that the \"ideal\" chunk shape given only our chunk size would have been `(51, 90, 56)`.\n", + "However, this had some partial chunks that would have been very small.\n", + "So, its choice would not have been good given this additional constraint.\n", + "Therefore, it adjusted the chunk shape to `(53, 88, 54)` to meet the partial chunk constraint and provide us with a reasonably close alternative in terms of both dimension balance and chunk size.\n", + "This is great, exactly what we wanted!" + ] + }, + { + "cell_type": "markdown", + "id": "0a8a8d0d-a75a-409e-ad00-202d0b5cf100", + "metadata": {}, + "source": [ + "### PRISM Example\n", + "\n", + "As a real world example, let's apply the algorithm to the PRISM data from the [Basics of Chunk Shape and Size notebook](../101/BasicsShapeSize.ipynb).\n", + "First, we need to read in the data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5b888f0-c335-4836-bb02-a48d5f882986", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem(\n", + " 's3',\n", + " anon=True, # anonymous = does not require credentials\n", + " client_kwargs={'endpoint_url': 'https://usgs.osn.mghpcc.org/'}\n", + ")\n", + "ds = xr.open_dataset(\n", + " fs.get_mapper('s3://mdmf/gdp/PRISM_v2.zarr/'),\n", + " engine='zarr',\n", + " chunks={}\n", + ")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "2f15d796-7ed8-4841-afa1-94ae82a005e8", + "metadata": {}, + "source": [ + "Now, we can estimate the \"optimal\" chunk shape using our algorithm.\n", + "We will only do this for the precipitaiton data variable as the others all have the same shape and data type.\n", + "Also, we will use a maximum chunk size that matches the same chunk size of the dataset currently to see how our algorithm compares to the chosen chunking." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "149194b3-dad9-4a02-961e-1597449d3910", + "metadata": {}, + "outputs": [], + "source": [ + "current_chunk_size = np.prod([chunksize[0] for chunksize in ds['ppt'].chunksizes.values()])\n", + "current_chunk_size *= ds['ppt'].dtype.itemsize\n", + "\n", + "chunk_shape = chunk_shape_3D(\n", + " ds['ppt'].shape,\n", + " chunk_size=current_chunk_size,\n", + " var_value_size=ds['ppt'].dtype.itemsize,\n", + " verbose=True\n", + ")\n", + "print(f'\\n\"Optimal\" chunk shape: {chunk_shape}')" + ] + }, + { + "cell_type": "markdown", + "id": "bc2762d3-b358-474c-b63a-d469c262ba9c", + "metadata": {}, + "source": [ + "As we can see, our algorithm struggles with this dataset to come up with a balanced chunk shape that meets our size and partial fraction restrictions.\n", + "Rather than having the \"ideal\" chunk shape of `(125, 178, 404)`, we got a chunk shape of `(168, 135, 362)`, which is quite different than the current chunk shape of `(72, 354, 354)`.\n", + "The primary driver of this discrepancy is our restriction on balancing the dimensions, as the current chunk shape has a parital fraction of 0.73.\n", + "Therefore, enforcing the balance can be very restrictive." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "f7645c50-6f2e-471e-b91c-e961331d1212", + "metadata": {}, + "source": [ + "## Further Considerations\n", + "\n", + "As noted in the PRISM example, this algorithm is a very niche case for chunk shape selection.\n", + "It assumes you want even read times for the temporal and spatial dimensions, and it only allows for 3D data.\n", + "What if we had more dimensions or fewer?\n", + "What if we wanted a different read pattern that was unbalanced?\n", + "What if we wanted to not have any partial chunks and only use a chunk shape that is a divisor of the variable shape?\n", + "Therefore, this algorithm is not general by any means, but does give us an idea on how to formulate more general algorithms in the future.\n", + "For example, one of these more general algorithms can be found in [this repo on dynamic rechunking](https://github.com/jbusecke/dynamic_chunks), which has some algorithms that allow for the user to specify the balancing of the dimensions and a chunk size limit.\n", + "As algorithms like these become more developed, selecting an optimal chunk size should become easier.\n", + "However, the subjective component will never go away and the need for someone to make a decision on what critera that influences chunk shape and size is more important will always be required." + ] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/RechunkingwithDask.ipynb b/201/RechunkingwithDask.ipynb new file mode 100755 index 0000000..a566a1f --- /dev/null +++ b/201/RechunkingwithDask.ipynb @@ -0,0 +1,437 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Rechunking Larger Datasets with Dask\n", + "\n", + "The goal of this notebook is to expand on the rechunking performed in the [Introductory Rechunking tutorial](../101/Rechunking.ipynb).\n", + "This notebook will perfrom the same operations, but will work on the **much** larger dataset and involve some parallelization using [dask](https://www.dask.org/). \n", + "\n", + ":::{Warning}\n", + "You should only run workflows like this tutorial on a cloud or HPC compute node.\n", + "In application, this will require reading and writing **enormous** amounts of data.\n", + "Using a typical network connection and simple compute environment, you would saturate your bandwidth and max out your processor, thereby taking days for the rechunking to complete.\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import xarray as xr\n", + "import fsspec\n", + "from rechunker import rechunk\n", + "import zarr\n", + "import dask.distributed\n", + "import dask.diagnostics\n", + "import logging" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Read in a Zarr Store\n", + "\n", + "Like the [Introductory Rechunking tutorial](../101/Rechunking.ipynb), we will use the data from the National Water Model Retrospective Version 2.1.\n", + "The full dataset is part of the [AWS Open Data Program](https://aws.amazon.com/opendata/), available via the S3 bucket at: `s3://noaa-nwm-retro-v2-zarr-pds/`.\n", + "\n", + "As this is a Zarr store, let's read it in with [`xarray.open_dataset()`](https://docs.xarray.dev/en/stable/generated/xarray.open_dataset.html) and `engine='zarr'`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "file = fsspec.get_mapper('s3://noaa-nwm-retro-v2-zarr-pds', anon=True)\n", + "ds = xr.open_dataset(file, chunks={}, engine='zarr')\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Restrict for Tutorial\n", + "\n", + "As we saw in the [Introductory Rechunking tutorial](../101/Rechunking.ipynb), this data set is massive, taking up almost 32 TiB uncompressed.\n", + "As this is a tutorial, we will still restrict the data to a subset, as we don't really need to work on the entire dataset.\n", + "Following the [Introductory Rechunking tutorial](../101/Rechunking.ipynb) let's only look at `streamflow` and `velocity` for the first 15,000 `feature_id`, but the 2000s decade of water years (October 1999 through September 2009) instead of a single water year.\n", + "This will make our dataset larger-than-memory, but it should still run in a reasonable amount of time.\n", + "\n", + "For processing the full-sized dataset, you'd just skip this step where we slice off a representative example of the data.\n", + "Expect run time to increase in proportion to the size of the data being processed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['streamflow', 'velocity']]\n", + "ds = ds.isel(feature_id=slice(0, 15000))\n", + "ds = ds.sel(time=slice('1999-10-01', '2009-09-30'))\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, our subset of data is only about 10 GiB per data variable and has a chunk shape of `{'time': 672, 'feature_id': 15000}` with size of 76.9 MiB.\n", + "However, the chunk shape is not an optimal choice for our analysis as it is chunked completely by `feature_id` (i.e., all feature IDs for a given time can be read in a single chunk).\n", + "Following the [Introductory Rechunking tutorial](../101/Rechunking.ipynb), let's get chunk shapes that are time-series wise chunking (i.e., all `time` for a given `feature_id` in one chunk) for streamflow and balanced for velocity." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rechunk Plan\n", + "\n", + "Using our general strategy of time-series wise chunking for streamflow and balanced for velocity,\n", + "let's compute how large the chunk sizes will be if we have chunk shapes of `{'time': 87672, 'feature_id': 1}` for streamflow and 3 chunks per dimension for velocity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nfeature = len(ds.feature_id)\n", + "ntime = len(ds.time)\n", + "\n", + "streamflow_chunk_plan = {'time': ntime, 'feature_id': 1}\n", + "bytes_per_value = ds.streamflow.dtype.itemsize\n", + "total_bytes = streamflow_chunk_plan['time'] * streamflow_chunk_plan['feature_id'] * bytes_per_value\n", + "streamflow_MiB = total_bytes / (2 ** 10) ** 2\n", + "partial_chunks = {'time': ntime - streamflow_chunk_plan['time'] * (ntime / streamflow_chunk_plan['time']),\n", + " 'feature_id': nfeature - streamflow_chunk_plan['feature_id'] * (nfeature / streamflow_chunk_plan['feature_id']),}\n", + "print(\"STREAMFLOW \\n\"\n", + " f\"Chunk of shape {streamflow_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {partial_chunks['time']} ({partial_chunks['time']/streamflow_chunk_plan['time']:.3f}% of a chunk)\\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {partial_chunks['feature_id']} ({partial_chunks['feature_id']/streamflow_chunk_plan['feature_id']:.3f}% of a chunk)\\n\"\n", + " f\"Chunk size: {streamflow_MiB:.2f} [MiB] \\n\")\n", + "\n", + "chunks_per_dim = 3\n", + "velocity_chunk_plan = {'time': ntime // chunks_per_dim, 'feature_id': nfeature // chunks_per_dim}\n", + "bytes_per_value = ds.velocity.dtype.itemsize\n", + "total_bytes = velocity_chunk_plan['time'] * velocity_chunk_plan['feature_id'] * bytes_per_value\n", + "velocity_MiB = total_bytes / (2 ** 10) ** 2\n", + "partial_chunks = {'time': ntime - velocity_chunk_plan['time'] * chunks_per_dim,\n", + " 'feature_id': nfeature - velocity_chunk_plan['feature_id'] * chunks_per_dim,}\n", + "print(\"VELOCITY \\n\"\n", + " f\"Chunk of shape {velocity_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {partial_chunks['time']} ({partial_chunks['time']/velocity_chunk_plan['time']:.3f}% of a chunk)\\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {partial_chunks['feature_id']} ({partial_chunks['feature_id']/velocity_chunk_plan['feature_id']:.3f}% of a chunk)\\n\"\n", + " f\"Chunk size: {velocity_MiB:.2f} [MiB]\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Okay, we can see that the streamflow chunk size is way to small by a factor of ~100.\n", + "So, let's include 100 feature IDs per chunk.\n", + "As for velocity, it is about ~10x too big.\n", + "As it is an even chunk split, that means we need to increase the number of chunks per dimension by ~$\\sqrt{10} \\approx 3$.\n", + "However knowing that the time dimension is hourly, we can get no partial chunks if our chunk per dimension is a divisor of 24.\n", + "Luckily, this also applies to the feature ID dimension as 15000 is a multiple of 24.\n", + "So, rather than increasing our chunks per dimension by a factor of 3 to 9, let's increase them to 12 as this will give no partial chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nfeature = len(ds.feature_id)\n", + "ntime = len(ds.time)\n", + "\n", + "streamflow_chunk_plan = {'time': ntime, 'feature_id': 100}\n", + "bytes_per_value = ds.streamflow.dtype.itemsize\n", + "total_bytes = streamflow_chunk_plan['time'] * streamflow_chunk_plan['feature_id'] * bytes_per_value\n", + "streamflow_MiB = total_bytes / (2 ** 10) ** 2\n", + "partial_chunks = {'time': ntime - streamflow_chunk_plan['time'] * (ntime / streamflow_chunk_plan['time']),\n", + " 'feature_id': nfeature - streamflow_chunk_plan['feature_id'] * (nfeature / streamflow_chunk_plan['feature_id']),}\n", + "print(\"STREAMFLOW \\n\"\n", + " f\"Chunk of shape {streamflow_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {partial_chunks['time']} ({partial_chunks['time']/streamflow_chunk_plan['time']:.3f}% of a chunk)\\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {partial_chunks['feature_id']} ({partial_chunks['feature_id']/streamflow_chunk_plan['feature_id']:.3f}% of a chunk)\\n\"\n", + " f\"Chunk size: {streamflow_MiB:.2f} [MiB] \\n\")\n", + "\n", + "chunks_per_dim = 12\n", + "velocity_chunk_plan = {'time': ntime // chunks_per_dim, 'feature_id': nfeature // chunks_per_dim}\n", + "bytes_per_value = ds.velocity.dtype.itemsize\n", + "total_bytes = velocity_chunk_plan['time'] * velocity_chunk_plan['feature_id'] * bytes_per_value\n", + "velocity_MiB = total_bytes / (2 ** 10) ** 2\n", + "partial_chunks = {'time': ntime - velocity_chunk_plan['time'] * chunks_per_dim,\n", + " 'feature_id': nfeature - velocity_chunk_plan['feature_id'] * chunks_per_dim,}\n", + "print(\"VELOCITY \\n\"\n", + " f\"Chunk of shape {velocity_chunk_plan} \\n\"\n", + " f\"Partial 'time' chunk remainder: {partial_chunks['time']} ({partial_chunks['time']/velocity_chunk_plan['time']:.3f}% of a chunk)\\n\"\n", + " f\"Partial 'feature_id' chunk remainder: {partial_chunks['feature_id']} ({partial_chunks['feature_id']/velocity_chunk_plan['feature_id']:.3f}% of a chunk)\\n\"\n", + " f\"Chunk size: {velocity_MiB:.2f} [MiB]\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nice!\n", + "Now, our chunks are a reasonable size and have no remainders.\n", + "So, lets use these chunk plans for our rechunking." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chunk_plan = {\n", + " 'streamflow': streamflow_chunk_plan,\n", + " 'velocity': velocity_chunk_plan,\n", + " # We don't want any of the coordinates chunked\n", + " 'latitude': (nfeature,),\n", + " 'longitude': (nfeature,), \n", + " 'time': (ntime,),\n", + " 'feature_id': (nfeature,)\n", + "}\n", + "chunk_plan" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rechunk with Rechunker\n", + "\n", + "With this plan, we can now ask Rechunker to re-write the data using the prescribed chunking pattern.\n", + "\n", + "### Set up output location\n", + "\n", + "Unlike with the smaller dataset in our previous rechunking tutorial, we will write this larger dataset to an object store (an S3 'bucket') on the USGS OSN.\n", + "So, we need to set that up so that Rechunker will have a suitable place to write data.\n", + "\n", + "First, we need to set up the AWS profile and S3 endpoit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['AWS_PROFILE'] = \"osn-hytest-scratch\"\n", + "os.environ['AWS_S3_ENDPOINT'] = \"https://usgs.osn.mghpcc.org\"\n", + "%run ../AWS.ipynb" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we make our S3 `fsspec.filesystem` with the required user info and get the mapper to this file to pass to Rechunker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from getpass import getuser\n", + "uname=getuser()\n", + "\n", + "fs = fsspec.filesystem(\n", + " 's3', \n", + " anon=False, \n", + " default_fill_cache=False, \n", + " skip_instance_cache=True, \n", + " client_kwargs={'endpoint_url': os.environ['AWS_S3_ENDPOINT'], }\n", + ")\n", + "\n", + "output_dir = f's3://hytest-scratch/rechunking_tutorial/{uname}/'\n", + "\n", + "temp_store = fs.get_mapper(output_dir + 'temp_store.zarr')\n", + "target_store = fs.get_mapper(output_dir + 'tutorial_rechunked.zarr')\n", + "# Check if the objects exist and remove if they do\n", + "for filename in [temp_store, target_store]:\n", + " try:\n", + " fs.rm(filename.root, recursive=True)\n", + " except:\n", + " FileNotFoundError" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Spin up Dask Cluster\n", + "\n", + "Our rechunking operation will be able to work in parallel.\n", + "To do that, we will spin up a dask cluster to schedule the various workers.\n", + "\n", + "```{note}\n", + "This cluster will be configured differently depending on where you compute is performed.\n", + "See the [dask deployment docs](https://docs.dask.org/en/stable/deploying.html) for details.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cluster = dask.distributed.LocalCluster(\n", + " n_workers=8,\n", + " threads_per_worker=1, \n", + " silence_logs=logging.ERROR\n", + ")\n", + "client = dask.distributed.Client(cluster)\n", + "client" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Rechunk\n", + "\n", + "Now, we are ready to rechunk!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = rechunk(\n", + " # Make sure the base chunks are correct\n", + " ds.chunk({'time': 672, 'feature_id': 15000}),\n", + " target_chunks=chunk_plan,\n", + " max_mem=\"2GB\",\n", + " target_store=target_store,\n", + " temp_store=temp_store\n", + ")\n", + "result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remember that merely invoking Rechunker does not do any work.\n", + "It just sorts out the rechunking plan and writes metadata.\n", + "We need to call `.execute` on the `result` object to actually run the rechunking." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [], + "source": [ + "with dask.diagnostics.ProgressBar():\n", + " r = result.execute(retries=10) \n", + "\n", + "# Also consolidate the metadata for fast reading into xarray\n", + "_ = zarr.consolidate_metadata(target_store)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Confirm the Creation of the Zarr Store by Rechunker\n", + "\n", + "Let's read in the resulting re-chunked dataset to confirm it turned out how we intended." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds_rechunked = xr.open_zarr(target_store)\n", + "ds_rechunked" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nice, looks good!\n", + "You may have noticed that the only difference between the [introductory tutorial on rechunking](../101/Rechunking.ipynb) and this is the inclusion of creating the dask cluster and where we saved the files.\n", + "Picking your compute environment and output location will typically be the only things that vary in other workflows requiring rechunking.\n", + "Therefore, if you understand this rechunking process you should be able to apply it to your own data efficiently." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Clean Up\n", + "\n", + "As we don't want to keep this rechunked Zarr, let's go ahead and delete it.\n", + "We will also conform with best practices and close our Dask client and cluster." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fs.rm(temp_store.root, recursive=True)\n", + "fs.rm(target_store.root, recursive=True)\n", + " \n", + "client.close()\n", + "cluster.close()" + ] + } + ], + "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.12.0" + }, + "vscode": { + "interpreter": { + "hash": "4100cc85ffefb381c538d28dd18cb927e5a99f05bbed6aaad5313d7bb1c2079e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/201/index.md b/201/index.md index 3c094ea..bca6e11 100644 --- a/201/index.md +++ b/201/index.md @@ -1,4 +1,7 @@ -# Chunking 201 +# Advanced Topics in Chunking + +In this second series of notebooks, we will go over more advanced topics associated with chunking. +The key concepts you should understand have after this series include: ```{tableofcontents} ``` diff --git a/201/old_notebooks/00_grid_rechunk.ipynb b/201/old_notebooks/00_grid_rechunk.ipynb new file mode 100644 index 0000000..da9e82f --- /dev/null +++ b/201/old_notebooks/00_grid_rechunk.ipynb @@ -0,0 +1,304 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "23c8086d-13e4-47af-811c-482464eed528", + "metadata": { + "tags": [] + }, + "source": [ + "# Rechunk NWM 1km gridded output\n", + "\n", + "The NWM 1km gridded output is available on AWS S3 as hourly NetCDF files, so we we would like to rechunk them to be read by the Zarr library.\n", + "\n", + "One approach would be to download all the files and work on them locally, like Pangeo forge often does. We will try a different approach, of first kerchunking the NetCDF files to make them more performant, then running rechunker on the kerchunked dataset. In both steps, we will use a Dask Gateway cluster, with workers writing directly to S3.\n" + ] + }, + { + "cell_type": "markdown", + "id": "885c6a17-a487-4ddd-8596-ac2006b14068", + "metadata": {}, + "source": [ + "## Chunking and rechunking resources\n", + "* [\"Making Earth Science data more accessible\"](https://www.slideserve.com/kiaria/making-earth-science-data-more-accessible-experience-with-chunking-and-compression), AMS presentation slides by Russ Rew, Unidata (2013)\n", + "* [\"Rechunker: The missing link for chunked array analytics\"](https://medium.com/pangeo/rechunker-the-missing-link-for-chunked-array-analytics-5b2359e9dc11), Medium blog post by Ryan Abernathy, Columbia University (2020)\n", + "* [\"Rechunker\" Python Library Documentation](https://rechunker.readthedocs.io/en/latest/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7ab4294-7b92-4482-9912-57357075be5a", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import fsspec\n", + "import xarray as xr\n", + "import hvplot.xarray\n", + "import zarr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f81d41d-93fb-4e04-ad6d-26f23129cd90", + "metadata": { + "tags": [ + "remove-input" + ] + }, + "outputs": [], + "source": [ + "print(\"Python : \", sys.version)\n", + "print(\"fsspec : \", fsspec.__version__)\n", + "print(\"xarray : \", xr.__version__)\n", + "print(\"zarr : \", zarr.__version__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7601239-424c-4ae4-b5f8-760cd58a9141", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem('s3', anon=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0467a0d8-0759-48c3-92b8-840918481dcd", + "metadata": {}, + "outputs": [], + "source": [ + "flist = fs.ls('s3://noaa-nwm-retrospective-2-1-pds/')\n", + "flist" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3688846d-8df7-427c-8226-6fd0bf21dd9c", + "metadata": {}, + "outputs": [], + "source": [ + "flist = fs.glob('noaa-nwm-retrospective-2-1-pds/model_output/*')\n", + "print(flist[0])\n", + "print(flist[-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e34f9c7-adf2-42db-866c-6e4c4487c858", + "metadata": {}, + "outputs": [], + "source": [ + "flist = fs.glob('noaa-nwm-retrospective-2-1-pds/model_output/1979/*LDAS*')\n", + "flist[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3755ecf-266a-4403-b3ed-c7edc8b0ea61", + "metadata": {}, + "outputs": [], + "source": [ + "flist = fs.glob('noaa-nwm-retrospective-2-1-pds/model_output/2020/*LDAS*')\n", + "flist[-1]" + ] + }, + { + "cell_type": "markdown", + "id": "3bb47465-4eee-4edd-8815-26050b02090c", + "metadata": {}, + "source": [ + "Okay, so at this point we've learned that we have 3-hourly output over roughly 40 years" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "621ceb7e-191a-4884-a474-b47a2afcc0ef", + "metadata": {}, + "outputs": [], + "source": [ + "# %%time\n", + "# flist = fs.glob('noaa-nwm-retrospective-2-1-pds/model_output/*/*LDAS*') # this is slow\n", + "40 * 365 * 24 / 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dbe431e-5564-4c15-99d6-338d6af840d9", + "metadata": {}, + "outputs": [], + "source": [ + "flist[0]" + ] + }, + { + "cell_type": "markdown", + "id": "1646169b-7466-4146-8060-5c39985604d9", + "metadata": {}, + "source": [ + "So about 117,000 NetCDF files! " + ] + }, + { + "cell_type": "markdown", + "id": "85914de3-6b6d-456f-8f37-61bc24e6964d", + "metadata": {}, + "source": [ + "Let's check one out. Although it's not super efficient, we can open a NetCDF file on S3 as a virtual file object with `fs.open(s3_url_of_netcdf_file)`. If we open a dataset in xarray using `chunks=` we are telling xarray to use Dask, and `chunks={}` means use the native chunking in the NetCDF file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7355518-8490-440c-99e8-f183b5e73c99", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(fs.open(flist[0]), chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e54fefb-c522-4c5b-80cb-45c39f88014b", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f056f13-6cb8-48cb-ac4e-d95c12758ff1", + "metadata": {}, + "outputs": [], + "source": [ + "ds.data_vars" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "055162ae-cda2-4d6f-8350-246ce3fbb743", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['ACCET', 'SNEQV', 'FSNO']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e24e41c-afbc-40d4-8211-1be8ab796527", + "metadata": {}, + "outputs": [], + "source": [ + "ds.data_vars" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1ddab31-7090-4fd3-bccc-c61c8ff1cd03", + "metadata": {}, + "outputs": [], + "source": [ + "ds['ACCET']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea0af67c-70c1-4043-adec-ca95cb15f8f4", + "metadata": {}, + "outputs": [], + "source": [ + "ds.ACCET" + ] + }, + { + "cell_type": "markdown", + "id": "32bd73ae-618a-4342-8b90-54d7e58fe769", + "metadata": {}, + "source": [ + "The data is chunked as full spatial domain and 1 time step, with about 135MB chunk size. This is actually great for visualization of maps at specific time steps or for calculations that involve the entire dataset. So kerchunking this data would be a nice first step. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3591a978-e5f5-48ca-aeb6-7df31a224779", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "da = ds.ACCET.load()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5a59214-6041-4d47-a5a8-ee61a08c1420", + "metadata": {}, + "outputs": [], + "source": [ + "da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e94899e-66a1-4f1e-8568-a4ac8d2a0dfa", + "metadata": {}, + "outputs": [], + "source": [ + "da.hvplot(x='x', y='y', rasterize=True, cmap='turbo', data_aspect=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90a81208-88ea-4921-9e21-aade42fc3952", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + }, + "vscode": { + "interpreter": { + "hash": "21742c3f70e60132a0f53ab9a02119f1da5d00e790acd69466294df8491d8f10" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/01_file_inspection.ipynb b/201/old_notebooks/01_file_inspection.ipynb similarity index 97% rename from 201/01_file_inspection.ipynb rename to 201/old_notebooks/01_file_inspection.ipynb index 5bcf90a..d1f8b3d 100644 --- a/201/01_file_inspection.ipynb +++ b/201/old_notebooks/01_file_inspection.ipynb @@ -257,6 +257,11 @@ } ], "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, "language_info": { "codemirror_mode": { "name": "ipython", @@ -267,7 +272,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.12.0" }, "vscode": { "interpreter": { diff --git a/201/02a_count_jsons.ipynb b/201/old_notebooks/02a_count_jsons.ipynb similarity index 98% rename from 201/02a_count_jsons.ipynb rename to 201/old_notebooks/02a_count_jsons.ipynb index 38b2d42..b2c04ad 100644 --- a/201/02a_count_jsons.ipynb +++ b/201/old_notebooks/02a_count_jsons.ipynb @@ -90,7 +90,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/201/02a_kerchunk_single.ipynb b/201/old_notebooks/02a_kerchunk_single.ipynb similarity index 99% rename from 201/02a_kerchunk_single.ipynb rename to 201/old_notebooks/02a_kerchunk_single.ipynb index 9198d87..d41d4d3 100644 --- a/201/02a_kerchunk_single.ipynb +++ b/201/old_notebooks/02a_kerchunk_single.ipynb @@ -455,9 +455,9 @@ ], "metadata": { "kernelspec": { - "display_name": "users-users-pangeo", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "conda-env-users-users-pangeo-py" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -469,7 +469,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/201/02b_kerchunk_multi.ipynb b/201/old_notebooks/02b_kerchunk_multi.ipynb similarity index 100% rename from 201/02b_kerchunk_multi.ipynb rename to 201/old_notebooks/02b_kerchunk_multi.ipynb diff --git a/201/02b_kerchunk_multi_bag-Copy1.ipynb b/201/old_notebooks/02b_kerchunk_multi_bag-Copy1.ipynb similarity index 100% rename from 201/02b_kerchunk_multi_bag-Copy1.ipynb rename to 201/old_notebooks/02b_kerchunk_multi_bag-Copy1.ipynb diff --git a/201/02b_kerchunk_multi_to_years.ipynb b/201/old_notebooks/02b_kerchunk_multi_to_years.ipynb similarity index 100% rename from 201/02b_kerchunk_multi_to_years.ipynb rename to 201/old_notebooks/02b_kerchunk_multi_to_years.ipynb diff --git a/201/02c_json_list_sizes.ipynb b/201/old_notebooks/02c_json_list_sizes.ipynb similarity index 100% rename from 201/02c_json_list_sizes.ipynb rename to 201/old_notebooks/02c_json_list_sizes.ipynb diff --git a/201/02c_kerchunk_multi_from_years.ipynb b/201/old_notebooks/02c_kerchunk_multi_from_years.ipynb similarity index 100% rename from 201/02c_kerchunk_multi_from_years.ipynb rename to 201/old_notebooks/02c_kerchunk_multi_from_years.ipynb diff --git a/201/02d_kerchunk.explore.ipynb b/201/old_notebooks/02d_kerchunk.explore.ipynb similarity index 100% rename from 201/02d_kerchunk.explore.ipynb rename to 201/old_notebooks/02d_kerchunk.explore.ipynb diff --git a/201/old_notebooks/03_rechunk_broken.ipynb b/201/old_notebooks/03_rechunk_broken.ipynb new file mode 100644 index 0000000..4834675 --- /dev/null +++ b/201/old_notebooks/03_rechunk_broken.ipynb @@ -0,0 +1,522 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4108776-2095-4696-a4b6-fef7c2496fce", + "metadata": {}, + "source": [ + "# Rechunk the kerchunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import fsspec.implementations.reference\n", + "import zarr\n", + "import xarray as xr\n", + "from pathlib import Path\n", + "\n", + "from rechunker import rechunk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", + "metadata": {}, + "outputs": [], + "source": [ + "import rechunker\n", + "rechunker.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr\n", + "zarr.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", + "metadata": {}, + "source": [ + "#### Start a Dask Gateway cluster\n", + "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "sys.path.append('/shared/users/rsignell/lib')\n", + "import ebdpy as ebd\n", + "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", + "\n", + "client, cluster, gateway = ebd.start_dask_cluster(\n", + " profile=os.environ['AWS_PROFILE'],\n", + " worker_max=30,\n", + " region='us-west-2', \n", + " worker_profile='Medium Worker',\n", + " use_existing_cluster=False,\n", + " adaptive_scaling=False, \n", + " wait_for_cluster=False, \n", + " propagate_env=True)" + ] + }, + { + "cell_type": "markdown", + "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", + "metadata": {}, + "source": [ + "#### Open Kerchunked Dataset JSON for one year" + ] + }, + { + "cell_type": "raw", + "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", + "metadata": {}, + "source": [ + "year = '1984'\n", + "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", + "\n", + "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", + "r_opts = {'anon':True}\n", + "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d80146a7-d6a5-4df9-b8ee-b39d2470535c", + "metadata": {}, + "outputs": [], + "source": [ + "#client.close()" + ] + }, + { + "cell_type": "markdown", + "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", + "metadata": {}, + "source": [ + "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", + " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", + "metadata": {}, + "source": [ + "#### Select high-priority vars only" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", + "metadata": {}, + "outputs": [], + "source": [ + "ds['ACCET'].isel(time=slice(0,144))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d511f0-f82e-4250-930c-145feff08d27", + "metadata": {}, + "outputs": [], + "source": [ + "ds.attrs" + ] + }, + { + "cell_type": "markdown", + "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", + "metadata": {}, + "source": [ + "#### set up zarr stores for temporary and final zarr stores on S3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", + "metadata": {}, + "outputs": [], + "source": [ + "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", + "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61d64b30-f089-4200-8e98-56dd5d80bc48", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write.rm(temp_name, recursive=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99febcd6-6e57-4997-a296-56e6e047fa0e", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write.rm(target_name, recursive=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", + "metadata": {}, + "outputs": [], + "source": [ + "temp_store = fs_write.get_mapper(temp_name)\n", + "target_store = fs_write.get_mapper(target_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds.drop('crs')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", + "metadata": {}, + "outputs": [], + "source": [ + "a = len(ds.time)/(144/2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", + "metadata": {}, + "outputs": [], + "source": [ + "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", + "metadata": {}, + "outputs": [], + "source": [ + "a/b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", + "metadata": {}, + "outputs": [], + "source": [ + "#client.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76f39719-735f-4a8a-96ab-f50018a92441", + "metadata": {}, + "outputs": [], + "source": [ + "#from dask.distributed import Client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", + "metadata": {}, + "outputs": [], + "source": [ + "#client = Client(threads_per_worker=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", + "metadata": {}, + "outputs": [], + "source": [ + "#client.amm.start()" + ] + }, + { + "cell_type": "raw", + "id": "5793ef68-f5d0-4e4a-b0d6-c774afd4b72f", + "metadata": {}, + "source": [ + "import zarr.storage\n", + "from numcodecs import Zstd\n", + "zarr.storage.default_compressor = Zstd(level=9)" + ] + }, + { + "cell_type": "markdown", + "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", + "metadata": {}, + "source": [ + "#### Rechunk!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", + "metadata": {}, + "outputs": [], + "source": [ + "rechunked = rechunk(ds.isel(time=slice(0,144)), target_chunks={'y':96*2, 'x':132*2, 'time':144/2},\n", + " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "rechunked.execute(retries=10)" + ] + }, + { + "cell_type": "raw", + "id": "aecea580-d6b2-46d3-84be-ed24354def9d", + "metadata": {}, + "source": [ + "def trim_memory() -> int:\n", + " libc = ctypes.CDLL('libc.so.6')\n", + " return libc.malloc_trim(0)" + ] + }, + { + "cell_type": "raw", + "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", + "metadata": {}, + "source": [ + "client.run(trim_memory)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", + "metadata": {}, + "outputs": [], + "source": [ + "zarr.convenience.consolidate_metadata(target_store)" + ] + }, + { + "cell_type": "markdown", + "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", + "metadata": {}, + "source": [ + "#### Explore the rechunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", + "metadata": {}, + "outputs": [], + "source": [ + "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", + "metadata": {}, + "outputs": [], + "source": [ + "ds2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cee33374-49d0-4607-a812-c9ed98eefb48", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.xarray\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET[:,2000,2000].hvplot(x='time')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9093e34d-ced3-4c20-9485-7449fd673dde", + "metadata": {}, + "outputs": [], + "source": [ + "client.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4a5070b-2ca8-4794-b354-495cbb81adf1", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.10.9" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/03_rechunk_fsstore.ipynb b/201/old_notebooks/03_rechunk_fsstore.ipynb new file mode 100644 index 0000000..734bc37 --- /dev/null +++ b/201/old_notebooks/03_rechunk_fsstore.ipynb @@ -0,0 +1,514 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4108776-2095-4696-a4b6-fef7c2496fce", + "metadata": {}, + "source": [ + "# Rechunk the kerchunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import fsspec.implementations.reference\n", + "import zarr\n", + "import xarray as xr\n", + "from pathlib import Path\n", + "\n", + "from rechunker import rechunk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", + "metadata": {}, + "outputs": [], + "source": [ + "import rechunker\n", + "rechunker.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr\n", + "zarr.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", + "metadata": {}, + "source": [ + "#### Start a Dask Gateway cluster\n", + "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "sys.path.append('/shared/users/rsignell/lib')\n", + "import ebdpy as ebd\n", + "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", + "\n", + "client, cluster, gateway = ebd.start_dask_cluster(\n", + " profile=os.environ['AWS_PROFILE'],\n", + " worker_max=30,\n", + " region='us-west-2', \n", + " worker_profile='Medium Worker',\n", + " use_existing_cluster=True,\n", + " adaptive_scaling=False, \n", + " wait_for_cluster=False, \n", + " propagate_env=True)" + ] + }, + { + "cell_type": "markdown", + "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", + "metadata": {}, + "source": [ + "#### Open Kerchunked Dataset JSON for one year" + ] + }, + { + "cell_type": "raw", + "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", + "metadata": {}, + "source": [ + "year = '1984'\n", + "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", + "\n", + "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", + "r_opts = {'anon':True}\n", + "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", + "metadata": {}, + "source": [ + "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", + " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", + "metadata": {}, + "source": [ + "#### Select high-priority vars only" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", + "metadata": {}, + "outputs": [], + "source": [ + "ds['ACCET'].isel(time=slice(0,144))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d511f0-f82e-4250-930c-145feff08d27", + "metadata": {}, + "outputs": [], + "source": [ + "ds.attrs" + ] + }, + { + "cell_type": "markdown", + "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", + "metadata": {}, + "source": [ + "#### set up zarr stores for temporary and final zarr stores on S3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", + "metadata": {}, + "outputs": [], + "source": [ + "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", + "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61d64b30-f089-4200-8e98-56dd5d80bc48", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write.rm(temp_name, recursive=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99febcd6-6e57-4997-a296-56e6e047fa0e", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write.rm(target_name, recursive=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", + "metadata": {}, + "outputs": [], + "source": [ + "temp_store = fs_write.get_mapper(temp_name)\n", + "target_store = fs_write.get_mapper(target_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3e9891e-edd8-4d01-902d-f196cd6932a0", + "metadata": {}, + "outputs": [], + "source": [ + "temp_store = zarr.storage.FFStore(temp_name)\n", + "target_store = zarr.storage.FSStore(target_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds.drop('crs')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", + "metadata": {}, + "outputs": [], + "source": [ + "a = len(ds.time)/(144/2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", + "metadata": {}, + "outputs": [], + "source": [ + "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", + "metadata": {}, + "outputs": [], + "source": [ + "a/b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", + "metadata": {}, + "outputs": [], + "source": [ + "#client.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76f39719-735f-4a8a-96ab-f50018a92441", + "metadata": {}, + "outputs": [], + "source": [ + "#from dask.distributed import Client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", + "metadata": {}, + "outputs": [], + "source": [ + "#client = Client(threads_per_worker=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", + "metadata": {}, + "outputs": [], + "source": [ + "#client.amm.start()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e4ab8ecb-f1d0-46f5-bad4-a008fa819ea0", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr.storage\n", + "from numcodecs import Zstd\n", + "zarr.storage.default_compressor = Zstd(level=9)" + ] + }, + { + "cell_type": "markdown", + "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", + "metadata": {}, + "source": [ + "#### Rechunk!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", + "metadata": {}, + "outputs": [], + "source": [ + "rechunked = rechunk(ds.isel(time=slice(0,144)), target_chunks={'y':96*2, 'x':132*2, 'time':144/2},\n", + " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "rechunked.execute(retries=10)" + ] + }, + { + "cell_type": "raw", + "id": "aecea580-d6b2-46d3-84be-ed24354def9d", + "metadata": {}, + "source": [ + "def trim_memory() -> int:\n", + " libc = ctypes.CDLL('libc.so.6')\n", + " return libc.malloc_trim(0)" + ] + }, + { + "cell_type": "raw", + "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", + "metadata": {}, + "source": [ + "client.run(trim_memory)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", + "metadata": {}, + "outputs": [], + "source": [ + "zarr.convenience.consolidate_metadata(target_store)" + ] + }, + { + "cell_type": "markdown", + "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", + "metadata": {}, + "source": [ + "#### Explore the rechunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", + "metadata": {}, + "outputs": [], + "source": [ + "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", + "metadata": {}, + "outputs": [], + "source": [ + "ds2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cee33374-49d0-4607-a812-c9ed98eefb48", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.xarray\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET[:,2000,2000].hvplot(x='time')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9093e34d-ced3-4c20-9485-7449fd673dde", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/03_rechunk_works-Copy1.ipynb b/201/old_notebooks/03_rechunk_works-Copy1.ipynb new file mode 100644 index 0000000..edeb1c7 --- /dev/null +++ b/201/old_notebooks/03_rechunk_works-Copy1.ipynb @@ -0,0 +1,467 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4108776-2095-4696-a4b6-fef7c2496fce", + "metadata": {}, + "source": [ + "# Rechunk the kerchunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import fsspec.implementations.reference\n", + "import zarr\n", + "import xarray as xr\n", + "from pathlib import Path\n", + "\n", + "from rechunker import rechunk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", + "metadata": {}, + "outputs": [], + "source": [ + "import rechunker\n", + "rechunker.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr\n", + "zarr.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", + "metadata": {}, + "source": [ + "#### Start a Dask Gateway cluster\n", + "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "sys.path.append('/shared/users/rsignell/lib')\n", + "import ebdpy as ebd\n", + "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", + "\n", + "client, cluster, gateway = ebd.start_dask_cluster(\n", + " profile=os.environ['AWS_PROFILE'],\n", + " worker_max=30,\n", + " region='us-west-2', \n", + " worker_profile='Medium Worker',\n", + " use_existing_cluster=True,\n", + " adaptive_scaling=False, \n", + " wait_for_cluster=False, \n", + " propagate_env=True)" + ] + }, + { + "cell_type": "markdown", + "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", + "metadata": {}, + "source": [ + "#### Open Kerchunked Dataset JSON for one year" + ] + }, + { + "cell_type": "raw", + "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", + "metadata": {}, + "source": [ + "year = '1984'\n", + "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", + "\n", + "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", + "r_opts = {'anon':True}\n", + "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", + "metadata": {}, + "source": [ + "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", + " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", + "metadata": {}, + "source": [ + "#### Select high-priority vars only" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", + "metadata": {}, + "outputs": [], + "source": [ + "ds['ACCET'].isel(time=slice(0,72))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d511f0-f82e-4250-930c-145feff08d27", + "metadata": {}, + "outputs": [], + "source": [ + "ds.attrs" + ] + }, + { + "cell_type": "markdown", + "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", + "metadata": {}, + "source": [ + "#### set up zarr stores for temporary and final zarr stores on S3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", + "metadata": {}, + "outputs": [], + "source": [ + "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", + "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c043b20-3e43-435e-9e45-7023b178698a", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write.rm(temp_name, recursive=True)\n", + "fs_write.rm(target_name, recursive=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", + "metadata": {}, + "outputs": [], + "source": [ + "temp_store = fs_write.get_mapper(temp_name)\n", + "target_store = fs_write.get_mapper(target_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds.drop('crs')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", + "metadata": {}, + "outputs": [], + "source": [ + "a = len(ds.time)/(144/2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", + "metadata": {}, + "outputs": [], + "source": [ + "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", + "metadata": {}, + "outputs": [], + "source": [ + "a/b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", + "metadata": {}, + "outputs": [], + "source": [ + "#client.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76f39719-735f-4a8a-96ab-f50018a92441", + "metadata": {}, + "outputs": [], + "source": [ + "#from dask.distributed import Client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", + "metadata": {}, + "outputs": [], + "source": [ + "#client = Client(threads_per_worker=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", + "metadata": {}, + "outputs": [], + "source": [ + "#client.amm.start()" + ] + }, + { + "cell_type": "raw", + "id": "5793ef68-f5d0-4e4a-b0d6-c774afd4b72f", + "metadata": {}, + "source": [ + "import zarr.storage\n", + "from numcodecs import Zstd\n", + "zarr.storage.default_compressor = Zstd(level=9)" + ] + }, + { + "cell_type": "markdown", + "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", + "metadata": {}, + "source": [ + "#### Rechunk!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", + "metadata": {}, + "outputs": [], + "source": [ + "rechunked = rechunk(ds.isel(time=slice(0,72)), target_chunks={'y':96*2, 'x':132*2, 'time':72},\n", + " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "rechunked.execute(retries=10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", + "metadata": {}, + "outputs": [], + "source": [ + "zarr.convenience.consolidate_metadata(target_store)" + ] + }, + { + "cell_type": "markdown", + "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", + "metadata": {}, + "source": [ + "#### Explore the rechunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", + "metadata": {}, + "outputs": [], + "source": [ + "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", + "metadata": {}, + "outputs": [], + "source": [ + "ds2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cee33374-49d0-4607-a812-c9ed98eefb48", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.xarray\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET[:,2000,2000].hvplot(x='time')" + ] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/03_rechunk_works.ipynb b/201/old_notebooks/03_rechunk_works.ipynb new file mode 100644 index 0000000..6a444aa --- /dev/null +++ b/201/old_notebooks/03_rechunk_works.ipynb @@ -0,0 +1,515 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4108776-2095-4696-a4b6-fef7c2496fce", + "metadata": {}, + "source": [ + "# Rechunk the kerchunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "720e3f30-0708-48c0-bbbb-696383c2b2f1", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import fsspec.implementations.reference\n", + "import zarr\n", + "import xarray as xr\n", + "from pathlib import Path\n", + "\n", + "from rechunker import rechunk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c5f1ee6-fc59-4b3f-8d9e-0d618bd8dd75", + "metadata": {}, + "outputs": [], + "source": [ + "import rechunker\n", + "rechunker.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecf60b93-c561-4e2e-ad79-c409c919cdaf", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr\n", + "zarr.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "1a0babee-2b88-4713-abf6-32ff6ca7862a", + "metadata": {}, + "source": [ + "#### Start a Dask Gateway cluster\n", + "Use a custom helper function `ebd.start_dask_cluster` to set options on this cluster. We don't have to use this helper, it just cuts down on lines of code in notebooks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca9dd82d-0281-498b-8a28-61d8267d6a50", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "sys.path.append('/shared/users/rsignell/lib')\n", + "import ebdpy as ebd\n", + "os.environ['AWS_PROFILE'] = 'esip-qhub' # use env vars for AWS credentials to write\n", + "\n", + "client, cluster, gateway = ebd.start_dask_cluster(\n", + " profile=os.environ['AWS_PROFILE'],\n", + " worker_max=30,\n", + " region='us-west-2', \n", + " worker_profile='Medium Worker',\n", + " use_existing_cluster=True,\n", + " adaptive_scaling=False, \n", + " wait_for_cluster=False, \n", + " propagate_env=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4351541b-de66-4135-853e-16bfd52a39a6", + "metadata": {}, + "outputs": [], + "source": [ + "client" + ] + }, + { + "cell_type": "markdown", + "id": "d2a80a71-afdd-4a14-96b6-505d8ed41af4", + "metadata": {}, + "source": [ + "#### Open Kerchunked Dataset JSON for one year" + ] + }, + { + "cell_type": "raw", + "id": "3ffc9c71-aa44-4102-99ca-9dd70c07b28a", + "metadata": {}, + "source": [ + "year = '1984'\n", + "combined_json = f's3://esip-qhub/noaa/nwm/grid1km/combined_{year}.json'\n", + "\n", + "s_opts = {'requester_pays':True, 'skip_instance_cache':True}\n", + "r_opts = {'anon':True}\n", + "fs = fsspec.filesystem(\"reference\", fo=combined_json, ref_storage_args=s_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "de1aafae-7b66-4895-8d36-9beddbbb9aec", + "metadata": {}, + "source": [ + "#### Open Entire Kerchunked Dataset, lazy loaded from parquet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44f9fa14-658e-479f-a485-ac87d775f8a8", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip-qhub-public/nwm/LDAS-1k/lazyrefs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "391492ac-706e-471f-8b94-8b9f7c35b65b", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "fs = fsspec.implementations.reference.DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options={\"anon\": True},\n", + " remote_protocol=\"s3\", remote_options={\"anon\": True})\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={'time':1, 'y':3840, 'x':4608}, \n", + " backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c1df56b-d237-498b-8f2c-8272471dd24c", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "aaf145c1-e623-4b0e-9a2b-d77e0fcc505b", + "metadata": {}, + "source": [ + "#### Select high-priority vars only" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b973279-f918-4f88-b9c5-290a47d5a76f", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds[['ACCET', 'SNEQV', 'FSNO', 'crs']]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f22e4b63-fb26-4284-8fe2-a1bf36e2e0ac", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d34eca30-bf72-4a8a-8dfd-66f235c191da", + "metadata": {}, + "outputs": [], + "source": [ + "ds['ACCET'].isel(time=slice(0,72))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d511f0-f82e-4250-930c-145feff08d27", + "metadata": {}, + "outputs": [], + "source": [ + "ds.attrs" + ] + }, + { + "cell_type": "markdown", + "id": "e2c8e98a-1569-46a0-b85c-2e4d20916b4d", + "metadata": {}, + "source": [ + "#### set up zarr stores for temporary and final zarr stores on S3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86da688a-14bc-486b-87c0-c1d11a28de3f", + "metadata": {}, + "outputs": [], + "source": [ + "fs_write = fsspec.filesystem('s3', anon=False, skip_instance_cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a53b62f7-0df4-44b0-a03d-5dee35f2a00e", + "metadata": {}, + "outputs": [], + "source": [ + "temp_name = 'esip-qhub/testing/usgs/nwm1km.tmp'\n", + "target_name = 'esip-qhub/testing/usgs/nwm1km.zarr'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c043b20-3e43-435e-9e45-7023b178698a", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " fs_write.rm(temp_name, recursive=True)\n", + "except:\n", + " pass\n", + "try:\n", + " fs_write.rm(target_name, recursive=True)\n", + "except:\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94ffca87-dbb5-4a35-9dab-89270429cd9c", + "metadata": {}, + "outputs": [], + "source": [ + "temp_store = fs_write.get_mapper(temp_name)\n", + "target_store = fs_write.get_mapper(target_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9be12a7f-5737-4c63-b0e1-f80aaf4504ad", + "metadata": {}, + "outputs": [], + "source": [ + "ds = ds.drop('crs')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9989b3c-f8ea-4ec0-8781-1505842e0835", + "metadata": {}, + "outputs": [], + "source": [ + "a = int(len(ds.time)/(72))\n", + "a" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a945faa-d66c-44d1-a6ae-099e9ed53adf", + "metadata": {}, + "outputs": [], + "source": [ + "b = (len(ds.x) * len(ds.y))/((96*2)*(132*2))\n", + "b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cdfac4b-65f3-4f5c-8319-962d527cd32f", + "metadata": {}, + "outputs": [], + "source": [ + "a/b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "507f792b-e6b4-46e7-82c0-c2bd55cfde94", + "metadata": {}, + "outputs": [], + "source": [ + "#client.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76f39719-735f-4a8a-96ab-f50018a92441", + "metadata": {}, + "outputs": [], + "source": [ + "#from dask.distributed import Client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dee03ed-3fd8-446c-899f-4ac197ac08f2", + "metadata": {}, + "outputs": [], + "source": [ + "#client = Client(threads_per_worker=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecba9a21-ed99-4b31-97b5-55259c5b3b71", + "metadata": {}, + "outputs": [], + "source": [ + "#client.amm.start()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26f90202-40e2-410c-b05c-f4a312b9364e", + "metadata": {}, + "outputs": [], + "source": [ + "import zarr.storage\n", + "from numcodecs import Zstd\n", + "zarr.storage.default_compressor = Zstd(level=9)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "152c8ba0-63f9-42bf-81f8-e18969c9ed06", + "metadata": {}, + "outputs": [], + "source": [ + "(192 * 264 * 72)*4/1e6" + ] + }, + { + "cell_type": "markdown", + "id": "5ee745ca-7648-48b1-abc3-6c10992e1fbc", + "metadata": {}, + "source": [ + "#### Rechunk!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36b812ea-01ae-461f-b8b3-1eb7b3ea9711", + "metadata": {}, + "outputs": [], + "source": [ + "rechunked = rechunk(ds.isel(time=slice(0,72)), target_chunks={'y':96*2, 'x':132*2, 'time':72},\n", + " target_store=target_store, temp_store=temp_store, max_mem='2.8GiB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e86843c4-4f9e-4ec3-b1b6-f9969d22b3a4", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "rechunked.execute(retries=10)" + ] + }, + { + "cell_type": "raw", + "id": "aecea580-d6b2-46d3-84be-ed24354def9d", + "metadata": {}, + "source": [ + "def trim_memory() -> int:\n", + " libc = ctypes.CDLL('libc.so.6')\n", + " return libc.malloc_trim(0)" + ] + }, + { + "cell_type": "raw", + "id": "9d0e008c-62ed-4e5e-8084-69758ee93f03", + "metadata": {}, + "source": [ + "client.run(trim_memory)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a211f08-4c4f-46fa-8a9f-5231ec17d183", + "metadata": {}, + "outputs": [], + "source": [ + "zarr.convenience.consolidate_metadata(target_store)" + ] + }, + { + "cell_type": "markdown", + "id": "8ba15656-c501-4aae-b327-c6cb0d24dce7", + "metadata": {}, + "source": [ + "#### Explore the rechunked dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15466b5d-13f3-4d45-a09d-136e6ddcb907", + "metadata": {}, + "outputs": [], + "source": [ + "ds2 = xr.open_dataset(target_store, engine='zarr', chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91c1a356-5ad9-4f72-ae3e-85bb29f0f20b", + "metadata": {}, + "outputs": [], + "source": [ + "ds2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cee33374-49d0-4607-a812-c9ed98eefb48", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91926a5d-0e86-4b57-b5ef-53b9c3b51c03", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.xarray\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c23b9064-8f13-432d-85b4-cbe8ec5384a3", + "metadata": {}, + "outputs": [], + "source": [ + "ds2.ACCET[:,2000,2000].hvplot(x='time')" + ] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/04_combine_zarrs.ipynb b/201/old_notebooks/04_combine_zarrs.ipynb similarity index 100% rename from 201/04_combine_zarrs.ipynb rename to 201/old_notebooks/04_combine_zarrs.ipynb diff --git a/201/old_notebooks/05_explore_rechunked.ipynb b/201/old_notebooks/05_explore_rechunked.ipynb new file mode 100644 index 0000000..281ea28 --- /dev/null +++ b/201/old_notebooks/05_explore_rechunked.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "abac6797-4386-4f15-8b34-5e433dce5e64", + "metadata": {}, + "source": [ + "# Explore rechunked data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6286295f-dbc0-4757-a433-a03f8fa2bfd9", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "import hvplot.xarray" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "301d41a2-7e11-444c-93fd-59b524da4ae5", + "metadata": {}, + "outputs": [], + "source": [ + "fs_read = fsspec.filesystem('s3', requester_pays=True, skip_instance_cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a8eda8f-fc70-457a-8892-560ce1acc312", + "metadata": {}, + "outputs": [], + "source": [ + "rechunked_zarr = 's3://esip-qhub/testing/usgs/nwm1km.zarr'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd53fdba-ace6-474a-8ff2-5daa1cf9c108", + "metadata": {}, + "outputs": [], + "source": [ + "ds = xr.open_dataset(fs_read.get_mapper(rechunked_zarr), engine='zarr', chunks={})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4b41d42-ead0-42f7-8494-37ab43fa1ada", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "983ecff0-d0d9-4a2e-93d8-9d514bea8dd0", + "metadata": {}, + "outputs": [], + "source": [ + "%time\n", + "da = ds.ACCET[:144,1500,2000]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17123ac3-53ee-4b49-ac51-69ab2b53bf46", + "metadata": {}, + "outputs": [], + "source": [ + "da.hvplot(x='time', grid=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "66ff87fb-2f18-4973-89ad-7d37567110cd", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/NWM_1km_DFReferenceFileSystem-local.ipynb b/201/old_notebooks/NWM_1km_DFReferenceFileSystem-local.ipynb new file mode 100644 index 0000000..6d6de35 --- /dev/null +++ b/201/old_notebooks/NWM_1km_DFReferenceFileSystem-local.ipynb @@ -0,0 +1,235 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "05681bd5-20c7-4528-822c-6ca6826714d4", + "metadata": {}, + "source": [ + "# Open NWM 1km dataset as DFReferenceFileSystem \n", + "\n", + "Open dataset as a fsspec `DFReferenceFileSystem` filesystem by reading references from a collection of Parquet files: one file containing global metadata and coordinate variable references, and one file for each of the data variables. \n", + "\n", + "The big wins here are lazy-loading of the references for each variable, and the more efficient construction of the virtual fsspec filesystem from the Parquet files (JSON is slow to decode)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "584ab9a2-4f6b-4907-93b1-3d2b0786f601", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "from fsspec.implementations.reference import DFReferenceFileSystem\n", + "import xarray as xr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "732722cb-4430-4359-9014-eb9c551e7873", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem('s3', anon=True, \n", + " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6f5f293-ced5-44c2-8231-a77e22c451e1", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip/noaa/nwm/lazy_refs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "691c9634-cc24-407f-ae56-50d4247960a5", + "metadata": {}, + "outputs": [], + "source": [ + "print(f'Number of reference files: {len(fs.ls(s3_lazy_refs))}')\n", + "print(f'Total size of references: {fs.du(s3_lazy_refs)/1e9} GB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5f4c4da-27c1-4374-ba60-61315cd965b1", + "metadata": {}, + "outputs": [], + "source": [ + "r_opts = {'anon': True}\n", + "s3_lazy_refs = './combined.parq'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69e11199-c729-42a0-ad25-0cbbf97088df", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "fs2 = DFReferenceFileSystem(s3_lazy_refs, lazy=True, \n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs2.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd8ddfb0-7b57-43aa-98dc-b9a837e57542", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "04d02447-a134-45eb-978f-e0d392435dbb", + "metadata": {}, + "source": [ + "Examine a specific variable:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce2ec93e-a879-459f-804c-66a9f977db3f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "ds.TRAD" + ] + }, + { + "cell_type": "markdown", + "id": "151133ab-e6ee-4903-b23a-36bfef0286d9", + "metadata": {}, + "source": [ + "How big would the uncompressed size of the whole dataset be?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8dd5b70a-2585-4dce-b0b1-a2cd915c7952", + "metadata": {}, + "outputs": [], + "source": [ + "ds.nbytes/1e12 #TB" + ] + }, + { + "cell_type": "markdown", + "id": "7496c3b2-ae11-4af4-952f-18c3f3a3b73c", + "metadata": {}, + "source": [ + "Load some data at a specific time step. The first time a variable is accessed it will take longer as the references need to be loaded." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b0a2164-053c-4f84-a9b7-172bf3cd83a5", + "metadata": {}, + "outputs": [], + "source": [ + "%%time \n", + "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "26510252-7ec2-4e21-8ddf-aff2eca56793", + "metadata": {}, + "source": [ + "Loading data for another time step is much faster as the references are already loaded:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef01e203-f6cd-4c4e-ac3d-410afd5a4524", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "1f41f59f-12aa-4e4c-bf64-c61ecfe50db5", + "metadata": {}, + "source": [ + "Compute the mean over the domain:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd30a9a2-2264-4628-8826-8b965fe55ded", + "metadata": {}, + "outputs": [], + "source": [ + "da.mean().data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73fe200b-ee97-4f49-8d42-60d53d0a7160", + "metadata": {}, + "outputs": [], + "source": [ + "da.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "570bf4f1-5f9e-4cf9-8fc8-d0c8b1356e14", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/NWM_1km_DFReferenceFileSystem.ipynb b/201/old_notebooks/NWM_1km_DFReferenceFileSystem.ipynb new file mode 100644 index 0000000..b216924 --- /dev/null +++ b/201/old_notebooks/NWM_1km_DFReferenceFileSystem.ipynb @@ -0,0 +1,235 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "05681bd5-20c7-4528-822c-6ca6826714d4", + "metadata": {}, + "source": [ + "# Open NWM 1km dataset as DFReferenceFileSystem \n", + "\n", + "Open dataset as a fsspec `DFReferenceFileSystem` filesystem by reading references from a collection of Parquet files: one file containing global metadata and coordinate variable references, and one file for each of the data variables. \n", + "\n", + "The big wins here are lazy-loading of the references for each variable, and the more efficient construction of the virtual fsspec filesystem from the Parquet files (JSON is slow to decode)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "584ab9a2-4f6b-4907-93b1-3d2b0786f601", + "metadata": {}, + "outputs": [], + "source": [ + "import fsspec\n", + "from fsspec.implementations.reference import DFReferenceFileSystem\n", + "import xarray as xr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "732722cb-4430-4359-9014-eb9c551e7873", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem('s3', anon=True, \n", + " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6f5f293-ced5-44c2-8231-a77e22c451e1", + "metadata": {}, + "outputs": [], + "source": [ + "s3_lazy_refs = 's3://esip/noaa/nwm/lazy_refs'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "691c9634-cc24-407f-ae56-50d4247960a5", + "metadata": {}, + "outputs": [], + "source": [ + "print(f'Number of reference files: {len(fs.ls(s3_lazy_refs))}')\n", + "print(f'Total size of references: {fs.du(s3_lazy_refs)/1e9} GB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5f4c4da-27c1-4374-ba60-61315cd965b1", + "metadata": {}, + "outputs": [], + "source": [ + "r_opts = {'anon': True}\n", + "t_opts = {'anon': True, 'client_kwargs':{'endpoint_url':'https://ncsa.osn.xsede.org'}}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69e11199-c729-42a0-ad25-0cbbf97088df", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "fs2 = DFReferenceFileSystem(s3_lazy_refs, lazy=True, target_options=t_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs2.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd8ddfb0-7b57-43aa-98dc-b9a837e57542", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "04d02447-a134-45eb-978f-e0d392435dbb", + "metadata": {}, + "source": [ + "Examine a specific variable:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce2ec93e-a879-459f-804c-66a9f977db3f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "ds.TRAD" + ] + }, + { + "cell_type": "markdown", + "id": "151133ab-e6ee-4903-b23a-36bfef0286d9", + "metadata": {}, + "source": [ + "How big would the uncompressed size of the whole dataset be?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8dd5b70a-2585-4dce-b0b1-a2cd915c7952", + "metadata": {}, + "outputs": [], + "source": [ + "ds.nbytes/1e12 #TB" + ] + }, + { + "cell_type": "markdown", + "id": "7496c3b2-ae11-4af4-952f-18c3f3a3b73c", + "metadata": {}, + "source": [ + "Load some data at a specific time step. The first time a variable is accessed it will take longer as the references need to be loaded." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b0a2164-053c-4f84-a9b7-172bf3cd83a5", + "metadata": {}, + "outputs": [], + "source": [ + "%%time \n", + "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "26510252-7ec2-4e21-8ddf-aff2eca56793", + "metadata": {}, + "source": [ + "Loading data for another time step is much faster as the references are already loaded:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef01e203-f6cd-4c4e-ac3d-410afd5a4524", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "1f41f59f-12aa-4e4c-bf64-c61ecfe50db5", + "metadata": {}, + "source": [ + "Compute the mean over the domain:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd30a9a2-2264-4628-8826-8b965fe55ded", + "metadata": {}, + "outputs": [], + "source": [ + "da.mean().data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73fe200b-ee97-4f49-8d42-60d53d0a7160", + "metadata": {}, + "outputs": [], + "source": [ + "da.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "570bf4f1-5f9e-4cf9-8fc8-d0c8b1356e14", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/201/old_notebooks/NWM_1km_ReferenceFileSystem.ipynb b/201/old_notebooks/NWM_1km_ReferenceFileSystem.ipynb new file mode 100644 index 0000000..1801006 --- /dev/null +++ b/201/old_notebooks/NWM_1km_ReferenceFileSystem.ipynb @@ -0,0 +1,206 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6e37266f-ef99-4ccc-a93c-1e8b8e346b7a", + "metadata": {}, + "source": [ + "# Open NWM 1km dataset as ReferenceFileSystem \n", + "Create a `ReferenceFileSystem` object by reading references from a 9.8GB combined JSON file. \n", + "\n", + "Opening the dataset in Xarray takes more than 10 minutes, mostly due to decoding the giant JSON file. It also requires more than 50GB of RAM to run, more than 8GB or 16GB typically available to users. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f32fec2-df41-4260-b081-d5b379eaa922", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import fsspec\n", + "import xarray as xr\n", + "from fsspec.implementations.reference import ReferenceFileSystem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65beb48e-6988-42e4-b12f-f22f6d56f37a", + "metadata": {}, + "outputs": [], + "source": [ + "fs = fsspec.filesystem('s3', anon=True, \n", + " client_kwargs={'endpoint_url':'https://ncsa.osn.xsede.org'})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26db3d84-d8f0-49b0-aefe-01275504bc4a", + "metadata": {}, + "outputs": [], + "source": [ + "url = 's3://esip/noaa/nwm/grid1km/LDAS_combined.json'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33a8c6f2-7998-4f35-a86a-263a28881c92", + "metadata": {}, + "outputs": [], + "source": [ + "fs.size(url)/1e9 # JSON size in GB" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "401182fe-69a9-418b-a6b5-6be0f50dcdb6", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "s_opts = {'anon':True, 'client_kwargs':{'endpoint_url':'https://ncsa.osn.xsede.org'}}\n", + "r_opts = {'anon':True}\n", + "fs = ReferenceFileSystem(url, ref_storage_args=s_opts,\n", + " remote_protocol='s3', remote_options=r_opts)\n", + "m = fs.get_mapper(\"\")\n", + "ds = xr.open_dataset(m, engine=\"zarr\", chunks={}, backend_kwargs=dict(consolidated=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c527f679-927d-411e-b72f-5a304725c729", + "metadata": {}, + "outputs": [], + "source": [ + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "0867e1a7-ad9c-492b-ace9-49efbcbbbd33", + "metadata": {}, + "source": [ + "Examine a specific variable:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "729e2fb8-b2d5-4968-adcd-3d0f77c3b25f", + "metadata": {}, + "outputs": [], + "source": [ + "ds.TRAD" + ] + }, + { + "cell_type": "markdown", + "id": "3ca7794f-930f-4964-9fef-3fc30ec5eda3", + "metadata": {}, + "source": [ + "Compute the uncompressed size of this dataset in TB:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67960b52-5600-4b71-963e-93701cffbd5b", + "metadata": {}, + "outputs": [], + "source": [ + "ds.nbytes/1e12 " + ] + }, + { + "cell_type": "markdown", + "id": "b3af81f4-d84b-4f19-a1f5-5815304c191f", + "metadata": {}, + "source": [ + "Loading data for a particular time step is fast as the references are already loaded:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af73254d-bb31-47d8-b7eb-6d12e7735bdf", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "da = ds.TRAD.sel(time='1990-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "e6112c50-cea2-49ef-8e97-e1dda4222c4a", + "metadata": {}, + "source": [ + "Loading data for another time step takes about the same amount of time:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d85d7899-f31e-4970-9c4c-fd04dc7cd8ce", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "da = ds.TRAD.sel(time='2015-01-01 00:00').load()" + ] + }, + { + "cell_type": "markdown", + "id": "4ae8eede-2838-4df0-9360-ad1263a43212", + "metadata": {}, + "source": [ + "Compute the mean over the domain:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6ae3a97-3bec-46ce-8377-0bd6ba6b699a", + "metadata": {}, + "outputs": [], + "source": [ + "da.mean().data" + ] + } + ], + "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.12.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/101/OpenDAP_to_S3.ipynb b/201/old_notebooks/OpenDAP_to_S3.ipynb similarity index 99% rename from 101/OpenDAP_to_S3.ipynb rename to 201/old_notebooks/OpenDAP_to_S3.ipynb index 3be3694..db90961 100644 --- a/101/OpenDAP_to_S3.ipynb +++ b/201/old_notebooks/OpenDAP_to_S3.ipynb @@ -335,7 +335,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/AWS.ipynb b/AWS.ipynb index fa34e8f..90cab61 100644 --- a/AWS.ipynb +++ b/AWS.ipynb @@ -20,8 +20,8 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "1117a21a-b7f7-4374-a5bd-15bca24c11a1", + "execution_count": 10, + "id": "858d22f3-065c-41d3-8974-06afc7ada04c", "metadata": {}, "outputs": [], "source": [ @@ -33,8 +33,9 @@ " os.path.expanduser('~/.aws/credentials') \n", " # default location... if yours is elsewhere, change this.\n", ")\n", - "_profile_nm = os.environ.get('AWS_PROFILE', 'osn-rsignellbucket2')\n", - "_endpoint = os.environ.get('AWS_S3_ENDPOINT', 'https://renc.osn.xsede.org')\n", + "_profile_nm = os.environ.get('AWS_PROFILE', 'osn-hytest-scratch')\n", + "_endpoint = os.environ.get('AWS_S3_ENDPOINT', 'https://usgs.osn.mghpcc.org/')\n", + "\n", "# Set environment vars based on parsed awsconfig\n", "try:\n", " os.environ['AWS_ACCESS_KEY_ID'] = awsconfig[_profile_nm]['aws_access_key_id']\n", @@ -53,14 +54,6 @@ "source": [ "It is extremely important that you **never** set any of the access keys or secrets directly -- we never want to include any of those values as string literals in any code. This code is committed to a public repository, so doing this would essentially publish those secrets. **ALWAYS** parse the config file as demonstrated above in order to obtain the access key and the secret access key. " ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f473e813-dfff-4e91-a87c-bf7f74a414e8", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -79,7 +72,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/_config.yml b/_config.yml index 5f9fd43..2325fa4 100755 --- a/_config.yml +++ b/_config.yml @@ -12,7 +12,7 @@ only_build_toc_files: true execute: execute_notebooks: cache timeout: 600 - allow_errors: false + allow_errors: true repository: url: https://github.com/gzt5142/DaskDataChunking diff --git a/_toc.yml b/_toc.yml index c1619d5..b831787 100755 --- a/_toc.yml +++ b/_toc.yml @@ -2,20 +2,26 @@ format: jb-book root: index chapters: -- file: about/index - file: 101/index sections: - file: 101/WhyChunk - - file: 101/ExamineSourceData - - file: 101/EffectSizeShape - - file: 101/OpenDAP_to_S3 - - file: 101/Compression - - file: 101/SecondaryExample + - file: 101/ExamineDataChunking + - file: 101/BasicsShapeSize + - file: 101/WriteChunkedFiles + - file: 101/Rechunking +- file: 201/index + sections: + - file: 201/RechunkingwithDask + - file: 201/CreateVirtualZarr + - file: 201/IncludeCRSinZarr + - file: 201/OptimalChunkSelection + # - file: 201/IcechunkTutorial - file: back/index sections: - - file: helpers.md - sections: - - file: utils - - file: AWS - - file: StartNebariCluster - - file: back/Appendix_A + # - file: helpers.md + # sections: + # - file: utils + # - file: AWS + # - file: StartNebariCluster + - file: back/Glossary + - file: back/AdditionalResources diff --git a/about/index.md b/about/index.md deleted file mode 100644 index 4a52b3a..0000000 --- a/about/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# About This Project - -who, what, objectives, etc. \ No newline at end of file diff --git a/back/AdditionalResources.md b/back/AdditionalResources.md new file mode 100644 index 0000000..4e94dad --- /dev/null +++ b/back/AdditionalResources.md @@ -0,0 +1,15 @@ +# Additional Resources + +As we can't cover all possible material on chunking in one series of notebooks, +listed below are some links to additional resources on chunking that can be referred to for additional information. + +- [Zarr docs on chunk optimization](https://zarr.readthedocs.io/en/stable/tutorial.html#chunk-optimizations) +- [Dask docs on chunk selection](https://docs.dask.org/en/stable/array-chunks.html) +- [Rechunker docs](https://rechunker.readthedocs.io/en/latest/index.html) +- [Kerchunk docs](https://fsspec.github.io/kerchunk/index.html) +- [VirtualiZarr docs](https://virtualizarr.readthedocs.io/en/stable/index.html) +- [Tutorial notebook on adding CRS to Zarr](https://code.usgs.gov/wma/nhgf/geo-data-portal/gdp_data_processing/-/blob/main/workflows/opendap/CIDA/crs_notebooks/tutorial.ipynb) +- [UCAR Blog on Difference between NetCDF and Zarr](https://www.unidata.ucar.edu/blogs/news/entry/netcdf-vs-zarr-an-incomplete) +- [UCAR Blog on Why Chunk Data](https://www.unidata.ucar.edu/blogs/developer/en/entry/chunking_data_why_it_matters) +- [UCAR Blog on Choosing Chunk Shapes](https://www.unidata.ucar.edu/blogs/developer/en/entry/chunking_data_choosing_shapes) +- [Project Pythia Cookbook on Kerchunk with Dask](https://projectpythia.org/kerchunk-cookbook/README.html) \ No newline at end of file diff --git a/back/Glossary.md b/back/Glossary.md index ca3c827..fe0b371 100644 --- a/back/Glossary.md +++ b/back/Glossary.md @@ -1 +1,36 @@ # Glossary + +A glossary of common terms used throughout Jupyter Book. + +```{glossary} +**Chunk** + Smaller, more manageable pieces of a larger dataset. + +**Chunking** + The process of breaking down large amounts of data into smaller, more manageable pieces. + +**Chunk shape** + The actual shape of a chunk, specifying the number of elements in each dimension. + +**Chunk size** + The size of the chunk in terms of memory, which depends on the chunk shape. + +**Coordinate Reference System** + A framework used to precisely measure locations on the surface of Earth as coordinates. + +**Larger-than-memory** + A dataset whose memory footprint is too large to fit into memory all at once. + +**Partial Chunk** + The final chunk along a dimensions of a dataset that is not completely full of data due to the chosen chunk shape not being an integer divisor of the dataset's dimensions. + +**Rechunking** + The process of changing the current chunk shape of a dataset to another chunk shape. + +**Stored chunks** + The chunks that are physically stored on disk. + +**Virtual Zarr Store** + A virtual representation of a Zarr store generated by mapping any number of real datasets in individual files (e.g., NetCDF/HDF5, GRIB2, TIFF) together into a single, sliceable dataset via an interface layer, which contains information about the original files (e.g., chunking, compression, etc.). + +``` \ No newline at end of file diff --git a/env.yml b/env.yml index 9910257..2f7c369 100644 --- a/env.yml +++ b/env.yml @@ -1,12 +1,12 @@ channels: - conda-forge dependencies: -- python=3.10 +- python - adlfs - aiobotocore - birdy - black -- bokeh < 3.0 +- bokeh - boto3 - cdsapi - cf_xarray @@ -16,7 +16,7 @@ dependencies: - coiled - curl>7.79.0 - dask-geopandas -- dask-gateway==2022.4.0 +- dask-gateway - datashader - datacube - dask-geopandas @@ -25,7 +25,7 @@ dependencies: - erddapy - fastparquet - folium -- fsspec==2023.3.0 +- fsspec - gcsfs - gdal - gdptools @@ -64,7 +64,7 @@ dependencies: - nbgitpuller - nbstripout - nco -- netcdf4 == 1.6.0 +- netcdf4 - numba - numcodecs - odc-algo @@ -136,10 +136,9 @@ dependencies: - ghp-import - jsonschema-with-format-nongpl - webcolors +- virtualizarr - pip: - - kerchunk @ git+https://github.com/fsspec/kerchunk@main - - rechunker @ git+https://github.com/pangeo-data/rechunker@master - - sparse @ git+https://github.com/jcmgray/sparse@master -description: '' -name: pangeofu -prefix: null \ No newline at end of file + - kerchunk + - rechunker + - sparse +name: chunking diff --git a/index.md b/index.md index dc7909a..4adf76c 100755 --- a/index.md +++ b/index.md @@ -1,17 +1,24 @@ -# Data Chunking +# A Data Chunking Tutorial -"Chunking" large datasets is an essential workflow in the data peparation stage of -analysis. Some of the large datasets are written with a chunking pattern which -is optimized for writing (i.e. how they are created -- model outputs, etc), and -performs poorly for reading. This depends on the analysis. +If you have found your way here, then you are probably interested in learning more about data chunking. +In this tutorial, we will go over all levels of information on data chunking, +from the basic introductions on the topic to complex methods of selecting optimal chunk sizes and rechunking on the cloud. +Much of what is covered in this tutorial replicates concepts covered in a variety of materials that we cite as we go. +However, that material has been adapted to use data that looks like data you might encounter in a HyTEST workflow. -Re-chunking is a useful strategy to re-write the dataset in such a way to optimize -a particular kind of analysis (i.e. time-series vs spatial). +The content is split into two primary section: + - [Introduction to Chunking](101/index.md) + - [Advanced Topics in Chunking](201/index.md) +In [Introduction to Chunking](101/index.md), we discuss all of the basic introductory topics associated with chunking. +As for [Advanced Topics in Chunking](201/index.md), we dive into some more advanced topics related to chunking, +which require a firm understanding of introductory topics. + +Feel free to read this tutorial in order (which has been set up for those new to chunking) or jump directly to the topic that interests you: ```{tableofcontents} ``` ------ -Download the environment YAML file [here](env.yml) +If you find any issues or errors in this tutorial or have any ideas for material that should be included, +please open an issue using GitHub icon in the upper right.