diff --git a/previews/PR437/404.html b/previews/PR437/404.html new file mode 100644 index 00000000..0fdec238 --- /dev/null +++ b/previews/PR437/404.html @@ -0,0 +1,22 @@ + + + + + + 404 | YAXArrays.jl + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/cache.html b/previews/PR437/UserGuide/cache.html new file mode 100644 index 00000000..1b877048 --- /dev/null +++ b/previews/PR437/UserGuide/cache.html @@ -0,0 +1,29 @@ + + + + + + Caching YAXArrays | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Caching YAXArrays

For some applications like interactive plotting of large datasets it can not be avoided that the same data must be accessed several times. In these cases it can be useful to store recently accessed data in a cache. In YAXArrays this can be easily achieved using the cache function. For example, if we open a large dataset from a remote source and want to keep data in a cache of size 500MB one can use:

julia
using YAXArrays, Zarr
+ds = open_dataset("path/to/source")
+cachesize = 500 #MB
+cache(ds,maxsize = cachesize)

The above will wrap every array in the dataset into its own cache, where the 500MB are distributed equally across datasets. Alternatively individual caches can be applied to single YAXArrays

julia
yax = ds.avariable
+cache(yax,maxsize = 1000)
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/chunk.html b/previews/PR437/UserGuide/chunk.html new file mode 100644 index 00000000..3de8fe02 --- /dev/null +++ b/previews/PR437/UserGuide/chunk.html @@ -0,0 +1,122 @@ + + + + + + Chunk YAXArrays | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Chunk YAXArrays

Thinking about chunking is important when it comes to analyzing your data, because in most situations this will not fit into memory, hence having the fastest read access to it is crucial for your workflows. For example, for geo-spatial data do you want fast access on time or space, or... think about it.

To determine the chunk size of the array representation on disk, call the setchunks function prior to saving.

Chunking YAXArrays

julia
using YAXArrays, Zarr
+a = YAXArray(rand(10,20))
+a_chunked = setchunks(a, (5,10))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

And the saved file is also splitted into Chunks.

julia
f = tempname()
+savecube(a_chunked, f, backend=:zarr)
+Cube(f).chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Alternatively chunk sizes can be given by dimension name, so the following results in the same chunks:

julia
a_chunked = setchunks(a, (Dim_2=10, Dim_1=5))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Chunking Datasets

Setchunks can also be applied to a Dataset.

Set Chunks by Axis

Set chunk size for each axis occuring in a Dataset. This will be applied to all variables in the dataset:

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds, Dict("Dim_1"=>5, "Dim_2"=>10, "Dim_3"=>2))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

Saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking by Variable

The following will set the chunk size for each Variable separately and results in exactly the same chunking as the example above

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds,(x = (5,10), y = Dict("Dim_1"=>5), z = (Dim_1 = 5, Dim_2 = 10, Dim_3 = 2)))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking for all variables

The following code snippet only works when all member variables of the dataset have the same shape and sets the output chunks for all arrays.

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10,20)), z = YAXArray(rand(10,20)))
+dschunked = setchunks(ds,(5,10))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:1)   (1:5, 11:20, 1:1)
+ (6:10, 1:10, 1:1)  (6:10, 11:20, 1:1)
+
+[:, :, 2] =
+ (1:5, 1:10, 2:2)   (1:5, 11:20, 2:2)
+ (6:10, 1:10, 2:2)  (6:10, 11:20, 2:2)
+
+[:, :, 3] =
+ (1:5, 1:10, 3:3)   (1:5, 11:20, 3:3)
+ (6:10, 1:10, 3:3)  (6:10, 11:20, 3:3)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+
+Variables: 
+x, y, z

Suggestions on how to improve or add to these examples is welcome.

+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/combine.html b/previews/PR437/UserGuide/combine.html new file mode 100644 index 00000000..198a2992 --- /dev/null +++ b/previews/PR437/UserGuide/combine.html @@ -0,0 +1,52 @@ + + + + + + Combine YAXArrays | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Combine YAXArrays

Data is often scattered across multiple files and corresponding arrays, e.g. one file per time step. This section describes methods on how to combine them into a single YAXArray.

cat along an existing dimension

Here we use cat to combine two arrays consisting of data from the first and the second half of a year into one single array containing the whole year. We glue the arrays along the first dimension using dims = 1: The resulting array whole_year still has one dimension, i.e. time, but with 12 instead of 6 elements.

julia
using YAXArrays
+
+first_half = YAXArray((Dim{:time}(1:6),), rand(6))
+second_half = YAXArray((Dim{:time}(7:12),), rand(6))
+whole_year = cat(first_half, second_half, dims = 1)
╭────────────────────────────────╮
+│ 12-element YAXArray{Float64,1} │
+├────────────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time Sampled{Int64} [1, 2, …, 11, 12] ForwardOrdered Regular Points
+├───────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├──────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└───────────────────────────────────────────────────────────────────────┘

concatenatecubes to a new dimension

Here we use concatenatecubes to combine two arrays of different variables that have the same dimensions. The resulting array combined has an additional dimension variable indicating from which array the element values originates. Note that using a Dataset instead is a more flexible approach in handling different variables.

julia
using YAXArrays
+
+temperature = YAXArray((Dim{:time}(1:6),), rand(6))
+precipitation = YAXArray((Dim{:time}(1:6),), rand(6))
+cubes = [temperature,precipitation]
+var_axis = Dim{:variable}(["temp", "prep"])
+combined = concatenatecubes(cubes, var_axis)
╭─────────────────────────╮
+│ 6×2 YAXArray{Float64,2} │
+├─────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time     Sampled{Int64} 1:6 ForwardOrdered Regular Points,
+  → variable Categorical{String} ["temp", "prep"] ReverseOrdered
+├────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└────────────────────────────────────────────────────────────────┘
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/compute.html b/previews/PR437/UserGuide/compute.html new file mode 100644 index 00000000..9533a856 --- /dev/null +++ b/previews/PR437/UserGuide/compute.html @@ -0,0 +1,289 @@ + + + + + + Compute YAXArrays | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Compute YAXArrays

This section describes how to create new YAXArrays by performing operations on them.

  • Use arithmetics to add or multiply numbers to each element of an array

  • Use map to apply a more complex functions to every element of an array

  • Use mapslices to reduce a dimension, e.g. to get the mean over all time steps

  • Use mapCube to apply complex functions on an array that may change any dimensions

Let's start by creating an example dataset:

julia
using YAXArrays
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Modify elements of a YAXArray

julia
a[1,2,3]
0.4802525933892837
julia
a[1,2,3] = 42
42
julia
a[1,2,3]
42.0

WARNING

Some arrays, e.g. those saved in a cloud object storage are immutable making any modification of the data impossible.

Arithmetics

Add a value to all elements of an array and save it as a new array:

julia
a2 = a .+ 5
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2[1,2,3] == a[1,2,3] + 5
true

map

Apply a function on every element of an array individually:

julia
offset = 5
+map(a) do x
+    (x + offset) / 2 * 3
+end
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This keeps all dimensions unchanged. Note, that here we can not access neighboring elements. In this case, we can use mapslices or mapCube instead. Each element of the array is processed individually.

The code runs very fast, because map applies the function lazily. Actual computation will be performed only on demand, e.g. when elements were explicitly requested or further computations were performed.

mapslices

Reduce the time dimension by calculating the average value of all points in time:

julia
import Statistics: mean
+mapslices(mean, a, dims="Time")
╭───────────────────────────────────────────╮
+│ 10×15 YAXArray{Union{Missing, Float64},2} │
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘

There is no time dimension left, because there is only one value left after averaging all time steps. We can also calculate spatial means resulting in one value per time step:

julia
mapslices(mean, a, dims=("lat", "lon"))
╭────────────────────────────────────────────────╮
+│ 30-element YAXArray{Union{Missing, Float64},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

mapCube

mapCube is the most flexible way to apply a function over subsets of an array. Dimensions may be added or removed.

Operations over several YAXArrays

Here, we will define a simple function, that will take as input several YAXArrays. But first, let's load the necessary packages.

julia
using YAXArrays, Zarr
+using Dates

Define function in space and time

julia
f(lo, la, t) = (lo + la + Dates.dayofyear(t))
f (generic function with 1 method)

now, mapCube requires this function to be wrapped as follows

julia
function g(xout, lo, la, t)
+    xout .= f.(lo, la, t)
+end
g (generic function with 1 method)

INFO

Note the . after f, this is because we will slice across time, namely, the function is broadcasted along this dimension.

Here, we do create YAXArrays only with the desired dimensions as

julia
julia> lon = YAXArray(Dim{:lon}(range(1, 15)))
╭──────────────────────────────╮
+15-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lon Sampled{Int64} 1:15 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 120.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> lat = YAXArray(Dim{:lat}(range(1, 10)))
╭──────────────────────────────╮
+10-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 80.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

And a time Cube's Axis

julia
tspan = Date("2022-01-01"):Day(1):Date("2022-01-30")
+time = YAXArray(Dim{:time}(tspan))
╭─────────────────────────────╮
+│ 30-element YAXArray{Date,1} │
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the following can be extended to arbitrary YAXArrays with additional data and dimensions.

Let's generate a new cube using mapCube and saving the output directly into disk.

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims(), InDims(), InDims("time")),
+           outdims = OutDims("time", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+30×15×10 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

"time axis goes first"

Note that currently the time axis in the output cube goes first.

Check that it is working

julia
julia> gen_cube.data[1, :, :]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

but, we can generate a another cube with a different output order as follows

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims("lon"), InDims(), InDims()),
+           outdims = OutDims("lon", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+15×10×30 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

INFO

Note that now the broadcasted dimension is lon.

we can see this by slicing on the last dimension now

julia
gen_cube.data[:, :, 1]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

which outputs the same as the gen_cube.data[1, :, :] called above.

Creating a vector array

Here we transform a raster array with spatial dimension lat and lon into a vector array having just one spatial dimension i.e. region. First, create the raster array:

julia
using YAXArrays
+using DimensionalData
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+raster_arr = YAXArray(axlist, data)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Then, create a Matrix with the same spatial dimensions indicating to which region each point belongs to:

julia
regions_mat = map(Iterators.product(raster_arr.lon, raster_arr.lat)) do (lon, lat)
+    1 <= lon < 10 && 1 <= lat < 5 && return "A"
+    1 <= lon < 10 && 5 <= lat < 10 && return "B"
+    10 <= lon < 15 && 1 <= lat < 5 && return "C"
+    return "D"
+end
+regions_mat = DimArray(regions_mat, (raster_arr.lon, raster_arr.lat))
╭──────────────────────────╮
+│ 10×15 DimArray{String,2} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0   1.28571  1.57143  1.85714  …  4.14286  4.42857  4.71429  5.0
+  1.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  2.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  3.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  4.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  5.0   "A"   "A"      "A"      "A"     …   "A"      "A"      "A"      "B"
+  6.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  7.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  8.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  9.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+ 10.0   "C"   "C"      "C"      "C"     …   "C"      "C"      "C"      "D"

which has the same spatial dimensions as the raster array at any given point in time:

julia
DimArray(raster_arr[time = 1])
╭───────────────────────────╮
+│ 10×15 DimArray{Float64,2} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0        1.28571   1.57143    …  4.42857   4.71429    5.0
+  1.0  0.0701065  0.963886  0.515763      0.324908  0.675918   0.745998
+  2.0  0.354703   0.231698  0.371974      0.809426  0.582551   0.879515
+  3.0  0.0696778  0.96757   0.440296      0.606578  0.95716    0.21498
+  ⋮                                    ⋱                       ⋮
+  8.0  0.417033   0.546641  0.788483      0.139694  0.879286   0.945109
+  9.0  0.877062   0.210902  0.0504114     0.831314  0.0645807  0.0443643
+ 10.0  0.880753   0.587901  0.0450445  …  0.634789  0.202429   0.697013

Now we calculate the list of corresponding points for each region. This will be re-used for each point in time during the final mapCube. In addition, this avoids the allocation of unnecessary memory.

julia
regions = ["A", "B", "C", "D"]
+points_of_regions = map(enumerate(regions)) do (i,region)
+    region => findall(isequal(region), regions_mat)
+end |> Dict |> sort
OrderedCollections.OrderedDict{String, Vector{CartesianIndex{2}}} with 4 entries:
+  "A" => [CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), Car…
+  "B" => [CartesianIndex(1, 15), CartesianIndex(2, 15), CartesianIndex(3, 15), …
+  "C" => [CartesianIndex(10, 1), CartesianIndex(10, 2), CartesianIndex(10, 3), …
+  "D" => [CartesianIndex(10, 15)]

Finally, we can transform the entire raster array:

julia
vector_array = mapCube(
+    raster_arr,
+    indims=InDims("lon", "lat"),
+    outdims=OutDims(Dim{:region}(regions))
+) do xout, xin
+    for (region_pos, points) in enumerate(points_of_regions.vals)
+        # aggregate values of points in the current region at the current date
+        xout[region_pos] = sum(view(xin, points))
+    end
+end
╭──────────────────────────────────────────╮
+│ 4×30 YAXArray{Union{Missing, Float64},2} │
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+  ↓ region Categorical{String} ["A", "B", "C", "D"] ForwardOrdered,
+  → time   Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 960.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

This gives us a vector array with only one spatial dimension, i.e. the region. Note that we still have 30 points in time. The transformation was applied for each date separately.

Hereby, xin is a 10x15 array representing a map at a given time and xout is a 4 element vector of missing values initially representing the 4 regions at that date. Then, we set each output element by the sum of all corresponding points

Distributed Computation

All map methods apply a function on all elements of all non-input dimensions separately. This allows to run each map function call in parallel. For example, we can execute each date of a time series in a different CPU thread during spatial aggregation.

The following code does a time mean over all grid points using multiple CPUs of a local machine:

julia
using YAXArrays
+using Dates
+using Distributed
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
+
+addprocs(2)
+
+@everywhere begin
+  using YAXArrays
+  using Zarr
+  using Statistics
+end
+
+@everywhere function mymean(output, pixel)
+  @show "doing a mean"
+     output[:] .= mean(pixel)
+end
+
+mapCube(mymean, a, indims=InDims("time"), outdims=OutDims())

In the last example, mapCube was used to map the mymean function. mapslices is a convenient function that can replace mapCube, where you can omit defining an extra function with the output argument as an input (e.g. mymean). It is possible to simply use mapslice

julia
mapslices(mean  skipmissing, a, dims="time")

It is also possible to distribute easily the workload on a cluster, with little modification to the code. To do so, we use the ClusterManagers package.

julia
using Distributed
+using ClusterManagers
+addprocs(SlurmManager(10))
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/convert.html b/previews/PR437/UserGuide/convert.html new file mode 100644 index 00000000..57063684 --- /dev/null +++ b/previews/PR437/UserGuide/convert.html @@ -0,0 +1,102 @@ + + + + + + Convert YAXArrays | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Convert YAXArrays

This section describes how to convert variables from types of other Julia packages into YAXArrays and vice versa.

WARNING

YAXArrays is designed to work with large datasets that are way larger than the memory. However, most types are designed to work in memory. Those conversions are only possible if the entire dataset fits into memory. In addition, metadata might be lost during conversion.

Convert Base.Array

Convert Base.Array to YAXArray:

julia
using YAXArrays
+
+m = rand(5,10)
+a = YAXArray(m)
╭──────────────────────────╮
+│ 5×10 YAXArray{Float64,2} │
+├──────────────────────────┴──────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 400.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Convert YAXArray to Base.Array:

julia
m2 = collect(a.data)
5×10 Matrix{Float64}:
+ 0.795153  0.0264902  0.0804585  0.0910572  …  0.606617  0.558735   0.979087
+ 0.318029  0.777976   0.351172   0.442589      0.934129  0.279857   0.391744
+ 0.290659  0.478507   0.611842   0.339863      0.364872  0.0391939  0.296448
+ 0.899311  0.365121   0.912882   0.0746545     0.197869  0.306701   0.634033
+ 0.15752   0.818753   0.14209    0.298586      0.396465  0.187958   0.027089

Convert Raster

A Raster as defined in Rasters.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types:

julia
using Rasters
+
+lon, lat = X(25:1:30), Y(25:1:30)
+time = Ti(2000:2024)
+ras = Raster(rand(lon, lat, time))
+a = YAXArray(dims(ras), ras.data)
╭────────────────────────────╮
+│ 6×6×25 YAXArray{Float64,3} │
+├────────────────────────────┴────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────── file size ┤ 
+  file size: 7.03 KB
+└─────────────────────────────────────────────────────────────┘
julia
ras2 = Raster(a)
╭──────────────────────────╮
+│ 6×6×25 Raster{Float64,3} │
+├──────────────────────────┴──────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (2000, 2024))
+
+└─────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26           27         28          29          30
+ 25     0.460901   0.448599     0.310425   0.333059    0.651427    0.865549
+ 26     0.294336   0.162016     0.159973   0.245293    0.0536221   0.810377
+ 27     0.764827   0.317333     0.536345   0.851063    0.932986    0.859051
+ 28     0.728649   0.885421     0.438166   0.0328466   0.21626     0.517644
+ 29     0.758648   0.00939122   0.864794   0.512244    0.988263    0.423459
+ 30     0.874109   0.743847     0.410173   0.85881     0.103772    0.81669

Convert DimArray

A DimArray as defined in DimensionalData.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types.

Convert DimArray to YAXArray:

julia
using DimensionalData
+using YAXArrayBase
+
+dim_arr = rand(X(1:5), Y(10.0:15.0), metadata = Dict{String, Any}())
+a = yaxconvert(YAXArray, dim_arr)
╭─────────────────────────╮
+│ 5×6 YAXArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────┘

Convert YAXArray to DimArray:

julia
dim_arr2 = yaxconvert(DimArray, a)
╭─────────────────────────╮
+│ 5×6 DimArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────┘
+ ↓ →  10.0       11.0       12.0        13.0       14.0        15.0
+ 1     0.748974   0.118396   0.645149    0.956491   0.598932    0.230696
+ 2     0.58618    0.103921   0.0589974   0.891881   0.305112    0.434868
+ 3     0.692366   0.613363   0.120628    0.586712   0.936887    0.769308
+ 4     0.823196   0.680373   0.123279    0.875862   0.0764503   0.903606
+ 5     0.372063   0.775785   0.0750832   0.689982   0.747443    0.201471

INFO

At the moment there is no support to save a DimArray directly into disk as a NetCDF or a Zarr file.

+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/create.html b/previews/PR437/UserGuide/create.html new file mode 100644 index 00000000..08dd33c1 --- /dev/null +++ b/previews/PR437/UserGuide/create.html @@ -0,0 +1,72 @@ + + + + + + Create YAXArrays and Datasets | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Create YAXArrays and Datasets

This section describes how to create arrays and datasets by filling values directly.

Create a YAXArray

We can create a new YAXArray by filling the values directly:

julia
using YAXArrays
+a1 = YAXArray(rand(10, 20, 5))
╭─────────────────────────────╮
+│ 10×20×5 YAXArray{Float64,3} │
+├─────────────────────────────┴────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 7.81 KB
+└──────────────────────────────────────────────────────────────────────┘

The dimensions have only generic names, e.g. Dim_1 and only integer values. We can also specify the dimensions with custom names enabling easier access:

julia
using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data2 = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a2 = YAXArray(axlist, data2, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2.properties
Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
julia
a2.axes
(↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+→ lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)

Create a Dataset

julia
data3 = rand(30, 10, 15)
+a3 = YAXArray(axlist, data3, properties)
+
+arrays = Dict(:a2 => a2, :a3 => a3)
+ds = Dataset(; properties, arrays...)
YAXArray Dataset
+Shared Axes: 
+  (↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)
+
+Variables: 
+a2, a3
+
+Properties: Dict(:origin => "user guide")
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/faq.html b/previews/PR437/UserGuide/faq.html new file mode 100644 index 00000000..55c11047 --- /dev/null +++ b/previews/PR437/UserGuide/faq.html @@ -0,0 +1,383 @@ + + + + + + Frequently Asked Questions (FAQ) | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Frequently Asked Questions (FAQ)

The purpose of this section is to do a collection of small convinient pieces of code on how to do simple things.

Extract the axes names from a Cube

julia
using YAXArrays
+using DimensionalData
julia
julia> c = YAXArray(rand(10, 10, 5))
╭─────────────────────────────╮
+10×10×5 YAXArray{Float64,3}
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 3.91 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> caxes(c) # former way of doing it
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

WARNING

To get the axes of a YAXArray use the dims function instead of the caxes function

julia
julia> dims(c)
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

INFO

Also, use DD.rebuild(c, values) to copy axes from c and build a new cube but with different values.

rebuild

As an example let's consider the following

julia
using YAXArrays
+using DimensionalData
+
+c = YAXArray(ones(Int, 10,10))
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────┘

then creating a new c with the same structure (axes) but different values is done by

julia
julia> new_c = rebuild(c, rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the type is now Float64. Or, we could create a new structure but using the dimensions from yax explicitly

julia
julia> c_c = YAXArray(dims(c), rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

which achieves the same goal as rebuild.

Obtain values from axes and data from the cube

There are two options to collect values from axes. In this examples the axis ranges from 1 to 10.

These two examples bring the same result

julia
collect(getAxis("Dim_1", c).val)
+collect(c.axes[1].val)
10-element Vector{Int64}:
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10

to collect data from a cube works exactly the same as doing it from an array

julia
julia> c[:, :, 1]
╭─────────────────────────╮
+10×10 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I concatenate cubes

It is possible to concatenate several cubes that shared the same dimensions using the [concatenatecubes]@ref function.

Let's create two dummy cubes

julia
using YAXArrays
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15))
+    )
+
+data1 = rand(20, 10, 15)
+ds1 = YAXArray(axlist, data1)
+
+data2 = rand(20, 10, 15)
+ds2 = YAXArray(axlist, data2)

Now we can concatenate ds1 and ds2:

julia
julia> dsfinal = concatenatecubes([ds1, ds2], Dim{:Variables}(["var1", "var2"]))
╭────────────────────────────────╮
+20×10×15×2 YAXArray{Float64,4}
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+time      Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon       Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat       Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+Variables Categorical{String} ["var1", "var2"] ForwardOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I subset a YAXArray ( Cube ) or Dataset?

These are the three main datatypes provided by the YAXArrays libray. You can find a description of them here. A Cube is no more than a YAXArray, so, we will not explicitly tell about a Cube.

Subsetting a YAXArray

Let's start by creating a dummy YAXArray.

Firstly, load the required libraries

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data, however the intervals notation should be used instead, i.e. `a .. b`.

Define the time span of the YAXArray

julia
t = Date("2020-01-01"):Month(1):Date("2022-12-31")
Date("2020-01-01"):Dates.Month(1):Date("2022-12-01")

create YAXArray axes

julia
axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
(↓ Lon  1:10,
+→ Lat  1:10,
+↗ Time Date("2020-01-01"):Dates.Month(1):Date("2022-12-01"))

create the YAXArray

julia
y = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
╭────────────────────────────╮
+│ 10×10×36 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 28.12 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Now we subset the YAXArray by any dimension.

Subset YAXArray by years

julia
ytime = y[Time=Between(Date(2021,1,1), Date(2021,12,31))]
╭────────────────────────────╮
+│ 10×10×12 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-01-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by a specific date

julia
ytime2 = y[Time=At(Date("2021-05-01"))]
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────── dims ┐
+  ↓ Lon Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────┘

Subset YAXArray by a date range

julia
ytime3 = y[Time=Date("2021-05-01") .. Date("2021-12-01")]
╭───────────────────────────╮
+│ 10×10×8 YAXArray{Int64,3} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-05-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 6.25 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by longitude and latitude

julia
ylonlat = y[Lon=1 .. 5, Lat=5 .. 10]
╭──────────────────────────╮
+│ 5×6×36 YAXArray{Int64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 8.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subsetting a Dataset

In a dataset, we can have several variables (YAXArrays) that share some or all of their dimensions.

Subsetting a Dataset whose variables share all their dimensions

This works for YAXArrays. Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
+
+var1 = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
+var2 = YAXArray(axes, reshape((1:3600)*5, (10, 10, 36)))
+
+ds = Dataset(; var1=var1, var2=var2)
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2
julia
ds_lonlat = ds[Lon=1 .. 5, Lat=5 .. 10]
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2

Subsetting a Dataset whose variables share some but not all of their dimensions

In this case, if we subset by the common dimension/s, this works the same as for YAXArrays, Cubes, and datasets that share all their dimensions.

But we can also subset a variable by the values of another variable with which it shares some dimensions.

Warning

If your data is not loaded into memory, the selection will be too slow. So, you have load into memory, at least, the variable with which you make the selection.

Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" selector for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+common_axis = Dim{:points}(1:100)
+time_axis =   Dim{:Time}(t)
+
+# Note that longitudes and latitudes are not dimensions, but YAXArrays
+longitudes = YAXArray((common_axis,), rand(1:369, 100)) # 100 random values taken from 1 to 359
+latitudes  = YAXArray((common_axis,), rand(0:90, 100))  # 100 random values taken from 0 to 90
+temperature = YAXArray((common_axis, time_axis), rand(-40:40, (100, 36)))
+
+ds = Dataset(; longitudes=longitudes, latitudes=latitudes, temperature=temperature)
YAXArray Dataset
+Shared Axes: 
+  (↓ points Sampled{Int64} 1:100 ForwardOrdered Regular Points)
+
+Variables: 
+latitudes, longitudes
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature

Select all points between 20ºN and 85ºN, and 0ºE to 180ºE

julia
ds_subset = ds[points = Where(p-> ds["latitudes"][p]  >= 20 && ds["latitudes"][p]  <= 80 &&
+                             ds["longitudes"][p] >= 0  && ds["longitudes"][p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

If your dataset has been read from a file with Cube it is not loaded into memory, and you have to load the latitudes and longitudes YAXArrays into memory:

julia
latitudes_yasxa  = readcubedata(ds["latitudes"])
+longitudes_yasxa = readcubedata(ds["longitudes"])
+ds_subset = ds[points = Where(p-> latitudes_yasxa[p]  >= 20 && latitudes_yasxa[p]  <= 80 &&
+                             longitudes_yasxa[p] >= 0  && longitudes_yasxa[p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

How do I apply map algebra?

Our next step is map algebra computations. This can be done effectively using the 'map' function. For example:

Multiplying cubes with only spatio-temporal dimensions

julia
julia> map((x, y) -> x * y, ds1, ds2)
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Cubes with more than 3 dimensions

julia
julia> map((x, y) -> x * y, dsfinal[Variables=At("var1")], dsfinal[Variables=At("var2")])
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

To add some complexity, we will multiply each value for π and then divided for the sum of each time step. We will use the ds1 cube for this purpose.

julia
julia> mapslices(ds1, dims=("Lon", "Lat")) do xin
+           (xin * π) ./ maximum(skipmissing(xin))
+       end
╭──────────────────────────────────────────────╮
+10×15×20 YAXArray{Union{Missing, Float64},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I use the CubeTable function?

The function "CubeTable" creates an iterable table and the result is a DataCube. It is therefore very handy for grouping data and computing statistics by class. It uses OnlineStats.jl to calculate statistics, and weighted statistics can be calculated as well.

Here we will use the ds1 Cube defined previously and we create a mask for data classification.

Cube containing a mask with classes 1, 2 and 3.

julia
julia> classes = YAXArray((getAxis("lon", dsfinal), getAxis("lat", dsfinal)), rand(1:3, 10, 15))
╭─────────────────────────╮
+10×15 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
using GLMakie
+GLMakie.activate!()
+# This is how our classification map looks like
+fig, ax, obj = heatmap(classes;
+    colormap=Makie.Categorical(cgrad([:grey15, :orangered, :snow3])))
+cbar = Colorbar(fig[1,2], obj)
+fig

Now we define the input cubes that will be considered for the iterable table

julia
t = CubeTable(values=ds1, classes=classes)
Datacube iterator with 1 subtables with fields: (:values, :classes, :time, :lon, :lat)
julia
using DataFrames
+using OnlineStats
+## visualization of the CubeTable
+c_tbl = DataFrame(t[1])
+first(c_tbl, 5)

In this line we calculate the Mean for each class

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes))
╭───────────────────────────────────────────────╮
+3-element YAXArray{Union{Missing, Float64},1}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 24.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

We can also use more than one criteria for grouping the values. In the next example, the mean is calculated for each class and timestep.

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes, :time))
╭──────────────────────────────────────────╮
+3×20 YAXArray{Union{Missing, Float64},2}
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points,
+time    Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 480.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I assign variable names to YAXArrays in a Dataset

One variable name

julia
julia> ds = YAXArrays.Dataset(; (:a => YAXArray(rand(10)),)...)
YAXArray Dataset
+Shared Axes:
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+a

Multiple variable names

julia
keylist = (:a, :b, :c)
+varlist = (YAXArray(rand(10)), YAXArray(rand(10,5)), YAXArray(rand(2,5)))
julia
julia> ds = YAXArrays.Dataset(; (keylist .=> varlist)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+  Variables: 
+  a
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  b
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  c

Ho do I construct a Dataset from a TimeArray

In this section we will use MarketData.jl and TimeSeries.jl to simulate some stocks.

julia
using YAXArrays, DimensionalData
+using MarketData, TimeSeries
+
+stocks = Dict(:Stock1 => random_ohlcv(), :Stock2 => random_ohlcv(), :Stock3 => random_ohlcv())
+d_keys = keys(stocks)
KeySet for a Dict{Symbol, TimeSeries.TimeArray{Float64, 2, DateTime, Matrix{Float64}}} with 3 entries. Keys:
+  :Stock3
+  :Stock1
+  :Stock2

currently there is not direct support to obtain dims from a TimeArray, but can build a function for it

julia
getTArrayAxes(ta::TimeArray) = (Dim{:time}(timestamp(ta)), Dim{:variable}(colnames(ta)), );

then, we create the YAXArrays as

julia
yax_list = [YAXArray(getTArrayAxes(stocks[k]), values(stocks[k])) for k in d_keys];

and a Dataset with all stocks names

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock2
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock1
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock3

and it looks like there some small differences in the axes, they are being printed independently although they should be the same. Well, they are at least at the == level but not at ===. We could use the axes from one YAXArray as reference and rebuild all the others

julia
yax_list = [rebuild(yax_list[1], values(stocks[k])) for k in d_keys];

and voilà

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+
+Variables: 
+Stock1, Stock2, Stock3

now they are printed together, showing that is exactly the same axis structure for all variables.

+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/group.html b/previews/PR437/UserGuide/group.html new file mode 100644 index 00000000..eb46e8c0 --- /dev/null +++ b/previews/PR437/UserGuide/group.html @@ -0,0 +1,214 @@ + + + + + + Group YAXArrays and Datasets | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Group YAXArrays and Datasets

The following examples will use the groupby function to calculate temporal and spatial averages.

julia
using YAXArrays, DimensionalData
+using NetCDF
+using Downloads
+using Dates
+using Statistics

Seasonal Averages from Time Series of Monthly Means

The following reproduces the example in xarray by Joe Hamman.

Where the goal is to calculate the seasonal average. And in order to do this properly, is necessary to calculate the weighted average considering that each month has a different number of days.

Download the data

julia
url_path = "https://github.com/pydata/xarray-data/raw/master/rasm.nc"
+filename = Downloads.download(url_path, "rasm.nc")
+ds_o = Cube(filename)

WARNING

The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Out of memory groupby currently is work in progress. Related to https://github.com/rafaqz/DimensionalData.jl/issues/642

julia
axs = dims(ds_o) # get the dimensions
+data = ds_o.data[:,:,:] # read the data
+_FillValue = ds_o.properties["_FillValue"]
+data = replace(data, _FillValue => NaN)
+# create new YAXArray
+ds = YAXArray(axs, data)

GroupBy: seasons

function weighted_seasons(ds) ... end
julia
function weighted_seasons(ds)
+    # calculate weights 
+    tempo = dims(ds, :Ti)
+    month_length = YAXArray((tempo,), daysinmonth.(tempo))
+    g_tempo = groupby(month_length, Ti => seasons(; start=December))
+    sum_days = sum.(g_tempo, dims=:Ti)
+    weights = map(./, g_tempo, sum_days)
+    # unweighted seasons
+    g_ds = groupby(ds, Ti => seasons(; start=December))
+    mean_g = mean.(g_ds, dims=:Ti)
+    mean_g = dropdims.(mean_g, dims=:Ti)
+    # weighted seasons
+    g_dsW = broadcast_dims.(*, weights, g_ds)
+    weighted_g = sum.(g_dsW, dims = :Ti);
+    weighted_g = dropdims.(weighted_g, dims=:Ti)
+    # differences
+    diff_g = map(.-, weighted_g, mean_g)
+    seasons_g = lookup(mean_g, :Ti)
+    return mean_g, weighted_g, diff_g, seasons_g
+end

Now, we continue with the groupby operations as usual

julia
julia> g_ds = groupby(ds, Ti => seasons(; start=December))
╭──────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Float64,2},1}
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+x, y, Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  275×205×9 YAXArray
+ :Mar_Apr_May  275×205×9 YAXArray
+ :Jun_Jul_Aug  275×205×9 YAXArray
+ :Sep_Oct_Nov  275×205×9 YAXArray

And the mean per season is calculated as follows

julia
julia> mean_g = mean.(g_ds, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843;;;]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762;;;]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537;;;]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404;;;]

dropdims

Note that now the time dimension has length one, we can use dropdims to remove it

julia
julia> mean_g = dropdims.(mean_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404]

seasons

Due to the groupby function we will obtain new grouping names, in this case in the time dimension:

julia
seasons_g = lookup(mean_g, :Ti)
Categorical{Symbol} Unordered
+wrapping: 4-element Vector{Symbol}:
+ :Dec_Jan_Feb
+ :Mar_Apr_May
+ :Jun_Jul_Aug
+ :Sep_Oct_Nov

Next, we will weight this grouping by days/month in each group.

GroupBy: weight

Create a YAXArray for the month length

julia
tempo = dims(ds, :Ti)
+month_length = YAXArray((tempo,), daysinmonth.(tempo))
╭──────────────────────────────╮
+│ 36-element YAXArray{Int64,1} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(1980-09-16T12:00:00), …, CFTime.DateTimeNoLeap(1983-08-17T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 288.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now group it by season

julia
julia> g_tempo = groupby(month_length, Ti => seasons(; start=December))
╭────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Int64,0},1}
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  9-element YAXArray
+ :Mar_Apr_May  9-element YAXArray
+ :Jun_Jul_Aug  9-element YAXArray
+ :Sep_Oct_Nov  9-element YAXArray

Get the number of days per season

julia
julia> sum_days = sum.(g_tempo, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Int64, 1, Vector{Int64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  [270]
+ :Mar_Apr_May  [276]
+ :Jun_Jul_Aug  [276]
+ :Sep_Oct_Nov  [273]

weights

Weight the seasonal groups by sum_days

julia
julia> weights = map(./, g_tempo, sum_days)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 1, Vector{Float64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1} groupby
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704]
+ :Mar_Apr_May     [0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319]
+ :Jun_Jul_Aug     [0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319]
+ :Sep_Oct_Nov     [0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989]

Verify that the sum per season is 1

julia
julia> sum.(weights)
╭───────────────────────────────╮
+4-element DimArray{Float64,1}
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  1.0
+ :Mar_Apr_May  1.0
+ :Jun_Jul_Aug  1.0
+ :Sep_Oct_Nov  1.0

weighted seasons

Now, let's weight the seasons

julia
julia> g_dsW = broadcast_dims.(*, weights, g_ds)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.32149 1.33565; NaN NaN … 1.29564 1.32555; … ; NaN NaN … 1.3188 1.3169; NaN NaN … 1.17863 1.18434;;; NaN NaN … 1.29816 1.34218; NaN NaN … 1.30113 1.35483; … ; NaN NaN … 1.30142 1.31753; NaN NaN … 1.16258 1.17647;;; NaN NaN … 1.34549 1.37878; NaN NaN … 1.36836 1.41634; … ; NaN NaN … 1.34832 1.38364; NaN NaN … 1.17852 1.16713]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.87705 1.90365; NaN NaN … 2.30018 2.35432; … ; NaN NaN … 2.41049 2.43254; NaN NaN … 2.65105 2.69085;;; NaN NaN … 1.86457 1.90712; NaN NaN … 2.2894 2.34818; … ; NaN NaN … 2.3866 2.41241; NaN NaN … 2.61197 2.64976;;; NaN NaN … 1.89237 1.8984; NaN NaN … 2.29473 2.312; … ; NaN NaN … 2.36142 2.36126; NaN NaN … 2.56632 2.59085]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 3.21209 3.25153; NaN NaN … 3.23 3.28008; … ; NaN NaN … 3.12575 3.15532; NaN NaN … 3.2434 3.26274;;; NaN NaN … 3.17434 3.21699; NaN NaN … 3.18892 3.24375; … ; NaN NaN … 3.06755 3.1083; NaN NaN … 3.19241 3.22211;;; NaN NaN … 3.1437 3.15644; NaN NaN … 3.16631 3.18583; … ; NaN NaN … 3.03361 3.05846; NaN NaN … 3.16581 3.16824]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 2.97047 3.00388; NaN NaN … 2.77587 2.80759; … ; NaN NaN … 2.60175 2.60918; NaN NaN … 1.4947 1.52419;;; NaN NaN … 2.94534 2.97649; NaN NaN … 2.75891 2.79502; … ; NaN NaN … 2.57695 2.59212; NaN NaN … 1.46506 1.49909;;; NaN NaN … 2.9192 2.93743; NaN NaN … 2.7593 2.77687; … ; NaN NaN … 2.57873 2.63006; NaN NaN … 1.48367 1.50089]

apply a sum over the time dimension and drop it

julia
julia> weighted_g = sum.(g_dsW, dims = :Ti);
+
+julia> weighted_g = dropdims.(weighted_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1181 11.372; NaN NaN … 11.3069 11.5743]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1242 21.0057; NaN NaN … 21.4198 21.1644]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2747 27.9362; NaN NaN … 28.6122 28.0465]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.73 21.7341; NaN NaN … 21.986 21.959]

Calculate the differences

julia
julia> diff_g = map(.-, weighted_g, mean_g)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.019016 -0.0115514; NaN NaN … -0.0183003 -0.00990356]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.0121037 -0.0123091; NaN NaN … -0.0127077 -0.0117519]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.00709111 -0.00693713; NaN NaN … -0.00684233 -0.00722034]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 0.0180572 0.0182373; NaN NaN … 0.0178074 0.018571]

All the previous steps are equivalent to calling the function defined at the top:

julia
mean_g, weighted_g, diff_g, seasons_g = weighted_seasons(ds)

Once all calculations are done we can plot the results with Makie.jl as follows:

julia
using CairoMakie
+# define plot arguments/attributes
+colorrange = (-30,30)
+colormap = Reverse(:Spectral)
+highclip = :red
+lowclip = :grey15
+cb_label =  ds_o.properties["long_name"]
"Surface air temperature"
julia
with_theme(theme_ggplot2()) do
+    hm_o, hm_d, hm_w = nothing, nothing, nothing
+    # the figure
+    fig = Figure(; size = (850,500))
+    axs = [Axis(fig[i,j], aspect=DataAspect()) for i in 1:3, j in 1:4]
+    for (j, s) in enumerate(seasons_g)
+        hm_o = heatmap!(axs[1,j], mean_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_w = heatmap!(axs[2,j], weighted_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_d = heatmap!(axs[3,j], diff_g[Ti=At(s)]; colorrange=(-0.1,0.1), lowclip, highclip,
+            colormap=:diverging_bwr_20_95_c54_n256)
+    end
+    Colorbar(fig[1:2,5], hm_o, label=cb_label)
+    Colorbar(fig[3,5], hm_d, label="Tair")
+    hidedecorations!.(axs, grid=false, ticks=false, label=false)
+    # some labels
+    [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons_g)]
+    Label(fig[0,1:5], "Seasonal Surface Air Temperature", fontsize=18, font=:bold)
+    axs[1,1].ylabel = "Unweighted"
+    axs[2,1].ylabel = "Weighted"
+    axs[3,1].ylabel = "Difference"
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    fig
+end

which shows a good agreement with the results first published by Joe Hamman.

+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/read.html b/previews/PR437/UserGuide/read.html new file mode 100644 index 00000000..4802a6af --- /dev/null +++ b/previews/PR437/UserGuide/read.html @@ -0,0 +1,103 @@ + + + + + + Read YAXArrays and Datasets | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Read YAXArrays and Datasets

This section describes how to read files, URLs, and directories into YAXArrays and datasets.

Read Zarr

Open a Zarr store as a Dataset:

julia
using YAXArrays
+using Zarr
+path="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
+store = zopen(path, consolidated=true)
+ds = open_dataset(store)
YAXArray Dataset
+Shared Axes: 
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)

We can set path to a URL, a local directory, or in this case to a cloud object storage path.

A zarr store may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tas
╭────────────────────────────────────╮
+│ 384×192×251288 YAXArray{Float32,3} │
+├────────────────────────────────────┴─────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"         => "K"
+  "history"       => "2019-07-21T06:26:13Z altered by CMOR: Treated scalar dime…
+  "name"          => "tas"
+  "cell_methods"  => "area: mean time: point"
+  "cell_measures" => "area: areacella"
+  "long_name"     => "Near-Surface Air Temperature"
+  "coordinates"   => "height"
+  "standard_name" => "air_temperature"
+  "_FillValue"    => 1.0f20
+  "comment"       => "near-surface (usually, 2 meter) air temperature"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 69.02 GB
+└──────────────────────────────────────────────────────────────────────────────┘

Read NetCDF

Open a NetCDF file as a Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

A NetCDF file may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Read GDAL (GeoTIFF, GeoJSON)

All GDAL compatible files can be read as a YAXArrays.Dataset after loading ArchGDAL:

julia
using YAXArrays
+using ArchGDAL
+using Downloads: download
+
+path = download("https://github.com/yeesian/ArchGDALDatasets/raw/307f8f0e584a39a050c042849004e6a2bd674f99/gdalworkshop/world.tif", "world.tif")
+# ds = open_dataset(path) # this is broken
+nothing
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/select.html b/previews/PR437/UserGuide/select.html new file mode 100644 index 00000000..66fc15ae --- /dev/null +++ b/previews/PR437/UserGuide/select.html @@ -0,0 +1,318 @@ + + + + + + Select YAXArrays and Datasets | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Select YAXArrays and Datasets

The dimensions or axes of an YAXArray are named making it easier to subset or query certain ranges of an array. Let's open an example Dataset used to select certain elements:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Select a YAXArray

Get the sea surface temperature of the Dataset:

julia
tos = ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

which is the same as:

julia
tos = ds.cubes[:tos]
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Select elements

Using positional integer indexing:

julia
tos[lon = 1, lat = 1]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1), lat = At(-79.5)]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Using special types:

julia
using CFTime
+time1 = DateTime360Day(2001,01,16)
+tos[time = At(time1)]
╭─────────────────────────────────────────────╮
+│ 180×170 YAXArray{Union{Missing, Float32},2} │
+├─────────────────────────────────────────────┴───────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────────────────┴ metadata ┐
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├───────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 119.53 KB
+└────────────────────────────────────────────────────────────────────────────────┘

Select ranges

Here we subset an interval of a dimension using positional integer indexing.

julia
tos[lon = 1:10, lat = 1:10]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:19.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:-70.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1.0:2:19), lat = At(-79.5:1:-70.5)]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 3.0, …, 17.0, 19.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} [-79.5, -78.5, …, -71.5, -70.5] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Read more about the At selector in the package DimensionalData. Get values within a tolerances:

julia
tos[lon = At(1:10; atol = 1)]
╭───────────────────────────────────────────────╮
+│ 10×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 1.0, …, 9.0, 9.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 159.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Closed and open intervals

Although a Between(a,b) function is available in DimensionalData, is recommended to use instead the a .. b notation:

julia
tos[lon = 90 .. 180]
╭───────────────────────────────────────────────╮
+│ 45×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This describes a closed interval in which all points were included. More selectors from DimensionalData are available, such as Touches, Near, Where and Contains.

julia
using IntervalSets
julia
julia> tos[lon = OpenInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon = ClosedInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:open,:closed}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:closed,:open}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

See tutorials for use cases.

Get a dimension

Get values, .e.g., axis tick labels, of a dimension that can be used for subseting:

julia
collect(tos.lat)
170-element Vector{Float64}:
+ -79.5
+ -78.5
+ -77.5
+ -76.5
+ -75.5
+ -74.5
+ -73.5
+ -72.5
+ -71.5
+ -70.5
+
+  81.5
+  82.5
+  83.5
+  84.5
+  85.5
+  86.5
+  87.5
+  88.5
+  89.5

These values are defined as lookups in the package DimensionalData:

julia
lookup(tos, :lon)
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0

which is equivalent to:

julia
tos.lon.val
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0
+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/types.html b/previews/PR437/UserGuide/types.html new file mode 100644 index 00000000..6955d5c2 --- /dev/null +++ b/previews/PR437/UserGuide/types.html @@ -0,0 +1,25 @@ + + + + + + Types | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Types

This section describes the data structures used to work with n-dimensional arrays in YAXArrays.

YAXArray

An Array stores a sequence of ordered elements of the same type usually across multiple dimensions or axes. For example, one can measure temperature across all time points of the time dimension or brightness values of a picture across X and Y dimensions. A one dimensional array is called Vector and a two dimensional array is called a Matrix. In many Machine Learning libraries, arrays are also called tensors. Arrays are designed to store dense spatial-temporal data stored in a grid, whereas a collection of sparse points is usually stored in data frames or relational databases.

A DimArray as defined by DimensionalData.jl adds names to the dimensions and their axes ticks for a given Array. These names can be used to access the data, e.g., by date instead of just by integer position.

A YAXArray is a subtype of a AbstractDimArray and adds functions to load and process the named arrays. For example, it can also handle very large arrays stored on disk that are too big to fit in memory. In addition, it provides functions for parallel computation.

Dataset

A Dataset is an ordered dictionary of YAXArrays that usually share dimensions. For example, it can bundle arrays storing temperature and precipitation that are measured at the same time points and the same locations. One also can store a picture in a Dataset with three arrays containing brightness values for red green and blue, respectively. Internally, those arrays are still separated allowing to chose different element types for each array. Analog to the (NetCDF Data Model)[https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_data_model.html], a Dataset usually represents variables belonging to the same group.

(Data) Cube

A (Data) Cube is just a YAXArray in which arrays from a dataset are combined together by introducing a new dimension containing labels of which array the corresponding element came from. Unlike a Dataset, all arrays must have the same element type to be converted into a cube. This data structure is useful when we want to use all variables at once. For example, the arrays temperature and precipitation which are measured at the same locations and dates can be combined into a single cube. A more formal definition of Data Cubes are given in Mahecha et al. 2020

Dimension

A Dimension or axis as defined by DimensionalData.jl adds tick labels, e.g., to each row or column of an array. It's name is used to access particular subsets of that array.

+ + + + \ No newline at end of file diff --git a/previews/PR437/UserGuide/write.html b/previews/PR437/UserGuide/write.html new file mode 100644 index 00000000..f959ebcb --- /dev/null +++ b/previews/PR437/UserGuide/write.html @@ -0,0 +1,90 @@ + + + + + + Write YAXArrays and Datasets | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Write YAXArrays and Datasets

Create an example Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Write Zarr

Save a single YAXArray to a directory:

julia
using Zarr
+savecube(ds.tos, "tos.zarr", driver=:zarr)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.zarr", driver=:zarr)

Write NetCDF

Save a single YAXArray to a directory:

julia
using NetCDF
+savecube(ds.tos, "tos.nc", driver=:netcdf)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.nc", driver=:netcdf)

Overwrite a Dataset

If a path already exists, an error will be thrown. Set overwrite=true to delete the existing dataset

julia
savedataset(ds, path="ds.zarr", driver=:zarr, overwrite=true)

DANGER

Again, setting overwrite will delete all your previous saved data.

Look at the doc string for more information

# YAXArrays.Datasets.savedatasetFunction.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


Append to a Dataset

New variables can be added to an existing dataset using the append=true keyword.

julia
ds2 = Dataset(z = YAXArray(rand(10,20,5)))
+savedataset(ds2, path="ds.zarr", backend=:zarr, append=true)
julia
julia> open_dataset("ds.zarr", driver=:zarr)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+  Variables: 
+  tos
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} 1:1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:1:20 ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} 1:1:5 ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+Properties: Dict{String, Any}("cmor_version" => 0.96, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "Conventions" => "CF-1.0", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Save Skeleton

Sometimes one merely wants to create a datacube "Skeleton" on disk and gradually fill it with data. Here we make use of FillArrays to create a YAXArray and write only the axis data and array metadata to disk, while no actual array data is copied:

julia
using YAXArrays, Zarr, FillArrays

create the Zeros array

julia
julia> a = YAXArray(Zeros(Union{Missing, Float32},  5, 4, 5))
╭───────────────────────────────────────────╮
+5×4×5 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 400.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now, save to disk with

julia
r = savecube(a, "skeleton.zarr", layername="skeleton", driver=:zarr, skeleton=true, overwrite=true)

WARNING

overwrite=true will delete your previous .zarr file before creating a new one.

Note also that if layername="skeleton" is not provided then the default name for the cube variable will be layer.

Now, we check that all the values are missing

julia
all(ismissing, r[:,:,:])
true

If using FillArrays is not possible, using the zeros function works as well, though it does allocate the array in memory.

INFO

The skeleton argument is also available for savedataset.

Using the toy array defined above we can do

julia
ds = Dataset(skeleton=a) # skeleton will the variable name
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+
+Variables: 
+skeleton
julia
ds_s = savedataset(ds, path="skeleton.zarr", driver=:zarr, skeleton=true, overwrite=true)

Update values of dataset

Now, we show how to start updating the array values. In order to do it we need to open the dataset first with writing w rights as follows:

julia
ds_open = zopen("skeleton.zarr", "w")
+ds_array = ds_open["skeleton"]
ZArray{Float32} of size 5 x 4 x 5

and then we simply update values by indexing them where necessary

julia
ds_array[:,:,1] = rand(Float32, 5, 4) # this will update values directly into disk!
5×4 Matrix{Float32}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

we can verify is this working by loading again directly from disk

julia
ds_open = open_dataset("skeleton.zarr")
+ds_array = ds_open["skeleton"]
+ds_array.data[:,:,1]
5×4 Matrix{Union{Missing, Float32}}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

indeed, those entries had been updated.

+ + + + \ No newline at end of file diff --git a/previews/PR437/api.html b/previews/PR437/api.html new file mode 100644 index 00000000..ecf6ee6b --- /dev/null +++ b/previews/PR437/api.html @@ -0,0 +1,37 @@ + + + + + + API Reference | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

API Reference

This section describes all available functions of this package.

Public API

# YAXArrays.getAxisMethod.
julia
getAxis(desc, c)

Given an Axis description and a cube, returns the corresponding axis of the cube. The Axis description can be:

  • the name as a string or symbol.

  • an Axis object

source


# YAXArrays.CubesModule.

The functions provided by YAXArrays are supposed to work on different types of cubes. This module defines the interface for all Data types that

source


# YAXArrays.Cubes.YAXArrayType.
julia
YAXArray{T,N}

An array labelled with named axes that have values associated with them. It can wrap normal arrays or, more typically DiskArrays.

Fields

  • axes: Tuple of Dimensions containing the Axes of the Cube

  • data: length(axes)-dimensional array which holds the data, this can be a lazy DiskArray

  • properties: Metadata properties describing the content of the data

  • chunks: Representation of the chunking of the data

  • cleaner: Cleaner objects to track which objects to tidy up when the YAXArray goes out of scope

source


# YAXArrays.Cubes.caxesFunction.

Returns the axes of a Cube

source


# YAXArrays.Cubes.caxesMethod.
julia
caxes

Embeds Cube inside a new Cube

source


# YAXArrays.Cubes.concatenatecubesMethod.
julia
function concatenateCubes(cubelist, cataxis::CategoricalAxis)

Concatenates a vector of datacubes that have identical axes to a new single cube along the new axis cataxis

source


# YAXArrays.Cubes.readcubedataMethod.
julia
readcubedata(cube)

Given any array implementing the YAXArray interface it returns an in-memory YAXArray from it.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::YAXArray,chunks)

Resets the chunks of a YAXArray and returns a new YAXArray. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savecube on the resulting array. The chunks argument can take one of the following forms:

  • a DiskArrays.GridChunks object

  • a tuple specifying the chunk size along each dimension

  • an AbstractDict or NamedTuple mapping one or more axis names to chunk sizes

source


# YAXArrays.Cubes.subsetcubeFunction.

This function calculates a subset of a cube's data

source


# YAXArrays.DAT.InDimsType.
julia
InDims(axisdesc...;...)

Creates a description of an Input Data Cube for cube operations. Takes a single or multiple axis descriptions as first arguments. Alternatively a MovingWindow(@ref) struct can be passed to include neighbour slices of one or more axes in the computation. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

Keyword arguments

  • artype how shall the array be represented in the inner function. Defaults to Array, alternatives are DataFrame or AsAxisArray

  • filter define some filter to skip the computation, e.g. when all values are missing. Defaults to AllMissing(), possible values are AnyMissing(), AnyOcean(), StdZero(), NValid(n) (for at least n non-missing elements). It is also possible to provide a custom one-argument function that takes the array and returns true if the compuation shall be skipped and false otherwise.

  • window_oob_value if one of the input dimensions is a MowingWindow, this value will be used to fill out-of-bounds areas

source


# YAXArrays.DAT.MovingWindowType.
julia
MovingWindow(desc, pre, after)

Constructs a MovingWindow object to be passed to an InDims constructor to define that the axis in desc shall participate in the inner function (i.e. shall be looped over), but inside the inner function pre values before and after values after the center value will be passed as well.

For example passing MovingWindow("Time", 2, 0) will loop over the time axis and always pass the current time step plus the 2 previous steps. So in the inner function the array will have an additional dimension of size 3.

source


# YAXArrays.DAT.OutDimsMethod.
julia
OutDims(axisdesc;...)

Creates a description of an Output Data Cube for cube operations. Takes a single or a Vector/Tuple of axes as first argument. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

  • axisdesc: List of input axis names

  • backend : specifies the dataset backend to write data to, must be either :auto or a key in YAXArrayBase.backendlist

  • update : specifies wether the function operates inplace or if an output is returned

  • artype : specifies the Array type inside the inner function that is mapped over

  • chunksize: A Dict specifying the chunksizes for the output dimensions of the cube, or :input to copy chunksizes from input cube axes or :max to not chunk the inner dimensions

  • outtype: force the output type to a specific type, defaults to Any which means that the element type of the first input cube is used

source


# YAXArrays.DAT.CubeTableMethod.
julia
CubeTable()

Function to turn a DataCube object into an iterable table. Takes a list of as arguments, specified as a name=cube expression. For example CubeTable(data=cube1,country=cube2) would generate a Table with the entries data and country, where data contains the values of cube1 and country the values of cube2. The cubes are matched and broadcasted along their axes like in mapCube.

source


# YAXArrays.DAT.cubefittableMethod.
julia
cubefittable(tab,o,fitsym;post=getpostfunction(o),kwargs...)

Executes fittable on the CubeTable tab with the (Weighted-)OnlineStat o, looping through the values specified by fitsym. Finally, writes the results from the TableAggregator to an output data cube.

source


# YAXArrays.DAT.fittableMethod.
julia
fittable(tab,o,fitsym;by=(),weight=nothing)

Loops through an iterable table tab and thereby fitting an OnlineStat o with the values specified through fitsym. Optionally one can specify a field (or tuple) to group by. Any groupby specifier can either be a symbol denoting the entry to group by or an anynymous function calculating the group from a table row.

For example the following would caluclate a weighted mean over a cube weighted by grid cell area and grouped by country and month:

julia
fittable(iter,WeightedMean,:tair,weight=(i->abs(cosd(i.lat))),by=(i->month(i.time),:country))

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)
+
+Map a given function `fun` over slices of all cubes of the dataset `ds`. 
+Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.
+For Datasets, only one output cube can be specified.
+In contrast to the mapCube function for cubes, additional arguments for the inner function should be set as keyword arguments.
+
+For the specific keyword arguments see the docstring of the mapCube function for cubes.

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)

Map a given function fun over slices of the data cube cube. The additional arguments addargs will be forwarded to the inner function fun. Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.

Keyword arguments

  • max_cache=YAXDefaults.max_cache Float64 maximum size of blocks that are read into memory in bits e.g. max_cache=5.0e8. Or String. e.g. max_cache="10MB" ormax_cache=1GB``` defaults to approx 10Mb.

  • indims::InDims List of input cube descriptors of type InDims for each input data cube.

  • outdims::OutDims List of output cube descriptors of type OutDims for each output cube.

  • inplace does the function write to an output array inplace or return a single value> defaults to true

  • ispar boolean to determine if parallelisation should be applied, defaults to true if workers are available.

  • showprog boolean indicating if a ProgressMeter shall be shown

  • include_loopvars boolean to indicate if the varoables looped over should be added as function arguments

  • nthreads number of threads for the computation, defaults to Threads.nthreads for every worker.

  • loopchunksize determines the chunk sizes of variables which are looped over, a dict

  • kwargs additional keyword arguments are passed to the inner function

The first argument is always the function to be applied, the second is the input cube or a tuple of input cubes if needed.

source


# YAXArrays.Datasets.DatasetType.
julia
Dataset object which stores an `OrderedDict` of YAXArrays with Symbol keys.
+a dictionary of CubeAxes and a Dictionary of general properties.
+A dictionary can hold cubes with differing axes. But it will share the common axes between the subcubes.

source


# YAXArrays.Datasets.DatasetMethod.

Dataset(; properties = Dict{String,Any}, cubes...)

Construct a YAXArray Dataset with global attributes properties a and a list of named YAXArrays cubes...

source


# YAXArrays.Datasets.CubeMethod.
julia
Cube(ds::Dataset; joinname="Variable")

Construct a single YAXArray from the dataset ds by concatenating the cubes in the datset on the joinname dimension.

source


# YAXArrays.Datasets.open_datasetMethod.

open_dataset(g; driver=:all)

Open the dataset at g with the given driver. The default driver will search for available drivers and tries to detect the useable driver from the filename extension.

source


# YAXArrays.Datasets.savecubeMethod.
julia
savecube(cube,name::String)

Save a YAXArray to the path.

Extended Help

The keyword arguments are:

  • name:

  • datasetaxis="Variable" special treatment of a categorical axis that gets written into separate zarr arrays

  • max_cache: The number of bits that are used as cache for the data handling.

  • backend: The backend, that is used to save the data. Falls back to searching the backend according to the extension of the path.

  • driver: The same setting as backend.

  • overwrite::Bool=false overwrite cube if it already exists

source


# YAXArrays.Datasets.savedatasetMethod.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


# YAXArrays.Datasets.to_datasetMethod.

to_dataset(c;datasetaxis = "Variable", layername = "layer")

Convert a Data Cube into a Dataset. It is possible to treat one of the Cube's axes as a "DatasetAxis" i.e. the cube will be split into different parts that become variables in the Dataset. If no such axis is specified or found, there will only be a single variable in the dataset with the name layername

source


Internal API

# YAXArrays.YAXDefaultsConstant.

Default configuration for YAXArrays, has the following fields:

  • workdir[]::String = "./" The default location for temporary cubes.

  • recal[]::Bool = false set to true if you want @loadOrGenerate to always recalculate the results.

  • chunksize[]::Any = :input Set the default output chunksize.

  • max_cache[]::Float64 = 1e8 The maximum cache used by mapCube.

  • cubedir[]::"" the default location for Cube() without an argument.

  • subsetextensions::Array{Any} = [] List of registered functions, that convert subsetting input into dimension boundaries.

source


# YAXArrays.findAxisMethod.
julia
findAxis(desc, c)

Internal function

Extended Help

Given an Axis description and a cube return the index of the Axis.

The Axis description can be:

  • the name as a string or symbol.

  • an Axis object

source


# YAXArrays.getOutAxisMethod.
julia
getOutAxis

source


# YAXArrays.get_descriptorMethod.
julia
get_descriptor(a)

Get the descriptor of an Axis. This is used to dispatch on the descriptor.

source


# YAXArrays.match_axisMethod.
julia
match_axis

Internal function

Extended Help

Match the Axis based on the AxisDescriptor.
+This is used to find different axes and to make certain axis description the same.
+For example to disregard differences of captialisation.

source


# YAXArrays.Cubes.CleanMeType.
julia
mutable struct CleanMe

Struct which describes data paths and their persistency. Non-persistend paths/files are removed at finalize step

source


# YAXArrays.Cubes.cleanMethod.
julia
clean(c::CleanMe)

finalizer function for CleanMe struct. The main process removes all directories/files which are not persistent.

source


# YAXArrays.Cubes.copydataMethod.
julia
copydata(outar, inar, copybuf)

Internal function which copies the data from the input inar into the output outar at the copybuf positions.

source


# YAXArrays.Cubes.optifuncMethod.
julia
optifunc(s, maxbuf, incs, outcs, insize, outsize, writefac)

Internal

This function is going to be minimized to detect the best possible chunk setting for the rechunking of the data.

source


# YAXArrays.DAT.DATConfigType.

Configuration object of a DAT process. This holds all necessary information to perform the calculations. It contains the following fields:

  • incubes::Tuple{Vararg{YAXArrays.DAT.InputCube, NIN}} where NIN: The input data cubes

  • outcubes::Tuple{Vararg{YAXArrays.DAT.OutputCube, NOUT}} where NOUT: The output data cubes

  • allInAxes::Vector: List of all axes of the input cubes

  • LoopAxes::Vector: List of axes that are looped through

  • ispar::Bool: Flag whether the computation is parallelized

  • loopcachesize::Vector{Int64}:

  • allow_irregular_chunks::Bool:

  • max_cache::Any: Maximal size of the in memory cache

  • fu::Any: Inner function which is computed

  • inplace::Bool: Flag whether the computation happens in place

  • include_loopvars::Bool:

  • ntr::Any:

  • do_gc::Bool: Flag if GC should be called explicitly. Probably necessary for many runs in Julia 1.9

  • addargs::Any: Additional arguments for the inner function

  • kwargs::Any: Additional keyword arguments for the inner function

source


# YAXArrays.DAT.InputCubeType.

Internal representation of an input cube for DAT operations

  • cube: The input data

  • desc: The input description given by the user/registration

  • axesSmall: List of axes that were actually selected through the description

  • icolon

  • colonperm

  • loopinds: Indices of loop axes that this cube does not contain, i.e. broadcasts

  • cachesize: Number of elements to keep in cache along each axis

  • window

  • iwindow

  • windowloopinds

  • iall

source


# YAXArrays.DAT.OutputCubeType.

Internal representation of an output cube for DAT operations

Fields

  • cube: The actual outcube cube, once it is generated

  • cube_unpermuted: The unpermuted output cube

  • desc: The description of the output axes as given by users or registration

  • axesSmall: The list of output axes determined through the description

  • allAxes: List of all the axes of the cube

  • loopinds: Index of the loop axes that are broadcasted for this output cube

  • innerchunks

  • outtype: Elementtype of the outputcube

source


# YAXArrays.DAT.YAXColumnType.
julia
YAXColumn

A struct representing a single column of a YAXArray partitioned Table # Fields

  • inarBC

  • inds

source


# YAXArrays.DAT.cmpcachmissesMethod.

Function that compares two cache miss specifiers by their importance

source


# YAXArrays.DAT.getFrontPermMethod.

Calculate an axis permutation that brings the wanted dimensions to the front

source


# YAXArrays.DAT.getLoopCacheSizeMethod.

Calculate optimal Cache size to DAT operation

source


# YAXArrays.DAT.getOuttypeMethod.
julia
getOuttype(outtype, cdata)

Internal function

Get the element type for the output cube

source


# YAXArrays.DAT.getloopchunksMethod.
julia
getloopchunks(dc::DATConfig)

Internal function

Returns the chunks that can be looped over toghether for all dimensions.
+This computation of the size of the chunks is handled by [`DiskArrays.approx_chunksize`](@ref)

source


# YAXArrays.DAT.permuteloopaxesMethod.
julia
permuteloopaxes(dc)

Internal function

Permute the dimensions of the cube, so that the axes that are looped through are in the first positions. This is necessary for a faster looping through the data.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::Dataset,chunks)

Resets the chunks of all or a subset YAXArrays in the dataset and returns a new Dataset. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savedataset on the resulting array. The chunks argument can take one of the following forms:

  • a NamedTuple or AbstractDict mapping from variable name to a description of the desired variable chunks

  • a NamedTuple or AbstractDict mapping from dimension name to a description of the desired variable chunks

  • a description of the desired variable chunks applied to all members of the Dataset

where a description of the desired variable chunks can take one of the following forms:

  • a DiskArrays.GridChunks object

  • a tuple specifying the chunk size along each dimension

  • an AbstractDict or NamedTuple mapping one or more axis names to chunk sizes

source


# YAXArrays.Datasets.collectfromhandleMethod.

Extracts a YAXArray from a dataset handle that was just created from a arrayinfo

source


# YAXArrays.Datasets.createdatasetMethod.

function createdataset(DS::Type,axlist; kwargs...)

Creates a new dataset with axes specified in axlist. Each axis must be a subtype of CubeAxis. A new empty Zarr array will be created and can serve as a sink for mapCube operations.

Keyword arguments

  • path="" location where the new cube is stored

  • T=Union{Float32,Missing} data type of the target cube

  • chunksize = ntuple(i->length(axlist[i]),length(axlist)) chunk sizes of the array

  • chunkoffset = ntuple(i->0,length(axlist)) offsets of the chunks

  • persist::Bool=true shall the disk data be garbage-collected when the cube goes out of scope?

  • overwrite::Bool=false overwrite cube if it already exists

  • properties=Dict{String,Any}() additional cube properties

  • globalproperties=Dict{String,Any} global attributes to be added to the dataset

  • fillvalue= T>:Missing ? defaultfillval(Base.nonmissingtype(T)) : nothing fill value

  • datasetaxis="Variable" special treatment of a categorical axis that gets written into separate zarr arrays

  • layername="layer" Fallback name of the variable stored in the dataset if no datasetaxis is found

source


# YAXArrays.Datasets.getarrayinfoMethod.

Extract necessary information to create a YAXArrayBase dataset from a name and YAXArray pair

source


# YAXArrays.Datasets.testrangeMethod.

Test if data in x can be approximated by a step range

source


+ + + + \ No newline at end of file diff --git a/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.js b/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.js new file mode 100644 index 00000000..5010f4af --- /dev/null +++ b/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.js @@ -0,0 +1,5 @@ +import{_ as a,c as i,a2 as e,o as t}from"./chunks/framework.BxolPc_T.js";const o=JSON.parse('{"title":"Caching YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/cache.md","filePath":"UserGuide/cache.md","lastUpdated":null}'),n={name:"UserGuide/cache.md"};function h(l,s,p,r,c,d){return t(),i("div",null,s[0]||(s[0]=[e(`

Caching YAXArrays

For some applications like interactive plotting of large datasets it can not be avoided that the same data must be accessed several times. In these cases it can be useful to store recently accessed data in a cache. In YAXArrays this can be easily achieved using the cache function. For example, if we open a large dataset from a remote source and want to keep data in a cache of size 500MB one can use:

julia
using YAXArrays, Zarr
+ds = open_dataset("path/to/source")
+cachesize = 500 #MB
+cache(ds,maxsize = cachesize)

The above will wrap every array in the dataset into its own cache, where the 500MB are distributed equally across datasets. Alternatively individual caches can be applied to single YAXArrays

julia
yax = ds.avariable
+cache(yax,maxsize = 1000)
`,5)]))}const g=a(n,[["render",h]]);export{o as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.lean.js b/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.lean.js new file mode 100644 index 00000000..5010f4af --- /dev/null +++ b/previews/PR437/assets/UserGuide_cache.md.B_Z0kQqJ.lean.js @@ -0,0 +1,5 @@ +import{_ as a,c as i,a2 as e,o as t}from"./chunks/framework.BxolPc_T.js";const o=JSON.parse('{"title":"Caching YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/cache.md","filePath":"UserGuide/cache.md","lastUpdated":null}'),n={name:"UserGuide/cache.md"};function h(l,s,p,r,c,d){return t(),i("div",null,s[0]||(s[0]=[e(`

Caching YAXArrays

For some applications like interactive plotting of large datasets it can not be avoided that the same data must be accessed several times. In these cases it can be useful to store recently accessed data in a cache. In YAXArrays this can be easily achieved using the cache function. For example, if we open a large dataset from a remote source and want to keep data in a cache of size 500MB one can use:

julia
using YAXArrays, Zarr
+ds = open_dataset("path/to/source")
+cachesize = 500 #MB
+cache(ds,maxsize = cachesize)

The above will wrap every array in the dataset into its own cache, where the 500MB are distributed equally across datasets. Alternatively individual caches can be applied to single YAXArrays

julia
yax = ds.avariable
+cache(yax,maxsize = 1000)
`,5)]))}const g=a(n,[["render",h]]);export{o as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.js b/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.js new file mode 100644 index 00000000..0f8f4040 --- /dev/null +++ b/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.js @@ -0,0 +1,98 @@ +import{_ as a,c as i,a2 as n,o as p}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Chunk YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/chunk.md","filePath":"UserGuide/chunk.md","lastUpdated":null}'),l={name:"UserGuide/chunk.md"};function h(e,s,t,k,r,d){return p(),i("div",null,s[0]||(s[0]=[n(`

Chunk YAXArrays

Thinking about chunking is important when it comes to analyzing your data, because in most situations this will not fit into memory, hence having the fastest read access to it is crucial for your workflows. For example, for geo-spatial data do you want fast access on time or space, or... think about it.

To determine the chunk size of the array representation on disk, call the setchunks function prior to saving.

Chunking YAXArrays

julia
using YAXArrays, Zarr
+a = YAXArray(rand(10,20))
+a_chunked = setchunks(a, (5,10))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

And the saved file is also splitted into Chunks.

julia
f = tempname()
+savecube(a_chunked, f, backend=:zarr)
+Cube(f).chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Alternatively chunk sizes can be given by dimension name, so the following results in the same chunks:

julia
a_chunked = setchunks(a, (Dim_2=10, Dim_1=5))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Chunking Datasets

Setchunks can also be applied to a Dataset.

Set Chunks by Axis

Set chunk size for each axis occuring in a Dataset. This will be applied to all variables in the dataset:

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds, Dict("Dim_1"=>5, "Dim_2"=>10, "Dim_3"=>2))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

Saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking by Variable

The following will set the chunk size for each Variable separately and results in exactly the same chunking as the example above

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds,(x = (5,10), y = Dict("Dim_1"=>5), z = (Dim_1 = 5, Dim_2 = 10, Dim_3 = 2)))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking for all variables

The following code snippet only works when all member variables of the dataset have the same shape and sets the output chunks for all arrays.

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10,20)), z = YAXArray(rand(10,20)))
+dschunked = setchunks(ds,(5,10))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:1)   (1:5, 11:20, 1:1)
+ (6:10, 1:10, 1:1)  (6:10, 11:20, 1:1)
+
+[:, :, 2] =
+ (1:5, 1:10, 2:2)   (1:5, 11:20, 2:2)
+ (6:10, 1:10, 2:2)  (6:10, 11:20, 2:2)
+
+[:, :, 3] =
+ (1:5, 1:10, 3:3)   (1:5, 11:20, 3:3)
+ (6:10, 1:10, 3:3)  (6:10, 11:20, 3:3)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+
+Variables: 
+x, y, z

Suggestions on how to improve or add to these examples is welcome.

`,36)]))}const c=a(l,[["render",h]]);export{g as __pageData,c as default}; diff --git a/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.lean.js b/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.lean.js new file mode 100644 index 00000000..0f8f4040 --- /dev/null +++ b/previews/PR437/assets/UserGuide_chunk.md.CuKskIwf.lean.js @@ -0,0 +1,98 @@ +import{_ as a,c as i,a2 as n,o as p}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Chunk YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/chunk.md","filePath":"UserGuide/chunk.md","lastUpdated":null}'),l={name:"UserGuide/chunk.md"};function h(e,s,t,k,r,d){return p(),i("div",null,s[0]||(s[0]=[n(`

Chunk YAXArrays

Thinking about chunking is important when it comes to analyzing your data, because in most situations this will not fit into memory, hence having the fastest read access to it is crucial for your workflows. For example, for geo-spatial data do you want fast access on time or space, or... think about it.

To determine the chunk size of the array representation on disk, call the setchunks function prior to saving.

Chunking YAXArrays

julia
using YAXArrays, Zarr
+a = YAXArray(rand(10,20))
+a_chunked = setchunks(a, (5,10))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

And the saved file is also splitted into Chunks.

julia
f = tempname()
+savecube(a_chunked, f, backend=:zarr)
+Cube(f).chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Alternatively chunk sizes can be given by dimension name, so the following results in the same chunks:

julia
a_chunked = setchunks(a, (Dim_2=10, Dim_1=5))
+a_chunked.chunks
2×2 DiskArrays.GridChunks{2, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+ (1:5, 1:10)   (1:5, 11:20)
+ (6:10, 1:10)  (6:10, 11:20)

Chunking Datasets

Setchunks can also be applied to a Dataset.

Set Chunks by Axis

Set chunk size for each axis occuring in a Dataset. This will be applied to all variables in the dataset:

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds, Dict("Dim_1"=>5, "Dim_2"=>10, "Dim_3"=>2))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

Saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking by Variable

The following will set the chunk size for each Variable separately and results in exactly the same chunking as the example above

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10)), z = YAXArray(rand(10,20,5)))
+dschunked = setchunks(ds,(x = (5,10), y = Dict("Dim_1"=>5), z = (Dim_1 = 5, Dim_2 = 10, Dim_3 = 2)))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:2)   (1:5, 11:20, 1:2)
+ (6:10, 1:10, 1:2)  (6:10, 11:20, 1:2)
+
+[:, :, 2] =
+ (1:5, 1:10, 3:4)   (1:5, 11:20, 3:4)
+ (6:10, 1:10, 3:4)  (6:10, 11:20, 3:4)
+
+[:, :, 3] =
+ (1:5, 1:10, 5:5)   (1:5, 11:20, 5:5)
+ (6:10, 1:10, 5:5)  (6:10, 11:20, 5:5)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+y
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  → Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+  Additional Axes: 
+  (↓ Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+  Variables: 
+  x

Set chunking for all variables

The following code snippet only works when all member variables of the dataset have the same shape and sets the output chunks for all arrays.

julia
using YAXArrays, Zarr
+ds = Dataset(x = YAXArray(rand(10,20)), y = YAXArray(rand(10,20)), z = YAXArray(rand(10,20)))
+dschunked = setchunks(ds,(5,10))
+Cube(dschunked).chunks
2×2×3 DiskArrays.GridChunks{3, Tuple{DiskArrays.RegularChunks, DiskArrays.RegularChunks, DiskArrays.RegularChunks}}:
+[:, :, 1] =
+ (1:5, 1:10, 1:1)   (1:5, 11:20, 1:1)
+ (6:10, 1:10, 1:1)  (6:10, 11:20, 1:1)
+
+[:, :, 2] =
+ (1:5, 1:10, 2:2)   (1:5, 11:20, 2:2)
+ (6:10, 1:10, 2:2)  (6:10, 11:20, 2:2)
+
+[:, :, 3] =
+ (1:5, 1:10, 3:3)   (1:5, 11:20, 3:3)
+ (6:10, 1:10, 3:3)  (6:10, 11:20, 3:3)

saving...

julia
f = tempname()
+savedataset(dschunked, path=f, driver=:zarr)
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points)
+
+Variables: 
+x, y, z

Suggestions on how to improve or add to these examples is welcome.

`,36)]))}const c=a(l,[["render",h]]);export{g as __pageData,c as default}; diff --git a/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.js b/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.js new file mode 100644 index 00000000..39f1b599 --- /dev/null +++ b/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.js @@ -0,0 +1,28 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Combine YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/combine.md","filePath":"UserGuide/combine.md","lastUpdated":null}'),t={name:"UserGuide/combine.md"};function p(l,s,h,k,r,d){return e(),a("div",null,s[0]||(s[0]=[n(`

Combine YAXArrays

Data is often scattered across multiple files and corresponding arrays, e.g. one file per time step. This section describes methods on how to combine them into a single YAXArray.

cat along an existing dimension

Here we use cat to combine two arrays consisting of data from the first and the second half of a year into one single array containing the whole year. We glue the arrays along the first dimension using dims = 1: The resulting array whole_year still has one dimension, i.e. time, but with 12 instead of 6 elements.

julia
using YAXArrays
+
+first_half = YAXArray((Dim{:time}(1:6),), rand(6))
+second_half = YAXArray((Dim{:time}(7:12),), rand(6))
+whole_year = cat(first_half, second_half, dims = 1)
╭────────────────────────────────╮
+│ 12-element YAXArray{Float64,1} │
+├────────────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time Sampled{Int64} [1, 2, …, 11, 12] ForwardOrdered Regular Points
+├───────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├──────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└───────────────────────────────────────────────────────────────────────┘

concatenatecubes to a new dimension

Here we use concatenatecubes to combine two arrays of different variables that have the same dimensions. The resulting array combined has an additional dimension variable indicating from which array the element values originates. Note that using a Dataset instead is a more flexible approach in handling different variables.

julia
using YAXArrays
+
+temperature = YAXArray((Dim{:time}(1:6),), rand(6))
+precipitation = YAXArray((Dim{:time}(1:6),), rand(6))
+cubes = [temperature,precipitation]
+var_axis = Dim{:variable}(["temp", "prep"])
+combined = concatenatecubes(cubes, var_axis)
╭─────────────────────────╮
+│ 6×2 YAXArray{Float64,2} │
+├─────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time     Sampled{Int64} 1:6 ForwardOrdered Regular Points,
+  → variable Categorical{String} ["temp", "prep"] ReverseOrdered
+├────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└────────────────────────────────────────────────────────────────┘
`,10)]))}const E=i(t,[["render",p]]);export{c as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.lean.js b/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.lean.js new file mode 100644 index 00000000..39f1b599 --- /dev/null +++ b/previews/PR437/assets/UserGuide_combine.md.D52gFSsu.lean.js @@ -0,0 +1,28 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Combine YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/combine.md","filePath":"UserGuide/combine.md","lastUpdated":null}'),t={name:"UserGuide/combine.md"};function p(l,s,h,k,r,d){return e(),a("div",null,s[0]||(s[0]=[n(`

Combine YAXArrays

Data is often scattered across multiple files and corresponding arrays, e.g. one file per time step. This section describes methods on how to combine them into a single YAXArray.

cat along an existing dimension

Here we use cat to combine two arrays consisting of data from the first and the second half of a year into one single array containing the whole year. We glue the arrays along the first dimension using dims = 1: The resulting array whole_year still has one dimension, i.e. time, but with 12 instead of 6 elements.

julia
using YAXArrays
+
+first_half = YAXArray((Dim{:time}(1:6),), rand(6))
+second_half = YAXArray((Dim{:time}(7:12),), rand(6))
+whole_year = cat(first_half, second_half, dims = 1)
╭────────────────────────────────╮
+│ 12-element YAXArray{Float64,1} │
+├────────────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time Sampled{Int64} [1, 2, …, 11, 12] ForwardOrdered Regular Points
+├───────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├──────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└───────────────────────────────────────────────────────────────────────┘

concatenatecubes to a new dimension

Here we use concatenatecubes to combine two arrays of different variables that have the same dimensions. The resulting array combined has an additional dimension variable indicating from which array the element values originates. Note that using a Dataset instead is a more flexible approach in handling different variables.

julia
using YAXArrays
+
+temperature = YAXArray((Dim{:time}(1:6),), rand(6))
+precipitation = YAXArray((Dim{:time}(1:6),), rand(6))
+cubes = [temperature,precipitation]
+var_axis = Dim{:variable}(["temp", "prep"])
+combined = concatenatecubes(cubes, var_axis)
╭─────────────────────────╮
+│ 6×2 YAXArray{Float64,2} │
+├─────────────────────────┴──────────────────────────────── dims ┐
+  ↓ time     Sampled{Int64} 1:6 ForwardOrdered Regular Points,
+  → variable Categorical{String} ["temp", "prep"] ReverseOrdered
+├────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└────────────────────────────────────────────────────────────────┘
`,10)]))}const E=i(t,[["render",p]]);export{c as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.js b/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.js new file mode 100644 index 00000000..abef0ec7 --- /dev/null +++ b/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.js @@ -0,0 +1,265 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Compute YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/compute.md","filePath":"UserGuide/compute.md","lastUpdated":null}'),p={name:"UserGuide/compute.md"};function e(l,s,h,k,d,r){return t(),a("div",null,s[0]||(s[0]=[n(`

Compute YAXArrays

This section describes how to create new YAXArrays by performing operations on them.

Let's start by creating an example dataset:

julia
using YAXArrays
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Modify elements of a YAXArray

julia
a[1,2,3]
0.4802525933892837
julia
a[1,2,3] = 42
42
julia
a[1,2,3]
42.0

WARNING

Some arrays, e.g. those saved in a cloud object storage are immutable making any modification of the data impossible.

Arithmetics

Add a value to all elements of an array and save it as a new array:

julia
a2 = a .+ 5
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2[1,2,3] == a[1,2,3] + 5
true

map

Apply a function on every element of an array individually:

julia
offset = 5
+map(a) do x
+    (x + offset) / 2 * 3
+end
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This keeps all dimensions unchanged. Note, that here we can not access neighboring elements. In this case, we can use mapslices or mapCube instead. Each element of the array is processed individually.

The code runs very fast, because map applies the function lazily. Actual computation will be performed only on demand, e.g. when elements were explicitly requested or further computations were performed.

mapslices

Reduce the time dimension by calculating the average value of all points in time:

julia
import Statistics: mean
+mapslices(mean, a, dims="Time")
╭───────────────────────────────────────────╮
+│ 10×15 YAXArray{Union{Missing, Float64},2} │
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘

There is no time dimension left, because there is only one value left after averaging all time steps. We can also calculate spatial means resulting in one value per time step:

julia
mapslices(mean, a, dims=("lat", "lon"))
╭────────────────────────────────────────────────╮
+│ 30-element YAXArray{Union{Missing, Float64},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

mapCube

mapCube is the most flexible way to apply a function over subsets of an array. Dimensions may be added or removed.

Operations over several YAXArrays

Here, we will define a simple function, that will take as input several YAXArrays. But first, let's load the necessary packages.

julia
using YAXArrays, Zarr
+using Dates

Define function in space and time

julia
f(lo, la, t) = (lo + la + Dates.dayofyear(t))
f (generic function with 1 method)

now, mapCube requires this function to be wrapped as follows

julia
function g(xout, lo, la, t)
+    xout .= f.(lo, la, t)
+end
g (generic function with 1 method)

INFO

Note the . after f, this is because we will slice across time, namely, the function is broadcasted along this dimension.

Here, we do create YAXArrays only with the desired dimensions as

julia
julia> lon = YAXArray(Dim{:lon}(range(1, 15)))
╭──────────────────────────────╮
+15-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lon Sampled{Int64} 1:15 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 120.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> lat = YAXArray(Dim{:lat}(range(1, 10)))
╭──────────────────────────────╮
+10-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 80.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

And a time Cube's Axis

julia
tspan = Date("2022-01-01"):Day(1):Date("2022-01-30")
+time = YAXArray(Dim{:time}(tspan))
╭─────────────────────────────╮
+│ 30-element YAXArray{Date,1} │
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the following can be extended to arbitrary YAXArrays with additional data and dimensions.

Let's generate a new cube using mapCube and saving the output directly into disk.

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims(), InDims(), InDims("time")),
+           outdims = OutDims("time", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+30×15×10 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

"time axis goes first"

Note that currently the time axis in the output cube goes first.

Check that it is working

julia
julia> gen_cube.data[1, :, :]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

but, we can generate a another cube with a different output order as follows

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims("lon"), InDims(), InDims()),
+           outdims = OutDims("lon", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+15×10×30 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

INFO

Note that now the broadcasted dimension is lon.

we can see this by slicing on the last dimension now

julia
gen_cube.data[:, :, 1]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

which outputs the same as the gen_cube.data[1, :, :] called above.

Creating a vector array

Here we transform a raster array with spatial dimension lat and lon into a vector array having just one spatial dimension i.e. region. First, create the raster array:

julia
using YAXArrays
+using DimensionalData
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+raster_arr = YAXArray(axlist, data)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Then, create a Matrix with the same spatial dimensions indicating to which region each point belongs to:

julia
regions_mat = map(Iterators.product(raster_arr.lon, raster_arr.lat)) do (lon, lat)
+    1 <= lon < 10 && 1 <= lat < 5 && return "A"
+    1 <= lon < 10 && 5 <= lat < 10 && return "B"
+    10 <= lon < 15 && 1 <= lat < 5 && return "C"
+    return "D"
+end
+regions_mat = DimArray(regions_mat, (raster_arr.lon, raster_arr.lat))
╭──────────────────────────╮
+│ 10×15 DimArray{String,2} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0   1.28571  1.57143  1.85714  …  4.14286  4.42857  4.71429  5.0
+  1.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  2.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  3.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  4.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  5.0   "A"   "A"      "A"      "A"     …   "A"      "A"      "A"      "B"
+  6.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  7.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  8.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  9.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+ 10.0   "C"   "C"      "C"      "C"     …   "C"      "C"      "C"      "D"

which has the same spatial dimensions as the raster array at any given point in time:

julia
DimArray(raster_arr[time = 1])
╭───────────────────────────╮
+│ 10×15 DimArray{Float64,2} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0        1.28571   1.57143    …  4.42857   4.71429    5.0
+  1.0  0.0701065  0.963886  0.515763      0.324908  0.675918   0.745998
+  2.0  0.354703   0.231698  0.371974      0.809426  0.582551   0.879515
+  3.0  0.0696778  0.96757   0.440296      0.606578  0.95716    0.21498
+  ⋮                                    ⋱                       ⋮
+  8.0  0.417033   0.546641  0.788483      0.139694  0.879286   0.945109
+  9.0  0.877062   0.210902  0.0504114     0.831314  0.0645807  0.0443643
+ 10.0  0.880753   0.587901  0.0450445  …  0.634789  0.202429   0.697013

Now we calculate the list of corresponding points for each region. This will be re-used for each point in time during the final mapCube. In addition, this avoids the allocation of unnecessary memory.

julia
regions = ["A", "B", "C", "D"]
+points_of_regions = map(enumerate(regions)) do (i,region)
+    region => findall(isequal(region), regions_mat)
+end |> Dict |> sort
OrderedCollections.OrderedDict{String, Vector{CartesianIndex{2}}} with 4 entries:
+  "A" => [CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), Car…
+  "B" => [CartesianIndex(1, 15), CartesianIndex(2, 15), CartesianIndex(3, 15), …
+  "C" => [CartesianIndex(10, 1), CartesianIndex(10, 2), CartesianIndex(10, 3), …
+  "D" => [CartesianIndex(10, 15)]

Finally, we can transform the entire raster array:

julia
vector_array = mapCube(
+    raster_arr,
+    indims=InDims("lon", "lat"),
+    outdims=OutDims(Dim{:region}(regions))
+) do xout, xin
+    for (region_pos, points) in enumerate(points_of_regions.vals)
+        # aggregate values of points in the current region at the current date
+        xout[region_pos] = sum(view(xin, points))
+    end
+end
╭──────────────────────────────────────────╮
+│ 4×30 YAXArray{Union{Missing, Float64},2} │
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+  ↓ region Categorical{String} ["A", "B", "C", "D"] ForwardOrdered,
+  → time   Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 960.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

This gives us a vector array with only one spatial dimension, i.e. the region. Note that we still have 30 points in time. The transformation was applied for each date separately.

Hereby, xin is a 10x15 array representing a map at a given time and xout is a 4 element vector of missing values initially representing the 4 regions at that date. Then, we set each output element by the sum of all corresponding points

Distributed Computation

All map methods apply a function on all elements of all non-input dimensions separately. This allows to run each map function call in parallel. For example, we can execute each date of a time series in a different CPU thread during spatial aggregation.

The following code does a time mean over all grid points using multiple CPUs of a local machine:

julia
using YAXArrays
+using Dates
+using Distributed
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
+
+addprocs(2)
+
+@everywhere begin
+  using YAXArrays
+  using Zarr
+  using Statistics
+end
+
+@everywhere function mymean(output, pixel)
+  @show "doing a mean"
+     output[:] .= mean(pixel)
+end
+
+mapCube(mymean, a, indims=InDims("time"), outdims=OutDims())

In the last example, mapCube was used to map the mymean function. mapslices is a convenient function that can replace mapCube, where you can omit defining an extra function with the output argument as an input (e.g. mymean). It is possible to simply use mapslice

julia
mapslices(mean  skipmissing, a, dims="time")

It is also possible to distribute easily the workload on a cluster, with little modification to the code. To do so, we use the ClusterManagers package.

julia
using Distributed
+using ClusterManagers
+addprocs(SlurmManager(10))
`,95)]))}const E=i(p,[["render",e]]);export{g as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.lean.js b/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.lean.js new file mode 100644 index 00000000..abef0ec7 --- /dev/null +++ b/previews/PR437/assets/UserGuide_compute.md.B_a3BBtd.lean.js @@ -0,0 +1,265 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Compute YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/compute.md","filePath":"UserGuide/compute.md","lastUpdated":null}'),p={name:"UserGuide/compute.md"};function e(l,s,h,k,d,r){return t(),a("div",null,s[0]||(s[0]=[n(`

Compute YAXArrays

This section describes how to create new YAXArrays by performing operations on them.

Let's start by creating an example dataset:

julia
using YAXArrays
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Modify elements of a YAXArray

julia
a[1,2,3]
0.4802525933892837
julia
a[1,2,3] = 42
42
julia
a[1,2,3]
42.0

WARNING

Some arrays, e.g. those saved in a cloud object storage are immutable making any modification of the data impossible.

Arithmetics

Add a value to all elements of an array and save it as a new array:

julia
a2 = a .+ 5
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2[1,2,3] == a[1,2,3] + 5
true

map

Apply a function on every element of an array individually:

julia
offset = 5
+map(a) do x
+    (x + offset) / 2 * 3
+end
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This keeps all dimensions unchanged. Note, that here we can not access neighboring elements. In this case, we can use mapslices or mapCube instead. Each element of the array is processed individually.

The code runs very fast, because map applies the function lazily. Actual computation will be performed only on demand, e.g. when elements were explicitly requested or further computations were performed.

mapslices

Reduce the time dimension by calculating the average value of all points in time:

julia
import Statistics: mean
+mapslices(mean, a, dims="Time")
╭───────────────────────────────────────────╮
+│ 10×15 YAXArray{Union{Missing, Float64},2} │
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘

There is no time dimension left, because there is only one value left after averaging all time steps. We can also calculate spatial means resulting in one value per time step:

julia
mapslices(mean, a, dims=("lat", "lon"))
╭────────────────────────────────────────────────╮
+│ 30-element YAXArray{Union{Missing, Float64},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

mapCube

mapCube is the most flexible way to apply a function over subsets of an array. Dimensions may be added or removed.

Operations over several YAXArrays

Here, we will define a simple function, that will take as input several YAXArrays. But first, let's load the necessary packages.

julia
using YAXArrays, Zarr
+using Dates

Define function in space and time

julia
f(lo, la, t) = (lo + la + Dates.dayofyear(t))
f (generic function with 1 method)

now, mapCube requires this function to be wrapped as follows

julia
function g(xout, lo, la, t)
+    xout .= f.(lo, la, t)
+end
g (generic function with 1 method)

INFO

Note the . after f, this is because we will slice across time, namely, the function is broadcasted along this dimension.

Here, we do create YAXArrays only with the desired dimensions as

julia
julia> lon = YAXArray(Dim{:lon}(range(1, 15)))
╭──────────────────────────────╮
+15-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lon Sampled{Int64} 1:15 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 120.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> lat = YAXArray(Dim{:lat}(range(1, 10)))
╭──────────────────────────────╮
+10-element YAXArray{Int64,1}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 80.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

And a time Cube's Axis

julia
tspan = Date("2022-01-01"):Day(1):Date("2022-01-30")
+time = YAXArray(Dim{:time}(tspan))
╭─────────────────────────────╮
+│ 30-element YAXArray{Date,1} │
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the following can be extended to arbitrary YAXArrays with additional data and dimensions.

Let's generate a new cube using mapCube and saving the output directly into disk.

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims(), InDims(), InDims("time")),
+           outdims = OutDims("time", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+30×15×10 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

"time axis goes first"

Note that currently the time axis in the output cube goes first.

Check that it is working

julia
julia> gen_cube.data[1, :, :]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

but, we can generate a another cube with a different output order as follows

julia
julia> gen_cube = mapCube(g, (lon, lat, time);
+           indims = (InDims("lon"), InDims(), InDims()),
+           outdims = OutDims("lon", overwrite=true, path="my_gen_cube.zarr", backend=:zarr,
+           outtype = Float32)
+           # max_cache=1e9
+       )
╭──────────────────────────────────────────────╮
+15×10×30 YAXArray{Union{Missing, Float32},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Int64} 1:15 ForwardOrdered Regular Points,
+lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 1 entry:
+  "missing_value" => 1.0f32
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 17.58 KB
+└──────────────────────────────────────────────────────────────────────────────┘

INFO

Note that now the broadcasted dimension is lon.

we can see this by slicing on the last dimension now

julia
gen_cube.data[:, :, 1]
15×10 Matrix{Union{Missing, Float32}}:
+  3.0   4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0
+  4.0   5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0
+  5.0   6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0
+  6.0   7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0
+  7.0   8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
+  8.0   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0
+  9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0
+ 10.0  11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0
+ 11.0  12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0
+ 12.0  13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0
+ 13.0  14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0
+ 14.0  15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0
+ 15.0  16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0
+ 16.0  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0
+ 17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0  25.0  26.0

which outputs the same as the gen_cube.data[1, :, :] called above.

Creating a vector array

Here we transform a raster array with spatial dimension lat and lon into a vector array having just one spatial dimension i.e. region. First, create the raster array:

julia
using YAXArrays
+using DimensionalData
+using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+raster_arr = YAXArray(axlist, data)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Then, create a Matrix with the same spatial dimensions indicating to which region each point belongs to:

julia
regions_mat = map(Iterators.product(raster_arr.lon, raster_arr.lat)) do (lon, lat)
+    1 <= lon < 10 && 1 <= lat < 5 && return "A"
+    1 <= lon < 10 && 5 <= lat < 10 && return "B"
+    10 <= lon < 15 && 1 <= lat < 5 && return "C"
+    return "D"
+end
+regions_mat = DimArray(regions_mat, (raster_arr.lon, raster_arr.lat))
╭──────────────────────────╮
+│ 10×15 DimArray{String,2} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0   1.28571  1.57143  1.85714  …  4.14286  4.42857  4.71429  5.0
+  1.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  2.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  3.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  4.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  5.0   "A"   "A"      "A"      "A"     …   "A"      "A"      "A"      "B"
+  6.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  7.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  8.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+  9.0   "A"   "A"      "A"      "A"         "A"      "A"      "A"      "B"
+ 10.0   "C"   "C"      "C"      "C"     …   "C"      "C"      "C"      "D"

which has the same spatial dimensions as the raster array at any given point in time:

julia
DimArray(raster_arr[time = 1])
╭───────────────────────────╮
+│ 10×15 DimArray{Float64,2} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────────────────┘
+  ↓ →  1.0        1.28571   1.57143    …  4.42857   4.71429    5.0
+  1.0  0.0701065  0.963886  0.515763      0.324908  0.675918   0.745998
+  2.0  0.354703   0.231698  0.371974      0.809426  0.582551   0.879515
+  3.0  0.0696778  0.96757   0.440296      0.606578  0.95716    0.21498
+  ⋮                                    ⋱                       ⋮
+  8.0  0.417033   0.546641  0.788483      0.139694  0.879286   0.945109
+  9.0  0.877062   0.210902  0.0504114     0.831314  0.0645807  0.0443643
+ 10.0  0.880753   0.587901  0.0450445  …  0.634789  0.202429   0.697013

Now we calculate the list of corresponding points for each region. This will be re-used for each point in time during the final mapCube. In addition, this avoids the allocation of unnecessary memory.

julia
regions = ["A", "B", "C", "D"]
+points_of_regions = map(enumerate(regions)) do (i,region)
+    region => findall(isequal(region), regions_mat)
+end |> Dict |> sort
OrderedCollections.OrderedDict{String, Vector{CartesianIndex{2}}} with 4 entries:
+  "A" => [CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), Car…
+  "B" => [CartesianIndex(1, 15), CartesianIndex(2, 15), CartesianIndex(3, 15), …
+  "C" => [CartesianIndex(10, 1), CartesianIndex(10, 2), CartesianIndex(10, 3), …
+  "D" => [CartesianIndex(10, 15)]

Finally, we can transform the entire raster array:

julia
vector_array = mapCube(
+    raster_arr,
+    indims=InDims("lon", "lat"),
+    outdims=OutDims(Dim{:region}(regions))
+) do xout, xin
+    for (region_pos, points) in enumerate(points_of_regions.vals)
+        # aggregate values of points in the current region at the current date
+        xout[region_pos] = sum(view(xin, points))
+    end
+end
╭──────────────────────────────────────────╮
+│ 4×30 YAXArray{Union{Missing, Float64},2} │
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+  ↓ region Categorical{String} ["A", "B", "C", "D"] ForwardOrdered,
+  → time   Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 960.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

This gives us a vector array with only one spatial dimension, i.e. the region. Note that we still have 30 points in time. The transformation was applied for each date separately.

Hereby, xin is a 10x15 array representing a map at a given time and xout is a 4 element vector of missing values initially representing the 4 regions at that date. Then, we set each output element by the sum of all corresponding points

Distributed Computation

All map methods apply a function on all elements of all non-input dimensions separately. This allows to run each map function call in parallel. For example, we can execute each date of a time series in a different CPU thread during spatial aggregation.

The following code does a time mean over all grid points using multiple CPUs of a local machine:

julia
using YAXArrays
+using Dates
+using Distributed
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a = YAXArray(axlist, data, properties)
+
+addprocs(2)
+
+@everywhere begin
+  using YAXArrays
+  using Zarr
+  using Statistics
+end
+
+@everywhere function mymean(output, pixel)
+  @show "doing a mean"
+     output[:] .= mean(pixel)
+end
+
+mapCube(mymean, a, indims=InDims("time"), outdims=OutDims())

In the last example, mapCube was used to map the mymean function. mapslices is a convenient function that can replace mapCube, where you can omit defining an extra function with the output argument as an input (e.g. mymean). It is possible to simply use mapslice

julia
mapslices(mean  skipmissing, a, dims="time")

It is also possible to distribute easily the workload on a cluster, with little modification to the code. To do so, we use the ClusterManagers package.

julia
using Distributed
+using ClusterManagers
+addprocs(SlurmManager(10))
`,95)]))}const E=i(p,[["render",e]]);export{g as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.js b/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.js new file mode 100644 index 00000000..0850fdec --- /dev/null +++ b/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.js @@ -0,0 +1,78 @@ +import{_ as a,c as n,a2 as i,o as p}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Convert YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/convert.md","filePath":"UserGuide/convert.md","lastUpdated":null}'),e={name:"UserGuide/convert.md"};function l(t,s,r,h,d,k){return p(),n("div",null,s[0]||(s[0]=[i(`

Convert YAXArrays

This section describes how to convert variables from types of other Julia packages into YAXArrays and vice versa.

WARNING

YAXArrays is designed to work with large datasets that are way larger than the memory. However, most types are designed to work in memory. Those conversions are only possible if the entire dataset fits into memory. In addition, metadata might be lost during conversion.

Convert Base.Array

Convert Base.Array to YAXArray:

julia
using YAXArrays
+
+m = rand(5,10)
+a = YAXArray(m)
╭──────────────────────────╮
+│ 5×10 YAXArray{Float64,2} │
+├──────────────────────────┴──────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 400.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Convert YAXArray to Base.Array:

julia
m2 = collect(a.data)
5×10 Matrix{Float64}:
+ 0.795153  0.0264902  0.0804585  0.0910572  …  0.606617  0.558735   0.979087
+ 0.318029  0.777976   0.351172   0.442589      0.934129  0.279857   0.391744
+ 0.290659  0.478507   0.611842   0.339863      0.364872  0.0391939  0.296448
+ 0.899311  0.365121   0.912882   0.0746545     0.197869  0.306701   0.634033
+ 0.15752   0.818753   0.14209    0.298586      0.396465  0.187958   0.027089

Convert Raster

A Raster as defined in Rasters.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types:

julia
using Rasters
+
+lon, lat = X(25:1:30), Y(25:1:30)
+time = Ti(2000:2024)
+ras = Raster(rand(lon, lat, time))
+a = YAXArray(dims(ras), ras.data)
╭────────────────────────────╮
+│ 6×6×25 YAXArray{Float64,3} │
+├────────────────────────────┴────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────── file size ┤ 
+  file size: 7.03 KB
+└─────────────────────────────────────────────────────────────┘
julia
ras2 = Raster(a)
╭──────────────────────────╮
+│ 6×6×25 Raster{Float64,3} │
+├──────────────────────────┴──────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (2000, 2024))
+
+└─────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26           27         28          29          30
+ 25     0.460901   0.448599     0.310425   0.333059    0.651427    0.865549
+ 26     0.294336   0.162016     0.159973   0.245293    0.0536221   0.810377
+ 27     0.764827   0.317333     0.536345   0.851063    0.932986    0.859051
+ 28     0.728649   0.885421     0.438166   0.0328466   0.21626     0.517644
+ 29     0.758648   0.00939122   0.864794   0.512244    0.988263    0.423459
+ 30     0.874109   0.743847     0.410173   0.85881     0.103772    0.81669

Convert DimArray

A DimArray as defined in DimensionalData.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types.

Convert DimArray to YAXArray:

julia
using DimensionalData
+using YAXArrayBase
+
+dim_arr = rand(X(1:5), Y(10.0:15.0), metadata = Dict{String, Any}())
+a = yaxconvert(YAXArray, dim_arr)
╭─────────────────────────╮
+│ 5×6 YAXArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────┘

Convert YAXArray to DimArray:

julia
dim_arr2 = yaxconvert(DimArray, a)
╭─────────────────────────╮
+│ 5×6 DimArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────┘
+ ↓ →  10.0       11.0       12.0        13.0       14.0        15.0
+ 1     0.748974   0.118396   0.645149    0.956491   0.598932    0.230696
+ 2     0.58618    0.103921   0.0589974   0.891881   0.305112    0.434868
+ 3     0.692366   0.613363   0.120628    0.586712   0.936887    0.769308
+ 4     0.823196   0.680373   0.123279    0.875862   0.0764503   0.903606
+ 5     0.372063   0.775785   0.0750832   0.689982   0.747443    0.201471

INFO

At the moment there is no support to save a DimArray directly into disk as a NetCDF or a Zarr file.

`,25)]))}const g=a(e,[["render",l]]);export{c as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.lean.js b/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.lean.js new file mode 100644 index 00000000..0850fdec --- /dev/null +++ b/previews/PR437/assets/UserGuide_convert.md.dKg9ro9h.lean.js @@ -0,0 +1,78 @@ +import{_ as a,c as n,a2 as i,o as p}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Convert YAXArrays","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/convert.md","filePath":"UserGuide/convert.md","lastUpdated":null}'),e={name:"UserGuide/convert.md"};function l(t,s,r,h,d,k){return p(),n("div",null,s[0]||(s[0]=[i(`

Convert YAXArrays

This section describes how to convert variables from types of other Julia packages into YAXArrays and vice versa.

WARNING

YAXArrays is designed to work with large datasets that are way larger than the memory. However, most types are designed to work in memory. Those conversions are only possible if the entire dataset fits into memory. In addition, metadata might be lost during conversion.

Convert Base.Array

Convert Base.Array to YAXArray:

julia
using YAXArrays
+
+m = rand(5,10)
+a = YAXArray(m)
╭──────────────────────────╮
+│ 5×10 YAXArray{Float64,2} │
+├──────────────────────────┴──────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 400.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Convert YAXArray to Base.Array:

julia
m2 = collect(a.data)
5×10 Matrix{Float64}:
+ 0.795153  0.0264902  0.0804585  0.0910572  …  0.606617  0.558735   0.979087
+ 0.318029  0.777976   0.351172   0.442589      0.934129  0.279857   0.391744
+ 0.290659  0.478507   0.611842   0.339863      0.364872  0.0391939  0.296448
+ 0.899311  0.365121   0.912882   0.0746545     0.197869  0.306701   0.634033
+ 0.15752   0.818753   0.14209    0.298586      0.396465  0.187958   0.027089

Convert Raster

A Raster as defined in Rasters.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types:

julia
using Rasters
+
+lon, lat = X(25:1:30), Y(25:1:30)
+time = Ti(2000:2024)
+ras = Raster(rand(lon, lat, time))
+a = YAXArray(dims(ras), ras.data)
╭────────────────────────────╮
+│ 6×6×25 YAXArray{Float64,3} │
+├────────────────────────────┴────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────── file size ┤ 
+  file size: 7.03 KB
+└─────────────────────────────────────────────────────────────┘
julia
ras2 = Raster(a)
╭──────────────────────────╮
+│ 6×6×25 Raster{Float64,3} │
+├──────────────────────────┴──────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{Int64} 2000:2024 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├───────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (2000, 2024))
+
+└─────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26           27         28          29          30
+ 25     0.460901   0.448599     0.310425   0.333059    0.651427    0.865549
+ 26     0.294336   0.162016     0.159973   0.245293    0.0536221   0.810377
+ 27     0.764827   0.317333     0.536345   0.851063    0.932986    0.859051
+ 28     0.728649   0.885421     0.438166   0.0328466   0.21626     0.517644
+ 29     0.758648   0.00939122   0.864794   0.512244    0.988263    0.423459
+ 30     0.874109   0.743847     0.410173   0.85881     0.103772    0.81669

Convert DimArray

A DimArray as defined in DimensionalData.jl has a same supertype of a YAXArray, i.e. AbstractDimArray, allowing easy conversion between those types.

Convert DimArray to YAXArray:

julia
using DimensionalData
+using YAXArrayBase
+
+dim_arr = rand(X(1:5), Y(10.0:15.0), metadata = Dict{String, Any}())
+a = yaxconvert(YAXArray, dim_arr)
╭─────────────────────────╮
+│ 5×6 YAXArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────── file size ┤ 
+  file size: 240.0 bytes
+└──────────────────────────────────────────────────────────────────┘

Convert YAXArray to DimArray:

julia
dim_arr2 = yaxconvert(DimArray, a)
╭─────────────────────────╮
+│ 5×6 DimArray{Float64,2} │
+├─────────────────────────┴────────────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Y Sampled{Float64} 10.0:1.0:15.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+└──────────────────────────────────────────────────────────────────┘
+ ↓ →  10.0       11.0       12.0        13.0       14.0        15.0
+ 1     0.748974   0.118396   0.645149    0.956491   0.598932    0.230696
+ 2     0.58618    0.103921   0.0589974   0.891881   0.305112    0.434868
+ 3     0.692366   0.613363   0.120628    0.586712   0.936887    0.769308
+ 4     0.823196   0.680373   0.123279    0.875862   0.0764503   0.903606
+ 5     0.372063   0.775785   0.0750832   0.689982   0.747443    0.201471

INFO

At the moment there is no support to save a DimArray directly into disk as a NetCDF or a Zarr file.

`,25)]))}const g=a(e,[["render",l]]);export{c as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.js b/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.js new file mode 100644 index 00000000..7e931556 --- /dev/null +++ b/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.js @@ -0,0 +1,48 @@ +import{_ as a,c as i,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Create YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/create.md","filePath":"UserGuide/create.md","lastUpdated":null}'),e={name:"UserGuide/create.md"};function p(l,s,h,k,r,d){return t(),i("div",null,s[0]||(s[0]=[n(`

Create YAXArrays and Datasets

This section describes how to create arrays and datasets by filling values directly.

Create a YAXArray

We can create a new YAXArray by filling the values directly:

julia
using YAXArrays
+a1 = YAXArray(rand(10, 20, 5))
╭─────────────────────────────╮
+│ 10×20×5 YAXArray{Float64,3} │
+├─────────────────────────────┴────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 7.81 KB
+└──────────────────────────────────────────────────────────────────────┘

The dimensions have only generic names, e.g. Dim_1 and only integer values. We can also specify the dimensions with custom names enabling easier access:

julia
using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data2 = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a2 = YAXArray(axlist, data2, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2.properties
Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
julia
a2.axes
(↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+→ lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)

Create a Dataset

julia
data3 = rand(30, 10, 15)
+a3 = YAXArray(axlist, data3, properties)
+
+arrays = Dict(:a2 => a2, :a3 => a3)
+ds = Dataset(; properties, arrays...)
YAXArray Dataset
+Shared Axes: 
+  (↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)
+
+Variables: 
+a2, a3
+
+Properties: Dict(:origin => "user guide")
`,16)]))}const o=a(e,[["render",p]]);export{g as __pageData,o as default}; diff --git a/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.lean.js b/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.lean.js new file mode 100644 index 00000000..7e931556 --- /dev/null +++ b/previews/PR437/assets/UserGuide_create.md.hCVHNj4a.lean.js @@ -0,0 +1,48 @@ +import{_ as a,c as i,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Create YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/create.md","filePath":"UserGuide/create.md","lastUpdated":null}'),e={name:"UserGuide/create.md"};function p(l,s,h,k,r,d){return t(),i("div",null,s[0]||(s[0]=[n(`

Create YAXArrays and Datasets

This section describes how to create arrays and datasets by filling values directly.

Create a YAXArray

We can create a new YAXArray by filling the values directly:

julia
using YAXArrays
+a1 = YAXArray(rand(10, 20, 5))
╭─────────────────────────────╮
+│ 10×20×5 YAXArray{Float64,3} │
+├─────────────────────────────┴────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(20) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 7.81 KB
+└──────────────────────────────────────────────────────────────────────┘

The dimensions have only generic names, e.g. Dim_1 and only integer values. We can also specify the dimensions with custom names enabling easier access:

julia
using Dates
+
+axlist = (
+    Dim{:time}(Date("2022-01-01"):Day(1):Date("2022-01-30")),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15)),
+)
+data2 = rand(30, 10, 15)
+properties = Dict(:origin => "user guide")
+a2 = YAXArray(axlist, data2, properties)
╭──────────────────────────────╮
+│ 30×10×15 YAXArray{Float64,3} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 35.16 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
a2.properties
Dict{Symbol, String} with 1 entry:
+  :origin => "user guide"
julia
a2.axes
(↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+→ lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)

Create a Dataset

julia
data3 = rand(30, 10, 15)
+a3 = YAXArray(axlist, data3, properties)
+
+arrays = Dict(:a2 => a2, :a3 => a3)
+ds = Dataset(; properties, arrays...)
YAXArray Dataset
+Shared Axes: 
+  (↓ time Sampled{Date} Date("2022-01-01"):Dates.Day(1):Date("2022-01-30") ForwardOrdered Regular Points,
+  → lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points)
+
+Variables: 
+a2, a3
+
+Properties: Dict(:origin => "user guide")
`,16)]))}const o=a(e,[["render",p]]);export{g as __pageData,o as default}; diff --git a/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.js b/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.js new file mode 100644 index 00000000..5f316555 --- /dev/null +++ b/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.js @@ -0,0 +1,359 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const t="/YAXArrays.jl/previews/PR437/assets/zxfqnjz.DMLwX5kL.jpeg",o=JSON.parse('{"title":"Frequently Asked Questions (FAQ)","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/faq.md","filePath":"UserGuide/faq.md","lastUpdated":null}'),l={name:"UserGuide/faq.md"};function h(p,s,k,d,r,g){return e(),a("div",null,s[0]||(s[0]=[n(`

Frequently Asked Questions (FAQ)

The purpose of this section is to do a collection of small convinient pieces of code on how to do simple things.

Extract the axes names from a Cube

julia
using YAXArrays
+using DimensionalData
julia
julia> c = YAXArray(rand(10, 10, 5))
╭─────────────────────────────╮
+10×10×5 YAXArray{Float64,3}
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 3.91 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> caxes(c) # former way of doing it
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

WARNING

To get the axes of a YAXArray use the dims function instead of the caxes function

julia
julia> dims(c)
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

INFO

Also, use DD.rebuild(c, values) to copy axes from c and build a new cube but with different values.

rebuild

As an example let's consider the following

julia
using YAXArrays
+using DimensionalData
+
+c = YAXArray(ones(Int, 10,10))
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────┘

then creating a new c with the same structure (axes) but different values is done by

julia
julia> new_c = rebuild(c, rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the type is now Float64. Or, we could create a new structure but using the dimensions from yax explicitly

julia
julia> c_c = YAXArray(dims(c), rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

which achieves the same goal as rebuild.

Obtain values from axes and data from the cube

There are two options to collect values from axes. In this examples the axis ranges from 1 to 10.

These two examples bring the same result

julia
collect(getAxis("Dim_1", c).val)
+collect(c.axes[1].val)
10-element Vector{Int64}:
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10

to collect data from a cube works exactly the same as doing it from an array

julia
julia> c[:, :, 1]
╭─────────────────────────╮
+10×10 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I concatenate cubes

It is possible to concatenate several cubes that shared the same dimensions using the [concatenatecubes]@ref function.

Let's create two dummy cubes

julia
using YAXArrays
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15))
+    )
+
+data1 = rand(20, 10, 15)
+ds1 = YAXArray(axlist, data1)
+
+data2 = rand(20, 10, 15)
+ds2 = YAXArray(axlist, data2)

Now we can concatenate ds1 and ds2:

julia
julia> dsfinal = concatenatecubes([ds1, ds2], Dim{:Variables}(["var1", "var2"]))
╭────────────────────────────────╮
+20×10×15×2 YAXArray{Float64,4}
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+time      Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon       Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat       Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+Variables Categorical{String} ["var1", "var2"] ForwardOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I subset a YAXArray ( Cube ) or Dataset?

These are the three main datatypes provided by the YAXArrays libray. You can find a description of them here. A Cube is no more than a YAXArray, so, we will not explicitly tell about a Cube.

Subsetting a YAXArray

Let's start by creating a dummy YAXArray.

Firstly, load the required libraries

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data, however the intervals notation should be used instead, i.e. \`a .. b\`.

Define the time span of the YAXArray

julia
t = Date("2020-01-01"):Month(1):Date("2022-12-31")
Date("2020-01-01"):Dates.Month(1):Date("2022-12-01")

create YAXArray axes

julia
axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
(↓ Lon  1:10,
+→ Lat  1:10,
+↗ Time Date("2020-01-01"):Dates.Month(1):Date("2022-12-01"))

create the YAXArray

julia
y = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
╭────────────────────────────╮
+│ 10×10×36 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 28.12 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Now we subset the YAXArray by any dimension.

Subset YAXArray by years

julia
ytime = y[Time=Between(Date(2021,1,1), Date(2021,12,31))]
╭────────────────────────────╮
+│ 10×10×12 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-01-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by a specific date

julia
ytime2 = y[Time=At(Date("2021-05-01"))]
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────── dims ┐
+  ↓ Lon Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────┘

Subset YAXArray by a date range

julia
ytime3 = y[Time=Date("2021-05-01") .. Date("2021-12-01")]
╭───────────────────────────╮
+│ 10×10×8 YAXArray{Int64,3} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-05-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 6.25 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by longitude and latitude

julia
ylonlat = y[Lon=1 .. 5, Lat=5 .. 10]
╭──────────────────────────╮
+│ 5×6×36 YAXArray{Int64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 8.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subsetting a Dataset

In a dataset, we can have several variables (YAXArrays) that share some or all of their dimensions.

Subsetting a Dataset whose variables share all their dimensions

This works for YAXArrays. Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
+
+var1 = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
+var2 = YAXArray(axes, reshape((1:3600)*5, (10, 10, 36)))
+
+ds = Dataset(; var1=var1, var2=var2)
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2
julia
ds_lonlat = ds[Lon=1 .. 5, Lat=5 .. 10]
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2

Subsetting a Dataset whose variables share some but not all of their dimensions

In this case, if we subset by the common dimension/s, this works the same as for YAXArrays, Cubes, and datasets that share all their dimensions.

But we can also subset a variable by the values of another variable with which it shares some dimensions.

Warning

If your data is not loaded into memory, the selection will be too slow. So, you have load into memory, at least, the variable with which you make the selection.

Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" selector for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+common_axis = Dim{:points}(1:100)
+time_axis =   Dim{:Time}(t)
+
+# Note that longitudes and latitudes are not dimensions, but YAXArrays
+longitudes = YAXArray((common_axis,), rand(1:369, 100)) # 100 random values taken from 1 to 359
+latitudes  = YAXArray((common_axis,), rand(0:90, 100))  # 100 random values taken from 0 to 90
+temperature = YAXArray((common_axis, time_axis), rand(-40:40, (100, 36)))
+
+ds = Dataset(; longitudes=longitudes, latitudes=latitudes, temperature=temperature)
YAXArray Dataset
+Shared Axes: 
+  (↓ points Sampled{Int64} 1:100 ForwardOrdered Regular Points)
+
+Variables: 
+latitudes, longitudes
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature

Select all points between 20ºN and 85ºN, and 0ºE to 180ºE

julia
ds_subset = ds[points = Where(p-> ds["latitudes"][p]  >= 20 && ds["latitudes"][p]  <= 80 &&
+                             ds["longitudes"][p] >= 0  && ds["longitudes"][p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

If your dataset has been read from a file with Cube it is not loaded into memory, and you have to load the latitudes and longitudes YAXArrays into memory:

julia
latitudes_yasxa  = readcubedata(ds["latitudes"])
+longitudes_yasxa = readcubedata(ds["longitudes"])
+ds_subset = ds[points = Where(p-> latitudes_yasxa[p]  >= 20 && latitudes_yasxa[p]  <= 80 &&
+                             longitudes_yasxa[p] >= 0  && longitudes_yasxa[p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

How do I apply map algebra?

Our next step is map algebra computations. This can be done effectively using the 'map' function. For example:

Multiplying cubes with only spatio-temporal dimensions

julia
julia> map((x, y) -> x * y, ds1, ds2)
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Cubes with more than 3 dimensions

julia
julia> map((x, y) -> x * y, dsfinal[Variables=At("var1")], dsfinal[Variables=At("var2")])
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

To add some complexity, we will multiply each value for π and then divided for the sum of each time step. We will use the ds1 cube for this purpose.

julia
julia> mapslices(ds1, dims=("Lon", "Lat")) do xin
+           (xin * π) ./ maximum(skipmissing(xin))
+       end
╭──────────────────────────────────────────────╮
+10×15×20 YAXArray{Union{Missing, Float64},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I use the CubeTable function?

The function "CubeTable" creates an iterable table and the result is a DataCube. It is therefore very handy for grouping data and computing statistics by class. It uses OnlineStats.jl to calculate statistics, and weighted statistics can be calculated as well.

Here we will use the ds1 Cube defined previously and we create a mask for data classification.

Cube containing a mask with classes 1, 2 and 3.

julia
julia> classes = YAXArray((getAxis("lon", dsfinal), getAxis("lat", dsfinal)), rand(1:3, 10, 15))
╭─────────────────────────╮
+10×15 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
using GLMakie
+GLMakie.activate!()
+# This is how our classification map looks like
+fig, ax, obj = heatmap(classes;
+    colormap=Makie.Categorical(cgrad([:grey15, :orangered, :snow3])))
+cbar = Colorbar(fig[1,2], obj)
+fig

Now we define the input cubes that will be considered for the iterable table

julia
t = CubeTable(values=ds1, classes=classes)
Datacube iterator with 1 subtables with fields: (:values, :classes, :time, :lon, :lat)
julia
using DataFrames
+using OnlineStats
+## visualization of the CubeTable
+c_tbl = DataFrame(t[1])
+first(c_tbl, 5)

In this line we calculate the Mean for each class

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes))
╭───────────────────────────────────────────────╮
+3-element YAXArray{Union{Missing, Float64},1}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 24.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

We can also use more than one criteria for grouping the values. In the next example, the mean is calculated for each class and timestep.

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes, :time))
╭──────────────────────────────────────────╮
+3×20 YAXArray{Union{Missing, Float64},2}
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points,
+time    Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 480.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I assign variable names to YAXArrays in a Dataset

One variable name

julia
julia> ds = YAXArrays.Dataset(; (:a => YAXArray(rand(10)),)...)
YAXArray Dataset
+Shared Axes:
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+a

Multiple variable names

julia
keylist = (:a, :b, :c)
+varlist = (YAXArray(rand(10)), YAXArray(rand(10,5)), YAXArray(rand(2,5)))
julia
julia> ds = YAXArrays.Dataset(; (keylist .=> varlist)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+  Variables: 
+  a
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  b
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  c

Ho do I construct a Dataset from a TimeArray

In this section we will use MarketData.jl and TimeSeries.jl to simulate some stocks.

julia
using YAXArrays, DimensionalData
+using MarketData, TimeSeries
+
+stocks = Dict(:Stock1 => random_ohlcv(), :Stock2 => random_ohlcv(), :Stock3 => random_ohlcv())
+d_keys = keys(stocks)
KeySet for a Dict{Symbol, TimeSeries.TimeArray{Float64, 2, DateTime, Matrix{Float64}}} with 3 entries. Keys:
+  :Stock3
+  :Stock1
+  :Stock2

currently there is not direct support to obtain dims from a TimeArray, but can build a function for it

julia
getTArrayAxes(ta::TimeArray) = (Dim{:time}(timestamp(ta)), Dim{:variable}(colnames(ta)), );

then, we create the YAXArrays as

julia
yax_list = [YAXArray(getTArrayAxes(stocks[k]), values(stocks[k])) for k in d_keys];

and a Dataset with all stocks names

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock2
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock1
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock3

and it looks like there some small differences in the axes, they are being printed independently although they should be the same. Well, they are at least at the == level but not at ===. We could use the axes from one YAXArray as reference and rebuild all the others

julia
yax_list = [rebuild(yax_list[1], values(stocks[k])) for k in d_keys];

and voilà

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+
+Variables: 
+Stock1, Stock2, Stock3

now they are printed together, showing that is exactly the same axis structure for all variables.

`,141)]))}const E=i(l,[["render",h]]);export{o as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.lean.js b/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.lean.js new file mode 100644 index 00000000..5f316555 --- /dev/null +++ b/previews/PR437/assets/UserGuide_faq.md.BqoiJUSy.lean.js @@ -0,0 +1,359 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const t="/YAXArrays.jl/previews/PR437/assets/zxfqnjz.DMLwX5kL.jpeg",o=JSON.parse('{"title":"Frequently Asked Questions (FAQ)","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/faq.md","filePath":"UserGuide/faq.md","lastUpdated":null}'),l={name:"UserGuide/faq.md"};function h(p,s,k,d,r,g){return e(),a("div",null,s[0]||(s[0]=[n(`

Frequently Asked Questions (FAQ)

The purpose of this section is to do a collection of small convinient pieces of code on how to do simple things.

Extract the axes names from a Cube

julia
using YAXArrays
+using DimensionalData
julia
julia> c = YAXArray(rand(10, 10, 5))
╭─────────────────────────────╮
+10×10×5 YAXArray{Float64,3}
+├─────────────────────────────┴────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 3.91 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> caxes(c) # former way of doing it
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

WARNING

To get the axes of a YAXArray use the dims function instead of the caxes function

julia
julia> dims(c)
(Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)

INFO

Also, use DD.rebuild(c, values) to copy axes from c and build a new cube but with different values.

rebuild

As an example let's consider the following

julia
using YAXArrays
+using DimensionalData
+
+c = YAXArray(ones(Int, 10,10))
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────┘

then creating a new c with the same structure (axes) but different values is done by

julia
julia> new_c = rebuild(c, rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

note that the type is now Float64. Or, we could create a new structure but using the dimensions from yax explicitly

julia
julia> c_c = YAXArray(dims(c), rand(10,10))
╭───────────────────────────╮
+10×10 YAXArray{Float64,2}
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

which achieves the same goal as rebuild.

Obtain values from axes and data from the cube

There are two options to collect values from axes. In this examples the axis ranges from 1 to 10.

These two examples bring the same result

julia
collect(getAxis("Dim_1", c).val)
+collect(c.axes[1].val)
10-element Vector{Int64}:
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10

to collect data from a cube works exactly the same as doing it from an array

julia
julia> c[:, :, 1]
╭─────────────────────────╮
+10×10 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+Dim_1 Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I concatenate cubes

It is possible to concatenate several cubes that shared the same dimensions using the [concatenatecubes]@ref function.

Let's create two dummy cubes

julia
using YAXArrays
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    Dim{:lon}(range(1, 10, length=10)),
+    Dim{:lat}(range(1, 5, length=15))
+    )
+
+data1 = rand(20, 10, 15)
+ds1 = YAXArray(axlist, data1)
+
+data2 = rand(20, 10, 15)
+ds2 = YAXArray(axlist, data2)

Now we can concatenate ds1 and ds2:

julia
julia> dsfinal = concatenatecubes([ds1, ds2], Dim{:Variables}(["var1", "var2"]))
╭────────────────────────────────╮
+20×10×15×2 YAXArray{Float64,4}
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+time      Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon       Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat       Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+Variables Categorical{String} ["var1", "var2"] ForwardOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I subset a YAXArray ( Cube ) or Dataset?

These are the three main datatypes provided by the YAXArrays libray. You can find a description of them here. A Cube is no more than a YAXArray, so, we will not explicitly tell about a Cube.

Subsetting a YAXArray

Let's start by creating a dummy YAXArray.

Firstly, load the required libraries

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data, however the intervals notation should be used instead, i.e. \`a .. b\`.

Define the time span of the YAXArray

julia
t = Date("2020-01-01"):Month(1):Date("2022-12-31")
Date("2020-01-01"):Dates.Month(1):Date("2022-12-01")

create YAXArray axes

julia
axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
(↓ Lon  1:10,
+→ Lat  1:10,
+↗ Time Date("2020-01-01"):Dates.Month(1):Date("2022-12-01"))

create the YAXArray

julia
y = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
╭────────────────────────────╮
+│ 10×10×36 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 28.12 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Now we subset the YAXArray by any dimension.

Subset YAXArray by years

julia
ytime = y[Time=Between(Date(2021,1,1), Date(2021,12,31))]
╭────────────────────────────╮
+│ 10×10×12 YAXArray{Int64,3} │
+├────────────────────────────┴─────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-01-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by a specific date

julia
ytime2 = y[Time=At(Date("2021-05-01"))]
╭─────────────────────────╮
+│ 10×10 YAXArray{Int64,2} │
+├─────────────────────────┴────────────────────────── dims ┐
+  ↓ Lon Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat Sampled{Int64} 1:10 ForwardOrdered Regular Points
+├──────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────── file size ┤ 
+  file size: 800.0 bytes
+└──────────────────────────────────────────────────────────┘

Subset YAXArray by a date range

julia
ytime3 = y[Time=Date("2021-05-01") .. Date("2021-12-01")]
╭───────────────────────────╮
+│ 10×10×8 YAXArray{Int64,3} │
+├───────────────────────────┴──────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2021-05-01"):Dates.Month(1):Date("2021-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 6.25 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subset YAXArray by longitude and latitude

julia
ylonlat = y[Lon=1 .. 5, Lat=5 .. 10]
╭──────────────────────────╮
+│ 5×6×36 YAXArray{Int64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 8.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Subsetting a Dataset

In a dataset, we can have several variables (YAXArrays) that share some or all of their dimensions.

Subsetting a Dataset whose variables share all their dimensions

This works for YAXArrays. Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" option for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+axes = (Dim{:Lon}(1:10), Dim{:Lat}(1:10), Dim{:Time}(t))
+
+var1 = YAXArray(axes, reshape(1:3600, (10, 10, 36)))
+var2 = YAXArray(axes, reshape((1:3600)*5, (10, 10, 36)))
+
+ds = Dataset(; var1=var1, var2=var2)
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 1:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2
julia
ds_lonlat = ds[Lon=1 .. 5, Lat=5 .. 10]
YAXArray Dataset
+Shared Axes: 
+  (↓ Lon  Sampled{Int64} 1:5 ForwardOrdered Regular Points,
+  → Lat  Sampled{Int64} 5:10 ForwardOrdered Regular Points,
+  ↗ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+
+Variables: 
+var1, var2

Subsetting a Dataset whose variables share some but not all of their dimensions

In this case, if we subset by the common dimension/s, this works the same as for YAXArrays, Cubes, and datasets that share all their dimensions.

But we can also subset a variable by the values of another variable with which it shares some dimensions.

Warning

If your data is not loaded into memory, the selection will be too slow. So, you have load into memory, at least, the variable with which you make the selection.

Let's make an example.

julia
using YAXArrays
+using Dates # To generate the dates of the time axis
+using DimensionalData # To use the "Between" selector for selecting data
+
+t = Date("2020-01-01"):Month(1):Date("2022-12-31")
+common_axis = Dim{:points}(1:100)
+time_axis =   Dim{:Time}(t)
+
+# Note that longitudes and latitudes are not dimensions, but YAXArrays
+longitudes = YAXArray((common_axis,), rand(1:369, 100)) # 100 random values taken from 1 to 359
+latitudes  = YAXArray((common_axis,), rand(0:90, 100))  # 100 random values taken from 0 to 90
+temperature = YAXArray((common_axis, time_axis), rand(-40:40, (100, 36)))
+
+ds = Dataset(; longitudes=longitudes, latitudes=latitudes, temperature=temperature)
YAXArray Dataset
+Shared Axes: 
+  (↓ points Sampled{Int64} 1:100 ForwardOrdered Regular Points)
+
+Variables: 
+latitudes, longitudes
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ Time Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature

Select all points between 20ºN and 85ºN, and 0ºE to 180ºE

julia
ds_subset = ds[points = Where(p-> ds["latitudes"][p]  >= 20 && ds["latitudes"][p]  <= 80 &&
+                             ds["longitudes"][p] >= 0  && ds["longitudes"][p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

If your dataset has been read from a file with Cube it is not loaded into memory, and you have to load the latitudes and longitudes YAXArrays into memory:

julia
latitudes_yasxa  = readcubedata(ds["latitudes"])
+longitudes_yasxa = readcubedata(ds["longitudes"])
+ds_subset = ds[points = Where(p-> latitudes_yasxa[p]  >= 20 && latitudes_yasxa[p]  <= 80 &&
+                             longitudes_yasxa[p] >= 0  && longitudes_yasxa[p] <= 180
+                             ) # Where
+              ] # ds
YAXArray Dataset
+Shared Axes: 
+None
+Variables with additional axes:
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points,
+  → Time   Sampled{Date} Date("2020-01-01"):Dates.Month(1):Date("2022-12-01") ForwardOrdered Regular Points)
+  Variables: 
+  temperature
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  latitudes
+
+  Additional Axes: 
+  (↓ points Sampled{Int64} [4, 6, …, 94, 96] ForwardOrdered Irregular Points)
+  Variables: 
+  longitudes

How do I apply map algebra?

Our next step is map algebra computations. This can be done effectively using the 'map' function. For example:

Multiplying cubes with only spatio-temporal dimensions

julia
julia> map((x, y) -> x * y, ds1, ds2)
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Cubes with more than 3 dimensions

julia
julia> map((x, y) -> x * y, dsfinal[Variables=At("var1")], dsfinal[Variables=At("var2")])
╭──────────────────────────────╮
+20×10×15 YAXArray{Float64,3}
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

To add some complexity, we will multiply each value for π and then divided for the sum of each time step. We will use the ds1 cube for this purpose.

julia
julia> mapslices(ds1, dims=("Lon", "Lat")) do xin
+           (xin * π) ./ maximum(skipmissing(xin))
+       end
╭──────────────────────────────────────────────╮
+10×15×20 YAXArray{Union{Missing, Float64},3}
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+lon  Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat  Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+time Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 23.44 KB
+└──────────────────────────────────────────────────────────────────────────────┘

How do I use the CubeTable function?

The function "CubeTable" creates an iterable table and the result is a DataCube. It is therefore very handy for grouping data and computing statistics by class. It uses OnlineStats.jl to calculate statistics, and weighted statistics can be calculated as well.

Here we will use the ds1 Cube defined previously and we create a mask for data classification.

Cube containing a mask with classes 1, 2 and 3.

julia
julia> classes = YAXArray((getAxis("lon", dsfinal), getAxis("lat", dsfinal)), rand(1:3, 10, 15))
╭─────────────────────────╮
+10×15 YAXArray{Int64,2}
+├─────────────────────────┴────────────────────────────────────────────── dims ┐
+lon Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 1.17 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
using GLMakie
+GLMakie.activate!()
+# This is how our classification map looks like
+fig, ax, obj = heatmap(classes;
+    colormap=Makie.Categorical(cgrad([:grey15, :orangered, :snow3])))
+cbar = Colorbar(fig[1,2], obj)
+fig

Now we define the input cubes that will be considered for the iterable table

julia
t = CubeTable(values=ds1, classes=classes)
Datacube iterator with 1 subtables with fields: (:values, :classes, :time, :lon, :lat)
julia
using DataFrames
+using OnlineStats
+## visualization of the CubeTable
+c_tbl = DataFrame(t[1])
+first(c_tbl, 5)

In this line we calculate the Mean for each class

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes))
╭───────────────────────────────────────────────╮
+3-element YAXArray{Union{Missing, Float64},1}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 24.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

We can also use more than one criteria for grouping the values. In the next example, the mean is calculated for each class and timestep.

julia
julia> fitcube = cubefittable(t, Mean, :values, by=(:classes, :time))
╭──────────────────────────────────────────╮
+3×20 YAXArray{Union{Missing, Float64},2}
+├──────────────────────────────────────────┴───────────────────────────── dims ┐
+classes Sampled{Int64} [1, 2, 3] ForwardOrdered Irregular Points,
+time    Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 480.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

How do I assign variable names to YAXArrays in a Dataset

One variable name

julia
julia> ds = YAXArrays.Dataset(; (:a => YAXArray(rand(10)),)...)
YAXArray Dataset
+Shared Axes:
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+
+Variables: 
+a

Multiple variable names

julia
keylist = (:a, :b, :c)
+varlist = (YAXArray(rand(10)), YAXArray(rand(10,5)), YAXArray(rand(2,5)))
julia
julia> ds = YAXArrays.Dataset(; (keylist .=> varlist)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points)
+  Variables: 
+  a
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(10) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  b
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+  Variables: 
+  c

Ho do I construct a Dataset from a TimeArray

In this section we will use MarketData.jl and TimeSeries.jl to simulate some stocks.

julia
using YAXArrays, DimensionalData
+using MarketData, TimeSeries
+
+stocks = Dict(:Stock1 => random_ohlcv(), :Stock2 => random_ohlcv(), :Stock3 => random_ohlcv())
+d_keys = keys(stocks)
KeySet for a Dict{Symbol, TimeSeries.TimeArray{Float64, 2, DateTime, Matrix{Float64}}} with 3 entries. Keys:
+  :Stock3
+  :Stock1
+  :Stock2

currently there is not direct support to obtain dims from a TimeArray, but can build a function for it

julia
getTArrayAxes(ta::TimeArray) = (Dim{:time}(timestamp(ta)), Dim{:variable}(colnames(ta)), );

then, we create the YAXArrays as

julia
yax_list = [YAXArray(getTArrayAxes(stocks[k]), values(stocks[k])) for k in d_keys];

and a Dataset with all stocks names

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock2
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock1
+
+  Additional Axes: 
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+  Variables: 
+  Stock3

and it looks like there some small differences in the axes, they are being printed independently although they should be the same. Well, they are at least at the == level but not at ===. We could use the axes from one YAXArray as reference and rebuild all the others

julia
yax_list = [rebuild(yax_list[1], values(stocks[k])) for k in d_keys];

and voilà

julia
julia> ds = Dataset(; (d_keys .=> yax_list)...)
YAXArray Dataset
+Shared Axes:
+  (time     Sampled{DateTime} [2020-01-01T00:00:00, …, 2020-01-21T19:00:00] ForwardOrdered Irregular Points,
+variable Categorical{Symbol} [:Open, :High, :Low, :Close, :Volume] Unordered)
+
+Variables: 
+Stock1, Stock2, Stock3

now they are printed together, showing that is exactly the same axis structure for all variables.

`,141)]))}const E=i(l,[["render",h]]);export{o as __pageData,E as default}; diff --git a/previews/PR437/assets/UserGuide_group.md.BbGChzju.js b/previews/PR437/assets/UserGuide_group.md.BbGChzju.js new file mode 100644 index 00000000..a13fc6df --- /dev/null +++ b/previews/PR437/assets/UserGuide_group.md.BbGChzju.js @@ -0,0 +1,190 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const h="/YAXArrays.jl/previews/PR437/assets/okmnbox.CBBZcGwj.png",y=JSON.parse('{"title":"Group YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/group.md","filePath":"UserGuide/group.md","lastUpdated":null}'),t={name:"UserGuide/group.md"};function l(p,s,k,d,r,g){return e(),a("div",null,s[0]||(s[0]=[n(`

Group YAXArrays and Datasets

The following examples will use the groupby function to calculate temporal and spatial averages.

julia
using YAXArrays, DimensionalData
+using NetCDF
+using Downloads
+using Dates
+using Statistics

Seasonal Averages from Time Series of Monthly Means

The following reproduces the example in xarray by Joe Hamman.

Where the goal is to calculate the seasonal average. And in order to do this properly, is necessary to calculate the weighted average considering that each month has a different number of days.

Download the data

julia
url_path = "https://github.com/pydata/xarray-data/raw/master/rasm.nc"
+filename = Downloads.download(url_path, "rasm.nc")
+ds_o = Cube(filename)

WARNING

The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Out of memory groupby currently is work in progress. Related to https://github.com/rafaqz/DimensionalData.jl/issues/642

julia
axs = dims(ds_o) # get the dimensions
+data = ds_o.data[:,:,:] # read the data
+_FillValue = ds_o.properties["_FillValue"]
+data = replace(data, _FillValue => NaN)
+# create new YAXArray
+ds = YAXArray(axs, data)

GroupBy: seasons

function weighted_seasons(ds) ... end
julia
function weighted_seasons(ds)
+    # calculate weights 
+    tempo = dims(ds, :Ti)
+    month_length = YAXArray((tempo,), daysinmonth.(tempo))
+    g_tempo = groupby(month_length, Ti => seasons(; start=December))
+    sum_days = sum.(g_tempo, dims=:Ti)
+    weights = map(./, g_tempo, sum_days)
+    # unweighted seasons
+    g_ds = groupby(ds, Ti => seasons(; start=December))
+    mean_g = mean.(g_ds, dims=:Ti)
+    mean_g = dropdims.(mean_g, dims=:Ti)
+    # weighted seasons
+    g_dsW = broadcast_dims.(*, weights, g_ds)
+    weighted_g = sum.(g_dsW, dims = :Ti);
+    weighted_g = dropdims.(weighted_g, dims=:Ti)
+    # differences
+    diff_g = map(.-, weighted_g, mean_g)
+    seasons_g = lookup(mean_g, :Ti)
+    return mean_g, weighted_g, diff_g, seasons_g
+end

Now, we continue with the groupby operations as usual

julia
julia> g_ds = groupby(ds, Ti => seasons(; start=December))
╭──────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Float64,2},1}
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+x, y, Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  275×205×9 YAXArray
+ :Mar_Apr_May  275×205×9 YAXArray
+ :Jun_Jul_Aug  275×205×9 YAXArray
+ :Sep_Oct_Nov  275×205×9 YAXArray

And the mean per season is calculated as follows

julia
julia> mean_g = mean.(g_ds, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843;;;]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762;;;]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537;;;]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404;;;]

dropdims

Note that now the time dimension has length one, we can use dropdims to remove it

julia
julia> mean_g = dropdims.(mean_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404]

seasons

Due to the groupby function we will obtain new grouping names, in this case in the time dimension:

julia
seasons_g = lookup(mean_g, :Ti)
Categorical{Symbol} Unordered
+wrapping: 4-element Vector{Symbol}:
+ :Dec_Jan_Feb
+ :Mar_Apr_May
+ :Jun_Jul_Aug
+ :Sep_Oct_Nov

Next, we will weight this grouping by days/month in each group.

GroupBy: weight

Create a YAXArray for the month length

julia
tempo = dims(ds, :Ti)
+month_length = YAXArray((tempo,), daysinmonth.(tempo))
╭──────────────────────────────╮
+│ 36-element YAXArray{Int64,1} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(1980-09-16T12:00:00), …, CFTime.DateTimeNoLeap(1983-08-17T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 288.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now group it by season

julia
julia> g_tempo = groupby(month_length, Ti => seasons(; start=December))
╭────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Int64,0},1}
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  9-element YAXArray
+ :Mar_Apr_May  9-element YAXArray
+ :Jun_Jul_Aug  9-element YAXArray
+ :Sep_Oct_Nov  9-element YAXArray

Get the number of days per season

julia
julia> sum_days = sum.(g_tempo, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Int64, 1, Vector{Int64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  [270]
+ :Mar_Apr_May  [276]
+ :Jun_Jul_Aug  [276]
+ :Sep_Oct_Nov  [273]

weights

Weight the seasonal groups by sum_days

julia
julia> weights = map(./, g_tempo, sum_days)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 1, Vector{Float64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1} groupby
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704]
+ :Mar_Apr_May     [0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319]
+ :Jun_Jul_Aug     [0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319]
+ :Sep_Oct_Nov     [0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989]

Verify that the sum per season is 1

julia
julia> sum.(weights)
╭───────────────────────────────╮
+4-element DimArray{Float64,1}
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  1.0
+ :Mar_Apr_May  1.0
+ :Jun_Jul_Aug  1.0
+ :Sep_Oct_Nov  1.0

weighted seasons

Now, let's weight the seasons

julia
julia> g_dsW = broadcast_dims.(*, weights, g_ds)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.32149 1.33565; NaN NaN … 1.29564 1.32555; … ; NaN NaN … 1.3188 1.3169; NaN NaN … 1.17863 1.18434;;; NaN NaN … 1.29816 1.34218; NaN NaN … 1.30113 1.35483; … ; NaN NaN … 1.30142 1.31753; NaN NaN … 1.16258 1.17647;;; NaN NaN … 1.34549 1.37878; NaN NaN … 1.36836 1.41634; … ; NaN NaN … 1.34832 1.38364; NaN NaN … 1.17852 1.16713]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.87705 1.90365; NaN NaN … 2.30018 2.35432; … ; NaN NaN … 2.41049 2.43254; NaN NaN … 2.65105 2.69085;;; NaN NaN … 1.86457 1.90712; NaN NaN … 2.2894 2.34818; … ; NaN NaN … 2.3866 2.41241; NaN NaN … 2.61197 2.64976;;; NaN NaN … 1.89237 1.8984; NaN NaN … 2.29473 2.312; … ; NaN NaN … 2.36142 2.36126; NaN NaN … 2.56632 2.59085]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 3.21209 3.25153; NaN NaN … 3.23 3.28008; … ; NaN NaN … 3.12575 3.15532; NaN NaN … 3.2434 3.26274;;; NaN NaN … 3.17434 3.21699; NaN NaN … 3.18892 3.24375; … ; NaN NaN … 3.06755 3.1083; NaN NaN … 3.19241 3.22211;;; NaN NaN … 3.1437 3.15644; NaN NaN … 3.16631 3.18583; … ; NaN NaN … 3.03361 3.05846; NaN NaN … 3.16581 3.16824]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 2.97047 3.00388; NaN NaN … 2.77587 2.80759; … ; NaN NaN … 2.60175 2.60918; NaN NaN … 1.4947 1.52419;;; NaN NaN … 2.94534 2.97649; NaN NaN … 2.75891 2.79502; … ; NaN NaN … 2.57695 2.59212; NaN NaN … 1.46506 1.49909;;; NaN NaN … 2.9192 2.93743; NaN NaN … 2.7593 2.77687; … ; NaN NaN … 2.57873 2.63006; NaN NaN … 1.48367 1.50089]

apply a sum over the time dimension and drop it

julia
julia> weighted_g = sum.(g_dsW, dims = :Ti);
+
+julia> weighted_g = dropdims.(weighted_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1181 11.372; NaN NaN … 11.3069 11.5743]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1242 21.0057; NaN NaN … 21.4198 21.1644]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2747 27.9362; NaN NaN … 28.6122 28.0465]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.73 21.7341; NaN NaN … 21.986 21.959]

Calculate the differences

julia
julia> diff_g = map(.-, weighted_g, mean_g)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.019016 -0.0115514; NaN NaN … -0.0183003 -0.00990356]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.0121037 -0.0123091; NaN NaN … -0.0127077 -0.0117519]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.00709111 -0.00693713; NaN NaN … -0.00684233 -0.00722034]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 0.0180572 0.0182373; NaN NaN … 0.0178074 0.018571]

All the previous steps are equivalent to calling the function defined at the top:

julia
mean_g, weighted_g, diff_g, seasons_g = weighted_seasons(ds)

Once all calculations are done we can plot the results with Makie.jl as follows:

julia
using CairoMakie
+# define plot arguments/attributes
+colorrange = (-30,30)
+colormap = Reverse(:Spectral)
+highclip = :red
+lowclip = :grey15
+cb_label =  ds_o.properties["long_name"]
"Surface air temperature"
julia
with_theme(theme_ggplot2()) do
+    hm_o, hm_d, hm_w = nothing, nothing, nothing
+    # the figure
+    fig = Figure(; size = (850,500))
+    axs = [Axis(fig[i,j], aspect=DataAspect()) for i in 1:3, j in 1:4]
+    for (j, s) in enumerate(seasons_g)
+        hm_o = heatmap!(axs[1,j], mean_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_w = heatmap!(axs[2,j], weighted_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_d = heatmap!(axs[3,j], diff_g[Ti=At(s)]; colorrange=(-0.1,0.1), lowclip, highclip,
+            colormap=:diverging_bwr_20_95_c54_n256)
+    end
+    Colorbar(fig[1:2,5], hm_o, label=cb_label)
+    Colorbar(fig[3,5], hm_d, label="Tair")
+    hidedecorations!.(axs, grid=false, ticks=false, label=false)
+    # some labels
+    [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons_g)]
+    Label(fig[0,1:5], "Seasonal Surface Air Temperature", fontsize=18, font=:bold)
+    axs[1,1].ylabel = "Unweighted"
+    axs[2,1].ylabel = "Weighted"
+    axs[3,1].ylabel = "Difference"
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    fig
+end

which shows a good agreement with the results first published by Joe Hamman.

',62)]))}const N=i(t,[["render",l]]);export{y as __pageData,N as default}; diff --git a/previews/PR437/assets/UserGuide_group.md.BbGChzju.lean.js b/previews/PR437/assets/UserGuide_group.md.BbGChzju.lean.js new file mode 100644 index 00000000..a13fc6df --- /dev/null +++ b/previews/PR437/assets/UserGuide_group.md.BbGChzju.lean.js @@ -0,0 +1,190 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.BxolPc_T.js";const h="/YAXArrays.jl/previews/PR437/assets/okmnbox.CBBZcGwj.png",y=JSON.parse('{"title":"Group YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/group.md","filePath":"UserGuide/group.md","lastUpdated":null}'),t={name:"UserGuide/group.md"};function l(p,s,k,d,r,g){return e(),a("div",null,s[0]||(s[0]=[n(`

Group YAXArrays and Datasets

The following examples will use the groupby function to calculate temporal and spatial averages.

julia
using YAXArrays, DimensionalData
+using NetCDF
+using Downloads
+using Dates
+using Statistics

Seasonal Averages from Time Series of Monthly Means

The following reproduces the example in xarray by Joe Hamman.

Where the goal is to calculate the seasonal average. And in order to do this properly, is necessary to calculate the weighted average considering that each month has a different number of days.

Download the data

julia
url_path = "https://github.com/pydata/xarray-data/raw/master/rasm.nc"
+filename = Downloads.download(url_path, "rasm.nc")
+ds_o = Cube(filename)

WARNING

The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Out of memory groupby currently is work in progress. Related to https://github.com/rafaqz/DimensionalData.jl/issues/642

julia
axs = dims(ds_o) # get the dimensions
+data = ds_o.data[:,:,:] # read the data
+_FillValue = ds_o.properties["_FillValue"]
+data = replace(data, _FillValue => NaN)
+# create new YAXArray
+ds = YAXArray(axs, data)

GroupBy: seasons

function weighted_seasons(ds) ... end
julia
function weighted_seasons(ds)
+    # calculate weights 
+    tempo = dims(ds, :Ti)
+    month_length = YAXArray((tempo,), daysinmonth.(tempo))
+    g_tempo = groupby(month_length, Ti => seasons(; start=December))
+    sum_days = sum.(g_tempo, dims=:Ti)
+    weights = map(./, g_tempo, sum_days)
+    # unweighted seasons
+    g_ds = groupby(ds, Ti => seasons(; start=December))
+    mean_g = mean.(g_ds, dims=:Ti)
+    mean_g = dropdims.(mean_g, dims=:Ti)
+    # weighted seasons
+    g_dsW = broadcast_dims.(*, weights, g_ds)
+    weighted_g = sum.(g_dsW, dims = :Ti);
+    weighted_g = dropdims.(weighted_g, dims=:Ti)
+    # differences
+    diff_g = map(.-, weighted_g, mean_g)
+    seasons_g = lookup(mean_g, :Ti)
+    return mean_g, weighted_g, diff_g, seasons_g
+end

Now, we continue with the groupby operations as usual

julia
julia> g_ds = groupby(ds, Ti => seasons(; start=December))
╭──────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Float64,2},1}
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+x, y, Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  275×205×9 YAXArray
+ :Mar_Apr_May  275×205×9 YAXArray
+ :Jun_Jul_Aug  275×205×9 YAXArray
+ :Sep_Oct_Nov  275×205×9 YAXArray

And the mean per season is calculated as follows

julia
julia> mean_g = mean.(g_ds, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843;;;]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762;;;]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537;;;]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404;;;]

dropdims

Note that now the time dimension has length one, we can use dropdims to remove it

julia
julia> mean_g = dropdims.(mean_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1372 11.3835; NaN NaN … 11.3252 11.5843]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1363 21.018; NaN NaN … 21.4325 21.1762]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2818 27.9432; NaN NaN … 28.619 28.0537]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.7119 21.7158; NaN NaN … 21.9682 21.9404]

seasons

Due to the groupby function we will obtain new grouping names, in this case in the time dimension:

julia
seasons_g = lookup(mean_g, :Ti)
Categorical{Symbol} Unordered
+wrapping: 4-element Vector{Symbol}:
+ :Dec_Jan_Feb
+ :Mar_Apr_May
+ :Jun_Jul_Aug
+ :Sep_Oct_Nov

Next, we will weight this grouping by days/month in each group.

GroupBy: weight

Create a YAXArray for the month length

julia
tempo = dims(ds, :Ti)
+month_length = YAXArray((tempo,), daysinmonth.(tempo))
╭──────────────────────────────╮
+│ 36-element YAXArray{Int64,1} │
+├──────────────────────────────┴───────────────────────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTimeNoLeap} [CFTime.DateTimeNoLeap(1980-09-16T12:00:00), …, CFTime.DateTimeNoLeap(1983-08-17T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 288.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now group it by season

julia
julia> g_tempo = groupby(month_length, Ti => seasons(; start=December))
╭────────────────────────────────────────────────╮
+4-element DimGroupByArray{YAXArray{Int64,0},1}
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+├────────────────────────────────────────────────────────────────── group dims ┤
+Ti
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  9-element YAXArray
+ :Mar_Apr_May  9-element YAXArray
+ :Jun_Jul_Aug  9-element YAXArray
+ :Sep_Oct_Nov  9-element YAXArray

Get the number of days per season

julia
julia> sum_days = sum.(g_tempo, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Int64, 1, Vector{Int64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, Vector{CFTime.DateTimeNoLeap}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  [270]
+ :Mar_Apr_May  [276]
+ :Jun_Jul_Aug  [276]
+ :Sep_Oct_Nov  [273]

weights

Weight the seasonal groups by sum_days

julia
julia> weights = map(./, g_tempo, sum_days)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 1, Vector{Float64}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Dict{String, Any}},1} groupby
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704, 0.114815, 0.114815, 0.103704]
+ :Mar_Apr_May     [0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319]
+ :Jun_Jul_Aug     [0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319, 0.108696, 0.112319, 0.112319]
+ :Sep_Oct_Nov     [0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989, 0.10989, 0.113553, 0.10989]

Verify that the sum per season is 1

julia
julia> sum.(weights)
╭───────────────────────────────╮
+4-element DimArray{Float64,1}
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  1.0
+ :Mar_Apr_May  1.0
+ :Jun_Jul_Aug  1.0
+ :Sep_Oct_Nov  1.0

weighted seasons

Now, let's weight the seasons

julia
julia> g_dsW = broadcast_dims.(*, weights, g_ds)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 3, Array{Float64, 3}, Tuple{DimensionalData.Dimensions.Ti{DimensionalData.Dimensions.Lookups.Sampled{CFTime.DateTimeNoLeap, SubArray{CFTime.DateTimeNoLeap, 1, Vector{CFTime.DateTimeNoLeap}, Tuple{Vector{Int64}}, false}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Irregular{Tuple{CFTime.DateTimeNoLeap, CFTime.DateTimeNoLeap}}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.32149 1.33565; NaN NaN … 1.29564 1.32555; … ; NaN NaN … 1.3188 1.3169; NaN NaN … 1.17863 1.18434;;; NaN NaN … 1.29816 1.34218; NaN NaN … 1.30113 1.35483; … ; NaN NaN … 1.30142 1.31753; NaN NaN … 1.16258 1.17647;;; NaN NaN … 1.34549 1.37878; NaN NaN … 1.36836 1.41634; … ; NaN NaN … 1.34832 1.38364; NaN NaN … 1.17852 1.16713]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 1.87705 1.90365; NaN NaN … 2.30018 2.35432; … ; NaN NaN … 2.41049 2.43254; NaN NaN … 2.65105 2.69085;;; NaN NaN … 1.86457 1.90712; NaN NaN … 2.2894 2.34818; … ; NaN NaN … 2.3866 2.41241; NaN NaN … 2.61197 2.64976;;; NaN NaN … 1.89237 1.8984; NaN NaN … 2.29473 2.312; … ; NaN NaN … 2.36142 2.36126; NaN NaN … 2.56632 2.59085]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 3.21209 3.25153; NaN NaN … 3.23 3.28008; … ; NaN NaN … 3.12575 3.15532; NaN NaN … 3.2434 3.26274;;; NaN NaN … 3.17434 3.21699; NaN NaN … 3.18892 3.24375; … ; NaN NaN … 3.06755 3.1083; NaN NaN … 3.19241 3.22211;;; NaN NaN … 3.1437 3.15644; NaN NaN … 3.16631 3.18583; … ; NaN NaN … 3.03361 3.05846; NaN NaN … 3.16581 3.16824]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN;;; … ;;; NaN NaN … 2.97047 3.00388; NaN NaN … 2.77587 2.80759; … ; NaN NaN … 2.60175 2.60918; NaN NaN … 1.4947 1.52419;;; NaN NaN … 2.94534 2.97649; NaN NaN … 2.75891 2.79502; … ; NaN NaN … 2.57695 2.59212; NaN NaN … 1.46506 1.49909;;; NaN NaN … 2.9192 2.93743; NaN NaN … 2.7593 2.77687; … ; NaN NaN … 2.57873 2.63006; NaN NaN … 1.48367 1.50089]

apply a sum over the time dimension and drop it

julia
julia> weighted_g = sum.(g_dsW, dims = :Ti);
+
+julia> weighted_g = dropdims.(weighted_g, dims=:Ti)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 11.1181 11.372; NaN NaN … 11.3069 11.5743]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.1242 21.0057; NaN NaN … 21.4198 21.1644]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 28.2747 27.9362; NaN NaN … 28.6122 28.0465]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 21.73 21.7341; NaN NaN … 21.986 21.959]

Calculate the differences

julia
julia> diff_g = map(.-, weighted_g, mean_g)
╭──────────────────────────────────────────────────────────────────────────────╮
+4-element DimArray{YAXArray{Float64, 2, Matrix{Float64}, Tuple{Dim{:x, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}, Dim{:y, DimensionalData.Dimensions.Lookups.Sampled{Int64, UnitRange{Int64}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Int64}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, DimensionalData.Dimensions.Lookups.NoMetadata},1}
+├──────────────────────────────────────────────────────────────────────── dims ┤
+Ti Categorical{Symbol} [:Dec_Jan_Feb, :Mar_Apr_May, :Jun_Jul_Aug, :Sep_Oct_Nov] Unordered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{Symbol, Any} with 1 entry:
+  :groupby => :Ti=>CyclicBins(month; cycle=12, step=3, start=12)…
+└──────────────────────────────────────────────────────────────────────────────┘
+ :Dec_Jan_Feb  …  [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.019016 -0.0115514; NaN NaN … -0.0183003 -0.00990356]
+ :Mar_Apr_May     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.0121037 -0.0123091; NaN NaN … -0.0127077 -0.0117519]
+ :Jun_Jul_Aug     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … -0.00709111 -0.00693713; NaN NaN … -0.00684233 -0.00722034]
+ :Sep_Oct_Nov     [NaN NaN … NaN NaN; NaN NaN … NaN NaN; … ; NaN NaN … 0.0180572 0.0182373; NaN NaN … 0.0178074 0.018571]

All the previous steps are equivalent to calling the function defined at the top:

julia
mean_g, weighted_g, diff_g, seasons_g = weighted_seasons(ds)

Once all calculations are done we can plot the results with Makie.jl as follows:

julia
using CairoMakie
+# define plot arguments/attributes
+colorrange = (-30,30)
+colormap = Reverse(:Spectral)
+highclip = :red
+lowclip = :grey15
+cb_label =  ds_o.properties["long_name"]
"Surface air temperature"
julia
with_theme(theme_ggplot2()) do
+    hm_o, hm_d, hm_w = nothing, nothing, nothing
+    # the figure
+    fig = Figure(; size = (850,500))
+    axs = [Axis(fig[i,j], aspect=DataAspect()) for i in 1:3, j in 1:4]
+    for (j, s) in enumerate(seasons_g)
+        hm_o = heatmap!(axs[1,j], mean_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_w = heatmap!(axs[2,j], weighted_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap)
+        hm_d = heatmap!(axs[3,j], diff_g[Ti=At(s)]; colorrange=(-0.1,0.1), lowclip, highclip,
+            colormap=:diverging_bwr_20_95_c54_n256)
+    end
+    Colorbar(fig[1:2,5], hm_o, label=cb_label)
+    Colorbar(fig[3,5], hm_d, label="Tair")
+    hidedecorations!.(axs, grid=false, ticks=false, label=false)
+    # some labels
+    [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons_g)]
+    Label(fig[0,1:5], "Seasonal Surface Air Temperature", fontsize=18, font=:bold)
+    axs[1,1].ylabel = "Unweighted"
+    axs[2,1].ylabel = "Weighted"
+    axs[3,1].ylabel = "Difference"
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    fig
+end

which shows a good agreement with the results first published by Joe Hamman.

',62)]))}const N=i(t,[["render",l]]);export{y as __pageData,N as default}; diff --git a/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.js b/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.js new file mode 100644 index 00000000..4f0821b8 --- /dev/null +++ b/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.js @@ -0,0 +1,79 @@ +import{_ as a,c as n,a2 as i,o as t}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Read YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/read.md","filePath":"UserGuide/read.md","lastUpdated":null}'),e={name:"UserGuide/read.md"};function p(l,s,o,r,d,h){return t(),n("div",null,s[0]||(s[0]=[i(`

Read YAXArrays and Datasets

This section describes how to read files, URLs, and directories into YAXArrays and datasets.

Read Zarr

Open a Zarr store as a Dataset:

julia
using YAXArrays
+using Zarr
+path="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
+store = zopen(path, consolidated=true)
+ds = open_dataset(store)
YAXArray Dataset
+Shared Axes: 
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)

We can set path to a URL, a local directory, or in this case to a cloud object storage path.

A zarr store may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tas
╭────────────────────────────────────╮
+│ 384×192×251288 YAXArray{Float32,3} │
+├────────────────────────────────────┴─────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"         => "K"
+  "history"       => "2019-07-21T06:26:13Z altered by CMOR: Treated scalar dime…
+  "name"          => "tas"
+  "cell_methods"  => "area: mean time: point"
+  "cell_measures" => "area: areacella"
+  "long_name"     => "Near-Surface Air Temperature"
+  "coordinates"   => "height"
+  "standard_name" => "air_temperature"
+  "_FillValue"    => 1.0f20
+  "comment"       => "near-surface (usually, 2 meter) air temperature"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 69.02 GB
+└──────────────────────────────────────────────────────────────────────────────┘

Read NetCDF

Open a NetCDF file as a Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

A NetCDF file may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Read GDAL (GeoTIFF, GeoJSON)

All GDAL compatible files can be read as a YAXArrays.Dataset after loading ArchGDAL:

julia
using YAXArrays
+using ArchGDAL
+using Downloads: download
+
+path = download("https://github.com/yeesian/ArchGDALDatasets/raw/307f8f0e584a39a050c042849004e6a2bd674f99/gdalworkshop/world.tif", "world.tif")
+# ds = open_dataset(path) # this is broken
+nothing
`,20)]))}const k=a(e,[["render",p]]);export{c as __pageData,k as default}; diff --git a/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.lean.js b/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.lean.js new file mode 100644 index 00000000..4f0821b8 --- /dev/null +++ b/previews/PR437/assets/UserGuide_read.md.cM3lYpD2.lean.js @@ -0,0 +1,79 @@ +import{_ as a,c as n,a2 as i,o as t}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Read YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/read.md","filePath":"UserGuide/read.md","lastUpdated":null}'),e={name:"UserGuide/read.md"};function p(l,s,o,r,d,h){return t(),n("div",null,s[0]||(s[0]=[i(`

Read YAXArrays and Datasets

This section describes how to read files, URLs, and directories into YAXArrays and datasets.

Read Zarr

Open a Zarr store as a Dataset:

julia
using YAXArrays
+using Zarr
+path="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
+store = zopen(path, consolidated=true)
+ds = open_dataset(store)
YAXArray Dataset
+Shared Axes: 
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)

We can set path to a URL, a local directory, or in this case to a cloud object storage path.

A zarr store may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tas
╭────────────────────────────────────╮
+│ 384×192×251288 YAXArray{Float32,3} │
+├────────────────────────────────────┴─────────────────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"         => "K"
+  "history"       => "2019-07-21T06:26:13Z altered by CMOR: Treated scalar dime…
+  "name"          => "tas"
+  "cell_methods"  => "area: mean time: point"
+  "cell_measures" => "area: areacella"
+  "long_name"     => "Near-Surface Air Temperature"
+  "coordinates"   => "height"
+  "standard_name" => "air_temperature"
+  "_FillValue"    => 1.0f20
+  "comment"       => "near-surface (usually, 2 meter) air temperature"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 69.02 GB
+└──────────────────────────────────────────────────────────────────────────────┘

Read NetCDF

Open a NetCDF file as a Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

A NetCDF file may contain multiple arrays. Individual arrays can be accessed using subsetting:

julia
ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Read GDAL (GeoTIFF, GeoJSON)

All GDAL compatible files can be read as a YAXArrays.Dataset after loading ArchGDAL:

julia
using YAXArrays
+using ArchGDAL
+using Downloads: download
+
+path = download("https://github.com/yeesian/ArchGDALDatasets/raw/307f8f0e584a39a050c042849004e6a2bd674f99/gdalworkshop/world.tif", "world.tif")
+# ds = open_dataset(path) # this is broken
+nothing
`,20)]))}const k=a(e,[["render",p]]);export{c as __pageData,k as default}; diff --git a/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.js b/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.js new file mode 100644 index 00000000..4e774873 --- /dev/null +++ b/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.js @@ -0,0 +1,294 @@ +import{_ as a,c as n,a2 as i,o as e}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Select YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/select.md","filePath":"UserGuide/select.md","lastUpdated":null}'),t={name:"UserGuide/select.md"};function p(l,s,h,o,k,d){return e(),n("div",null,s[0]||(s[0]=[i(`

Select YAXArrays and Datasets

The dimensions or axes of an YAXArray are named making it easier to subset or query certain ranges of an array. Let's open an example Dataset used to select certain elements:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Select a YAXArray

Get the sea surface temperature of the Dataset:

julia
tos = ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

which is the same as:

julia
tos = ds.cubes[:tos]
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Select elements

Using positional integer indexing:

julia
tos[lon = 1, lat = 1]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1), lat = At(-79.5)]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Using special types:

julia
using CFTime
+time1 = DateTime360Day(2001,01,16)
+tos[time = At(time1)]
╭─────────────────────────────────────────────╮
+│ 180×170 YAXArray{Union{Missing, Float32},2} │
+├─────────────────────────────────────────────┴───────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────────────────┴ metadata ┐
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├───────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 119.53 KB
+└────────────────────────────────────────────────────────────────────────────────┘

Select ranges

Here we subset an interval of a dimension using positional integer indexing.

julia
tos[lon = 1:10, lat = 1:10]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:19.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:-70.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1.0:2:19), lat = At(-79.5:1:-70.5)]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 3.0, …, 17.0, 19.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} [-79.5, -78.5, …, -71.5, -70.5] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Read more about the At selector in the package DimensionalData. Get values within a tolerances:

julia
tos[lon = At(1:10; atol = 1)]
╭───────────────────────────────────────────────╮
+│ 10×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 1.0, …, 9.0, 9.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 159.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Closed and open intervals

Although a Between(a,b) function is available in DimensionalData, is recommended to use instead the a .. b notation:

julia
tos[lon = 90 .. 180]
╭───────────────────────────────────────────────╮
+│ 45×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This describes a closed interval in which all points were included. More selectors from DimensionalData are available, such as Touches, Near, Where and Contains.

julia
using IntervalSets
julia
julia> tos[lon = OpenInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon = ClosedInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:open,:closed}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:closed,:open}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

See tutorials for use cases.

Get a dimension

Get values, .e.g., axis tick labels, of a dimension that can be used for subseting:

julia
collect(tos.lat)
170-element Vector{Float64}:
+ -79.5
+ -78.5
+ -77.5
+ -76.5
+ -75.5
+ -74.5
+ -73.5
+ -72.5
+ -71.5
+ -70.5
+
+  81.5
+  82.5
+  83.5
+  84.5
+  85.5
+  86.5
+  87.5
+  88.5
+  89.5

These values are defined as lookups in the package DimensionalData:

julia
lookup(tos, :lon)
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0

which is equivalent to:

julia
tos.lon.val
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0
`,56)]))}const g=a(t,[["render",p]]);export{u as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.lean.js b/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.lean.js new file mode 100644 index 00000000..4e774873 --- /dev/null +++ b/previews/PR437/assets/UserGuide_select.md.DH9eTP1O.lean.js @@ -0,0 +1,294 @@ +import{_ as a,c as n,a2 as i,o as e}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Select YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/select.md","filePath":"UserGuide/select.md","lastUpdated":null}'),t={name:"UserGuide/select.md"};function p(l,s,h,o,k,d){return e(),n("div",null,s[0]||(s[0]=[i(`

Select YAXArrays and Datasets

The dimensions or axes of an YAXArray are named making it easier to subset or query certain ranges of an array. Let's open an example Dataset used to select certain elements:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Select a YAXArray

Get the sea surface temperature of the Dataset:

julia
tos = ds.tos
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

which is the same as:

julia
tos = ds.cubes[:tos]
╭────────────────────────────────────────────────╮
+│ 180×170×24 YAXArray{Union{Missing, Float32},3} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 2.8 MB
+└──────────────────────────────────────────────────────────────────────────────┘

Select elements

Using positional integer indexing:

julia
tos[lon = 1, lat = 1]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1), lat = At(-79.5)]
╭────────────────────────────────────────────────╮
+│ 24-element YAXArray{Union{Missing, Float32},1} │
+├────────────────────────────────────────────────┴─────────────────────── dims ┐
+  ↓ Ti Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 96.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Using special types:

julia
using CFTime
+time1 = DateTime360Day(2001,01,16)
+tos[time = At(time1)]
╭─────────────────────────────────────────────╮
+│ 180×170 YAXArray{Union{Missing, Float32},2} │
+├─────────────────────────────────────────────┴───────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────────────────┴ metadata ┐
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├───────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 119.53 KB
+└────────────────────────────────────────────────────────────────────────────────┘

Select ranges

Here we subset an interval of a dimension using positional integer indexing.

julia
tos[lon = 1:10, lat = 1:10]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 1.0:2.0:19.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:-70.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Same but using named indexing:

julia
tos[lon = At(1.0:2:19), lat = At(-79.5:1:-70.5)]
╭──────────────────────────────────────────────╮
+│ 10×10×24 YAXArray{Union{Missing, Float32},3} │
+├──────────────────────────────────────────────┴───────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 3.0, …, 17.0, 19.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} [-79.5, -78.5, …, -71.5, -70.5] ForwardOrdered Irregular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 9.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Read more about the At selector in the package DimensionalData. Get values within a tolerances:

julia
tos[lon = At(1:10; atol = 1)]
╭───────────────────────────────────────────────╮
+│ 10×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} [1.0, 1.0, …, 9.0, 9.0] ForwardOrdered Irregular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 159.38 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Closed and open intervals

Although a Between(a,b) function is available in DimensionalData, is recommended to use instead the a .. b notation:

julia
tos[lon = 90 .. 180]
╭───────────────────────────────────────────────╮
+│ 45×170×24 YAXArray{Union{Missing, Float32},3} │
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+  ↓ lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

This describes a closed interval in which all points were included. More selectors from DimensionalData are available, such as Touches, Near, Where and Contains.

julia
using IntervalSets
julia
julia> tos[lon = OpenInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon = ClosedInterval(90, 180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:open,:closed}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘
julia
julia> tos[lon =Interval{:closed,:open}(90,180)]
╭───────────────────────────────────────────────╮
+45×170×24 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────────┴──────────────────────── dims ┐
+lon Sampled{Float64} 91.0:2.0:179.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any} with 10 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "name"           => "tos"
+  "long_name"      => "Sea Surface Temperature"
+  "original_units" => "degC"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 717.19 KB
+└──────────────────────────────────────────────────────────────────────────────┘

See tutorials for use cases.

Get a dimension

Get values, .e.g., axis tick labels, of a dimension that can be used for subseting:

julia
collect(tos.lat)
170-element Vector{Float64}:
+ -79.5
+ -78.5
+ -77.5
+ -76.5
+ -75.5
+ -74.5
+ -73.5
+ -72.5
+ -71.5
+ -70.5
+
+  81.5
+  82.5
+  83.5
+  84.5
+  85.5
+  86.5
+  87.5
+  88.5
+  89.5

These values are defined as lookups in the package DimensionalData:

julia
lookup(tos, :lon)
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0

which is equivalent to:

julia
tos.lon.val
Sampled{Float64} ForwardOrdered Regular DimensionalData.Dimensions.Lookups.Points
+wrapping: 1.0:2.0:359.0
`,56)]))}const g=a(t,[["render",p]]);export{u as __pageData,g as default}; diff --git a/previews/PR437/assets/UserGuide_types.md.CpkihWi2.js b/previews/PR437/assets/UserGuide_types.md.CpkihWi2.js new file mode 100644 index 00000000..6e42ba13 --- /dev/null +++ b/previews/PR437/assets/UserGuide_types.md.CpkihWi2.js @@ -0,0 +1 @@ +import{_ as a,c as t,a2 as r,o as s}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Types","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/types.md","filePath":"UserGuide/types.md","lastUpdated":null}'),o={name:"UserGuide/types.md"};function n(i,e,d,l,c,h){return s(),t("div",null,e[0]||(e[0]=[r('

Types

This section describes the data structures used to work with n-dimensional arrays in YAXArrays.

YAXArray

An Array stores a sequence of ordered elements of the same type usually across multiple dimensions or axes. For example, one can measure temperature across all time points of the time dimension or brightness values of a picture across X and Y dimensions. A one dimensional array is called Vector and a two dimensional array is called a Matrix. In many Machine Learning libraries, arrays are also called tensors. Arrays are designed to store dense spatial-temporal data stored in a grid, whereas a collection of sparse points is usually stored in data frames or relational databases.

A DimArray as defined by DimensionalData.jl adds names to the dimensions and their axes ticks for a given Array. These names can be used to access the data, e.g., by date instead of just by integer position.

A YAXArray is a subtype of a AbstractDimArray and adds functions to load and process the named arrays. For example, it can also handle very large arrays stored on disk that are too big to fit in memory. In addition, it provides functions for parallel computation.

Dataset

A Dataset is an ordered dictionary of YAXArrays that usually share dimensions. For example, it can bundle arrays storing temperature and precipitation that are measured at the same time points and the same locations. One also can store a picture in a Dataset with three arrays containing brightness values for red green and blue, respectively. Internally, those arrays are still separated allowing to chose different element types for each array. Analog to the (NetCDF Data Model)[https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_data_model.html], a Dataset usually represents variables belonging to the same group.

(Data) Cube

A (Data) Cube is just a YAXArray in which arrays from a dataset are combined together by introducing a new dimension containing labels of which array the corresponding element came from. Unlike a Dataset, all arrays must have the same element type to be converted into a cube. This data structure is useful when we want to use all variables at once. For example, the arrays temperature and precipitation which are measured at the same locations and dates can be combined into a single cube. A more formal definition of Data Cubes are given in Mahecha et al. 2020

Dimension

A Dimension or axis as defined by DimensionalData.jl adds tick labels, e.g., to each row or column of an array. It's name is used to access particular subsets of that array.

',12)]))}const p=a(o,[["render",n]]);export{u as __pageData,p as default}; diff --git a/previews/PR437/assets/UserGuide_types.md.CpkihWi2.lean.js b/previews/PR437/assets/UserGuide_types.md.CpkihWi2.lean.js new file mode 100644 index 00000000..6e42ba13 --- /dev/null +++ b/previews/PR437/assets/UserGuide_types.md.CpkihWi2.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,a2 as r,o as s}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Types","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/types.md","filePath":"UserGuide/types.md","lastUpdated":null}'),o={name:"UserGuide/types.md"};function n(i,e,d,l,c,h){return s(),t("div",null,e[0]||(e[0]=[r('

Types

This section describes the data structures used to work with n-dimensional arrays in YAXArrays.

YAXArray

An Array stores a sequence of ordered elements of the same type usually across multiple dimensions or axes. For example, one can measure temperature across all time points of the time dimension or brightness values of a picture across X and Y dimensions. A one dimensional array is called Vector and a two dimensional array is called a Matrix. In many Machine Learning libraries, arrays are also called tensors. Arrays are designed to store dense spatial-temporal data stored in a grid, whereas a collection of sparse points is usually stored in data frames or relational databases.

A DimArray as defined by DimensionalData.jl adds names to the dimensions and their axes ticks for a given Array. These names can be used to access the data, e.g., by date instead of just by integer position.

A YAXArray is a subtype of a AbstractDimArray and adds functions to load and process the named arrays. For example, it can also handle very large arrays stored on disk that are too big to fit in memory. In addition, it provides functions for parallel computation.

Dataset

A Dataset is an ordered dictionary of YAXArrays that usually share dimensions. For example, it can bundle arrays storing temperature and precipitation that are measured at the same time points and the same locations. One also can store a picture in a Dataset with three arrays containing brightness values for red green and blue, respectively. Internally, those arrays are still separated allowing to chose different element types for each array. Analog to the (NetCDF Data Model)[https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_data_model.html], a Dataset usually represents variables belonging to the same group.

(Data) Cube

A (Data) Cube is just a YAXArray in which arrays from a dataset are combined together by introducing a new dimension containing labels of which array the corresponding element came from. Unlike a Dataset, all arrays must have the same element type to be converted into a cube. This data structure is useful when we want to use all variables at once. For example, the arrays temperature and precipitation which are measured at the same locations and dates can be combined into a single cube. A more formal definition of Data Cubes are given in Mahecha et al. 2020

Dimension

A Dimension or axis as defined by DimensionalData.jl adds tick labels, e.g., to each row or column of an array. It's name is used to access particular subsets of that array.

',12)]))}const p=a(o,[["render",n]]);export{u as __pageData,p as default}; diff --git a/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.js b/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.js new file mode 100644 index 00000000..d140919f --- /dev/null +++ b/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.js @@ -0,0 +1,66 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Write YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/write.md","filePath":"UserGuide/write.md","lastUpdated":null}'),n={name:"UserGuide/write.md"};function l(p,s,h,k,d,r){return t(),a("div",null,s[0]||(s[0]=[e(`

Write YAXArrays and Datasets

Create an example Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Write Zarr

Save a single YAXArray to a directory:

julia
using Zarr
+savecube(ds.tos, "tos.zarr", driver=:zarr)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.zarr", driver=:zarr)

Write NetCDF

Save a single YAXArray to a directory:

julia
using NetCDF
+savecube(ds.tos, "tos.nc", driver=:netcdf)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.nc", driver=:netcdf)

Overwrite a Dataset

If a path already exists, an error will be thrown. Set overwrite=true to delete the existing dataset

julia
savedataset(ds, path="ds.zarr", driver=:zarr, overwrite=true)

DANGER

Again, setting overwrite will delete all your previous saved data.

Look at the doc string for more information

# YAXArrays.Datasets.savedatasetFunction.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


Append to a Dataset

New variables can be added to an existing dataset using the append=true keyword.

julia
ds2 = Dataset(z = YAXArray(rand(10,20,5)))
+savedataset(ds2, path="ds.zarr", backend=:zarr, append=true)
julia
julia> open_dataset("ds.zarr", driver=:zarr)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+  Variables: 
+  tos
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} 1:1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:1:20 ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} 1:1:5 ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+Properties: Dict{String, Any}("cmor_version" => 0.96, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "Conventions" => "CF-1.0", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Save Skeleton

Sometimes one merely wants to create a datacube "Skeleton" on disk and gradually fill it with data. Here we make use of FillArrays to create a YAXArray and write only the axis data and array metadata to disk, while no actual array data is copied:

julia
using YAXArrays, Zarr, FillArrays

create the Zeros array

julia
julia> a = YAXArray(Zeros(Union{Missing, Float32},  5, 4, 5))
╭───────────────────────────────────────────╮
+5×4×5 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 400.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now, save to disk with

julia
r = savecube(a, "skeleton.zarr", layername="skeleton", driver=:zarr, skeleton=true, overwrite=true)

WARNING

overwrite=true will delete your previous .zarr file before creating a new one.

Note also that if layername="skeleton" is not provided then the default name for the cube variable will be layer.

Now, we check that all the values are missing

julia
all(ismissing, r[:,:,:])
true

If using FillArrays is not possible, using the zeros function works as well, though it does allocate the array in memory.

INFO

The skeleton argument is also available for savedataset.

Using the toy array defined above we can do

julia
ds = Dataset(skeleton=a) # skeleton will the variable name
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+
+Variables: 
+skeleton
julia
ds_s = savedataset(ds, path="skeleton.zarr", driver=:zarr, skeleton=true, overwrite=true)

Update values of dataset

Now, we show how to start updating the array values. In order to do it we need to open the dataset first with writing w rights as follows:

julia
ds_open = zopen("skeleton.zarr", "w")
+ds_array = ds_open["skeleton"]
ZArray{Float32} of size 5 x 4 x 5

and then we simply update values by indexing them where necessary

julia
ds_array[:,:,1] = rand(Float32, 5, 4) # this will update values directly into disk!
5×4 Matrix{Float32}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

we can verify is this working by loading again directly from disk

julia
ds_open = open_dataset("skeleton.zarr")
+ds_array = ds_open["skeleton"]
+ds_array.data[:,:,1]
5×4 Matrix{Union{Missing, Float32}}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

indeed, those entries had been updated.

`,56)]))}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.lean.js b/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.lean.js new file mode 100644 index 00000000..d140919f --- /dev/null +++ b/previews/PR437/assets/UserGuide_write.md.CjqlGJAC.lean.js @@ -0,0 +1,66 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Write YAXArrays and Datasets","description":"","frontmatter":{},"headers":[],"relativePath":"UserGuide/write.md","filePath":"UserGuide/write.md","lastUpdated":null}'),n={name:"UserGuide/write.md"};function l(p,s,h,k,d,r){return t(),a("div",null,s[0]||(s[0]=[e(`

Write YAXArrays and Datasets

Create an example Dataset:

julia
using YAXArrays
+using NetCDF
+using Downloads: download
+
+path = download("https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc", "example.nc")
+ds = open_dataset(path)
YAXArray Dataset
+Shared Axes: 
+  (↓ lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+  → lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+  ↗ Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+
+Variables: 
+tos
+
+Properties: Dict{String, Any}("cmor_version" => 0.96f0, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "Conventions" => "CF-1.0", "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Write Zarr

Save a single YAXArray to a directory:

julia
using Zarr
+savecube(ds.tos, "tos.zarr", driver=:zarr)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.zarr", driver=:zarr)

Write NetCDF

Save a single YAXArray to a directory:

julia
using NetCDF
+savecube(ds.tos, "tos.nc", driver=:netcdf)

Save an entire Dataset to a directory:

julia
savedataset(ds, path="ds.nc", driver=:netcdf)

Overwrite a Dataset

If a path already exists, an error will be thrown. Set overwrite=true to delete the existing dataset

julia
savedataset(ds, path="ds.zarr", driver=:zarr, overwrite=true)

DANGER

Again, setting overwrite will delete all your previous saved data.

Look at the doc string for more information

# YAXArrays.Datasets.savedatasetFunction.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


Append to a Dataset

New variables can be added to an existing dataset using the append=true keyword.

julia
ds2 = Dataset(z = YAXArray(rand(10,20,5)))
+savedataset(ds2, path="ds.zarr", backend=:zarr, append=true)
julia
julia> open_dataset("ds.zarr", driver=:zarr)
YAXArray Dataset
+Shared Axes:
+None
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 1.0:2.0:359.0 ForwardOrdered Regular Points,
+lat Sampled{Float64} -79.5:1.0:89.5 ForwardOrdered Regular Points,
+Ti  Sampled{CFTime.DateTime360Day} [CFTime.DateTime360Day(2001-01-16T00:00:00), …, CFTime.DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Irregular Points)
+  Variables: 
+  tos
+
+  Additional Axes: 
+  (Dim_1 Sampled{Int64} 1:1:10 ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} 1:1:20 ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} 1:1:5 ForwardOrdered Regular Points)
+  Variables: 
+  z
+
+Properties: Dict{String, Any}("cmor_version" => 0.96, "references" => "Dufresne et al, Journal of Climate, 2015, vol XX, p 136", "realization" => 1, "contact" => "Sebastien Denvil, sebastien.denvil@ipsl.jussieu.fr", "Conventions" => "CF-1.0", "history" => "YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed  At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements", "table_id" => "Table O1 (13 November 2004)", "source" => "IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v", "title" => "IPSL  model output prepared for IPCC Fourth Assessment SRES A2 experiment", "experiment_id" => "SRES A2 experiment"…)

Save Skeleton

Sometimes one merely wants to create a datacube "Skeleton" on disk and gradually fill it with data. Here we make use of FillArrays to create a YAXArray and write only the axis data and array metadata to disk, while no actual array data is copied:

julia
using YAXArrays, Zarr, FillArrays

create the Zeros array

julia
julia> a = YAXArray(Zeros(Union{Missing, Float32},  5, 4, 5))
╭───────────────────────────────────────────╮
+5×4×5 YAXArray{Union{Missing, Float32},3}
+├───────────────────────────────────────────┴──────────────────────────── dims ┐
+Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 400.0 bytes
+└──────────────────────────────────────────────────────────────────────────────┘

Now, save to disk with

julia
r = savecube(a, "skeleton.zarr", layername="skeleton", driver=:zarr, skeleton=true, overwrite=true)

WARNING

overwrite=true will delete your previous .zarr file before creating a new one.

Note also that if layername="skeleton" is not provided then the default name for the cube variable will be layer.

Now, we check that all the values are missing

julia
all(ismissing, r[:,:,:])
true

If using FillArrays is not possible, using the zeros function works as well, though it does allocate the array in memory.

INFO

The skeleton argument is also available for savedataset.

Using the toy array defined above we can do

julia
ds = Dataset(skeleton=a) # skeleton will the variable name
YAXArray Dataset
+Shared Axes: 
+  (↓ Dim_1 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(4) ForwardOrdered Regular Points,
+  ↗ Dim_3 Sampled{Int64} Base.OneTo(5) ForwardOrdered Regular Points)
+
+Variables: 
+skeleton
julia
ds_s = savedataset(ds, path="skeleton.zarr", driver=:zarr, skeleton=true, overwrite=true)

Update values of dataset

Now, we show how to start updating the array values. In order to do it we need to open the dataset first with writing w rights as follows:

julia
ds_open = zopen("skeleton.zarr", "w")
+ds_array = ds_open["skeleton"]
ZArray{Float32} of size 5 x 4 x 5

and then we simply update values by indexing them where necessary

julia
ds_array[:,:,1] = rand(Float32, 5, 4) # this will update values directly into disk!
5×4 Matrix{Float32}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

we can verify is this working by loading again directly from disk

julia
ds_open = open_dataset("skeleton.zarr")
+ds_array = ds_open["skeleton"]
+ds_array.data[:,:,1]
5×4 Matrix{Union{Missing, Float32}}:
+ 0.623244   0.771479   0.0620288  0.359023
+ 0.877461   0.498668   0.976121   0.621891
+ 0.0951123  0.0881536  0.394272   0.948197
+ 0.976249   0.666752   0.238743   0.0641324
+ 0.266521   0.358242   0.293101   0.359363

indeed, those entries had been updated.

`,56)]))}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/previews/PR437/assets/adzshwu.B7KFIfDV.jpeg b/previews/PR437/assets/adzshwu.B7KFIfDV.jpeg new file mode 100644 index 00000000..793464fc Binary files /dev/null and b/previews/PR437/assets/adzshwu.B7KFIfDV.jpeg differ diff --git a/previews/PR437/assets/api.md.BbyteFGm.js b/previews/PR437/assets/api.md.BbyteFGm.js new file mode 100644 index 00000000..f560f549 --- /dev/null +++ b/previews/PR437/assets/api.md.BbyteFGm.js @@ -0,0 +1,13 @@ +import{_ as a,c as s,a2 as i,o as t}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"API Reference","description":"","frontmatter":{},"headers":[],"relativePath":"api.md","filePath":"api.md","lastUpdated":null}'),r={name:"api.md"};function o(l,e,d,n,p,c){return t(),s("div",null,e[0]||(e[0]=[i(`

API Reference

This section describes all available functions of this package.

Public API

# YAXArrays.getAxisMethod.
julia
getAxis(desc, c)

Given an Axis description and a cube, returns the corresponding axis of the cube. The Axis description can be:

source


# YAXArrays.CubesModule.

The functions provided by YAXArrays are supposed to work on different types of cubes. This module defines the interface for all Data types that

source


# YAXArrays.Cubes.YAXArrayType.
julia
YAXArray{T,N}

An array labelled with named axes that have values associated with them. It can wrap normal arrays or, more typically DiskArrays.

Fields

source


# YAXArrays.Cubes.caxesFunction.

Returns the axes of a Cube

source


# YAXArrays.Cubes.caxesMethod.
julia
caxes

Embeds Cube inside a new Cube

source


# YAXArrays.Cubes.concatenatecubesMethod.
julia
function concatenateCubes(cubelist, cataxis::CategoricalAxis)

Concatenates a vector of datacubes that have identical axes to a new single cube along the new axis cataxis

source


# YAXArrays.Cubes.readcubedataMethod.
julia
readcubedata(cube)

Given any array implementing the YAXArray interface it returns an in-memory YAXArray from it.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::YAXArray,chunks)

Resets the chunks of a YAXArray and returns a new YAXArray. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savecube on the resulting array. The chunks argument can take one of the following forms:

source


# YAXArrays.Cubes.subsetcubeFunction.

This function calculates a subset of a cube's data

source


# YAXArrays.DAT.InDimsType.
julia
InDims(axisdesc...;...)

Creates a description of an Input Data Cube for cube operations. Takes a single or multiple axis descriptions as first arguments. Alternatively a MovingWindow(@ref) struct can be passed to include neighbour slices of one or more axes in the computation. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

Keyword arguments

source


# YAXArrays.DAT.MovingWindowType.
julia
MovingWindow(desc, pre, after)

Constructs a MovingWindow object to be passed to an InDims constructor to define that the axis in desc shall participate in the inner function (i.e. shall be looped over), but inside the inner function pre values before and after values after the center value will be passed as well.

For example passing MovingWindow("Time", 2, 0) will loop over the time axis and always pass the current time step plus the 2 previous steps. So in the inner function the array will have an additional dimension of size 3.

source


# YAXArrays.DAT.OutDimsMethod.
julia
OutDims(axisdesc;...)

Creates a description of an Output Data Cube for cube operations. Takes a single or a Vector/Tuple of axes as first argument. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

source


# YAXArrays.DAT.CubeTableMethod.
julia
CubeTable()

Function to turn a DataCube object into an iterable table. Takes a list of as arguments, specified as a name=cube expression. For example CubeTable(data=cube1,country=cube2) would generate a Table with the entries data and country, where data contains the values of cube1 and country the values of cube2. The cubes are matched and broadcasted along their axes like in mapCube.

source


# YAXArrays.DAT.cubefittableMethod.
julia
cubefittable(tab,o,fitsym;post=getpostfunction(o),kwargs...)

Executes fittable on the CubeTable tab with the (Weighted-)OnlineStat o, looping through the values specified by fitsym. Finally, writes the results from the TableAggregator to an output data cube.

source


# YAXArrays.DAT.fittableMethod.
julia
fittable(tab,o,fitsym;by=(),weight=nothing)

Loops through an iterable table tab and thereby fitting an OnlineStat o with the values specified through fitsym. Optionally one can specify a field (or tuple) to group by. Any groupby specifier can either be a symbol denoting the entry to group by or an anynymous function calculating the group from a table row.

For example the following would caluclate a weighted mean over a cube weighted by grid cell area and grouped by country and month:

julia
fittable(iter,WeightedMean,:tair,weight=(i->abs(cosd(i.lat))),by=(i->month(i.time),:country))

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)
+
+Map a given function \`fun\` over slices of all cubes of the dataset \`ds\`. 
+Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.
+For Datasets, only one output cube can be specified.
+In contrast to the mapCube function for cubes, additional arguments for the inner function should be set as keyword arguments.
+
+For the specific keyword arguments see the docstring of the mapCube function for cubes.

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)

Map a given function fun over slices of the data cube cube. The additional arguments addargs will be forwarded to the inner function fun. Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.

Keyword arguments

The first argument is always the function to be applied, the second is the input cube or a tuple of input cubes if needed.

source


# YAXArrays.Datasets.DatasetType.
julia
Dataset object which stores an \`OrderedDict\` of YAXArrays with Symbol keys.
+a dictionary of CubeAxes and a Dictionary of general properties.
+A dictionary can hold cubes with differing axes. But it will share the common axes between the subcubes.

source


# YAXArrays.Datasets.DatasetMethod.

Dataset(; properties = Dict{String,Any}, cubes...)

Construct a YAXArray Dataset with global attributes properties a and a list of named YAXArrays cubes...

source


# YAXArrays.Datasets.CubeMethod.
julia
Cube(ds::Dataset; joinname="Variable")

Construct a single YAXArray from the dataset ds by concatenating the cubes in the datset on the joinname dimension.

source


# YAXArrays.Datasets.open_datasetMethod.

open_dataset(g; driver=:all)

Open the dataset at g with the given driver. The default driver will search for available drivers and tries to detect the useable driver from the filename extension.

source


# YAXArrays.Datasets.savecubeMethod.
julia
savecube(cube,name::String)

Save a YAXArray to the path.

Extended Help

The keyword arguments are:

source


# YAXArrays.Datasets.savedatasetMethod.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


# YAXArrays.Datasets.to_datasetMethod.

to_dataset(c;datasetaxis = "Variable", layername = "layer")

Convert a Data Cube into a Dataset. It is possible to treat one of the Cube's axes as a "DatasetAxis" i.e. the cube will be split into different parts that become variables in the Dataset. If no such axis is specified or found, there will only be a single variable in the dataset with the name layername

source


Internal API

# YAXArrays.YAXDefaultsConstant.

Default configuration for YAXArrays, has the following fields:

source


# YAXArrays.findAxisMethod.
julia
findAxis(desc, c)

Internal function

Extended Help

Given an Axis description and a cube return the index of the Axis.

The Axis description can be:

source


# YAXArrays.getOutAxisMethod.
julia
getOutAxis

source


# YAXArrays.get_descriptorMethod.
julia
get_descriptor(a)

Get the descriptor of an Axis. This is used to dispatch on the descriptor.

source


# YAXArrays.match_axisMethod.
julia
match_axis

Internal function

Extended Help

Match the Axis based on the AxisDescriptor.
+This is used to find different axes and to make certain axis description the same.
+For example to disregard differences of captialisation.

source


# YAXArrays.Cubes.CleanMeType.
julia
mutable struct CleanMe

Struct which describes data paths and their persistency. Non-persistend paths/files are removed at finalize step

source


# YAXArrays.Cubes.cleanMethod.
julia
clean(c::CleanMe)

finalizer function for CleanMe struct. The main process removes all directories/files which are not persistent.

source


# YAXArrays.Cubes.copydataMethod.
julia
copydata(outar, inar, copybuf)

Internal function which copies the data from the input inar into the output outar at the copybuf positions.

source


# YAXArrays.Cubes.optifuncMethod.
julia
optifunc(s, maxbuf, incs, outcs, insize, outsize, writefac)

Internal

This function is going to be minimized to detect the best possible chunk setting for the rechunking of the data.

source


# YAXArrays.DAT.DATConfigType.

Configuration object of a DAT process. This holds all necessary information to perform the calculations. It contains the following fields:

source


# YAXArrays.DAT.InputCubeType.

Internal representation of an input cube for DAT operations

source


# YAXArrays.DAT.OutputCubeType.

Internal representation of an output cube for DAT operations

Fields

source


# YAXArrays.DAT.YAXColumnType.
julia
YAXColumn

A struct representing a single column of a YAXArray partitioned Table # Fields

source


# YAXArrays.DAT.cmpcachmissesMethod.

Function that compares two cache miss specifiers by their importance

source


# YAXArrays.DAT.getFrontPermMethod.

Calculate an axis permutation that brings the wanted dimensions to the front

source


# YAXArrays.DAT.getLoopCacheSizeMethod.

Calculate optimal Cache size to DAT operation

source


# YAXArrays.DAT.getOuttypeMethod.
julia
getOuttype(outtype, cdata)

Internal function

Get the element type for the output cube

source


# YAXArrays.DAT.getloopchunksMethod.
julia
getloopchunks(dc::DATConfig)

Internal function

Returns the chunks that can be looped over toghether for all dimensions.
+This computation of the size of the chunks is handled by [\`DiskArrays.approx_chunksize\`](@ref)

source


# YAXArrays.DAT.permuteloopaxesMethod.
julia
permuteloopaxes(dc)

Internal function

Permute the dimensions of the cube, so that the axes that are looped through are in the first positions. This is necessary for a faster looping through the data.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::Dataset,chunks)

Resets the chunks of all or a subset YAXArrays in the dataset and returns a new Dataset. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savedataset on the resulting array. The chunks argument can take one of the following forms:

where a description of the desired variable chunks can take one of the following forms:

source


# YAXArrays.Datasets.collectfromhandleMethod.

Extracts a YAXArray from a dataset handle that was just created from a arrayinfo

source


# YAXArrays.Datasets.createdatasetMethod.

function createdataset(DS::Type,axlist; kwargs...)

Creates a new dataset with axes specified in axlist. Each axis must be a subtype of CubeAxis. A new empty Zarr array will be created and can serve as a sink for mapCube operations.

Keyword arguments

source


# YAXArrays.Datasets.getarrayinfoMethod.

Extract necessary information to create a YAXArrayBase dataset from a name and YAXArray pair

source


# YAXArrays.Datasets.testrangeMethod.

Test if data in x can be approximated by a step range

source


`,100)]))}const b=a(r,[["render",o]]);export{u as __pageData,b as default}; diff --git a/previews/PR437/assets/api.md.BbyteFGm.lean.js b/previews/PR437/assets/api.md.BbyteFGm.lean.js new file mode 100644 index 00000000..f560f549 --- /dev/null +++ b/previews/PR437/assets/api.md.BbyteFGm.lean.js @@ -0,0 +1,13 @@ +import{_ as a,c as s,a2 as i,o as t}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"API Reference","description":"","frontmatter":{},"headers":[],"relativePath":"api.md","filePath":"api.md","lastUpdated":null}'),r={name:"api.md"};function o(l,e,d,n,p,c){return t(),s("div",null,e[0]||(e[0]=[i(`

API Reference

This section describes all available functions of this package.

Public API

# YAXArrays.getAxisMethod.
julia
getAxis(desc, c)

Given an Axis description and a cube, returns the corresponding axis of the cube. The Axis description can be:

source


# YAXArrays.CubesModule.

The functions provided by YAXArrays are supposed to work on different types of cubes. This module defines the interface for all Data types that

source


# YAXArrays.Cubes.YAXArrayType.
julia
YAXArray{T,N}

An array labelled with named axes that have values associated with them. It can wrap normal arrays or, more typically DiskArrays.

Fields

source


# YAXArrays.Cubes.caxesFunction.

Returns the axes of a Cube

source


# YAXArrays.Cubes.caxesMethod.
julia
caxes

Embeds Cube inside a new Cube

source


# YAXArrays.Cubes.concatenatecubesMethod.
julia
function concatenateCubes(cubelist, cataxis::CategoricalAxis)

Concatenates a vector of datacubes that have identical axes to a new single cube along the new axis cataxis

source


# YAXArrays.Cubes.readcubedataMethod.
julia
readcubedata(cube)

Given any array implementing the YAXArray interface it returns an in-memory YAXArray from it.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::YAXArray,chunks)

Resets the chunks of a YAXArray and returns a new YAXArray. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savecube on the resulting array. The chunks argument can take one of the following forms:

source


# YAXArrays.Cubes.subsetcubeFunction.

This function calculates a subset of a cube's data

source


# YAXArrays.DAT.InDimsType.
julia
InDims(axisdesc...;...)

Creates a description of an Input Data Cube for cube operations. Takes a single or multiple axis descriptions as first arguments. Alternatively a MovingWindow(@ref) struct can be passed to include neighbour slices of one or more axes in the computation. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

Keyword arguments

source


# YAXArrays.DAT.MovingWindowType.
julia
MovingWindow(desc, pre, after)

Constructs a MovingWindow object to be passed to an InDims constructor to define that the axis in desc shall participate in the inner function (i.e. shall be looped over), but inside the inner function pre values before and after values after the center value will be passed as well.

For example passing MovingWindow("Time", 2, 0) will loop over the time axis and always pass the current time step plus the 2 previous steps. So in the inner function the array will have an additional dimension of size 3.

source


# YAXArrays.DAT.OutDimsMethod.
julia
OutDims(axisdesc;...)

Creates a description of an Output Data Cube for cube operations. Takes a single or a Vector/Tuple of axes as first argument. Axes can be specified by their name (String), through an Axis type, or by passing a concrete axis.

source


# YAXArrays.DAT.CubeTableMethod.
julia
CubeTable()

Function to turn a DataCube object into an iterable table. Takes a list of as arguments, specified as a name=cube expression. For example CubeTable(data=cube1,country=cube2) would generate a Table with the entries data and country, where data contains the values of cube1 and country the values of cube2. The cubes are matched and broadcasted along their axes like in mapCube.

source


# YAXArrays.DAT.cubefittableMethod.
julia
cubefittable(tab,o,fitsym;post=getpostfunction(o),kwargs...)

Executes fittable on the CubeTable tab with the (Weighted-)OnlineStat o, looping through the values specified by fitsym. Finally, writes the results from the TableAggregator to an output data cube.

source


# YAXArrays.DAT.fittableMethod.
julia
fittable(tab,o,fitsym;by=(),weight=nothing)

Loops through an iterable table tab and thereby fitting an OnlineStat o with the values specified through fitsym. Optionally one can specify a field (or tuple) to group by. Any groupby specifier can either be a symbol denoting the entry to group by or an anynymous function calculating the group from a table row.

For example the following would caluclate a weighted mean over a cube weighted by grid cell area and grouped by country and month:

julia
fittable(iter,WeightedMean,:tair,weight=(i->abs(cosd(i.lat))),by=(i->month(i.time),:country))

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)
+
+Map a given function \`fun\` over slices of all cubes of the dataset \`ds\`. 
+Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.
+For Datasets, only one output cube can be specified.
+In contrast to the mapCube function for cubes, additional arguments for the inner function should be set as keyword arguments.
+
+For the specific keyword arguments see the docstring of the mapCube function for cubes.

source


# YAXArrays.DAT.mapCubeMethod.
julia
mapCube(fun, cube, addargs...;kwargs...)

Map a given function fun over slices of the data cube cube. The additional arguments addargs will be forwarded to the inner function fun. Use InDims to discribe the input dimensions and OutDims to describe the output dimensions of the function.

Keyword arguments

The first argument is always the function to be applied, the second is the input cube or a tuple of input cubes if needed.

source


# YAXArrays.Datasets.DatasetType.
julia
Dataset object which stores an \`OrderedDict\` of YAXArrays with Symbol keys.
+a dictionary of CubeAxes and a Dictionary of general properties.
+A dictionary can hold cubes with differing axes. But it will share the common axes between the subcubes.

source


# YAXArrays.Datasets.DatasetMethod.

Dataset(; properties = Dict{String,Any}, cubes...)

Construct a YAXArray Dataset with global attributes properties a and a list of named YAXArrays cubes...

source


# YAXArrays.Datasets.CubeMethod.
julia
Cube(ds::Dataset; joinname="Variable")

Construct a single YAXArray from the dataset ds by concatenating the cubes in the datset on the joinname dimension.

source


# YAXArrays.Datasets.open_datasetMethod.

open_dataset(g; driver=:all)

Open the dataset at g with the given driver. The default driver will search for available drivers and tries to detect the useable driver from the filename extension.

source


# YAXArrays.Datasets.savecubeMethod.
julia
savecube(cube,name::String)

Save a YAXArray to the path.

Extended Help

The keyword arguments are:

source


# YAXArrays.Datasets.savedatasetMethod.

savedataset(ds::Dataset; path = "", persist = nothing, overwrite = false, append = false, skeleton=false, backend = :all, driver = backend, max_cache = 5e8, writefac=4.0)

Saves a Dataset into a file at path with the format given by driver, i.e., driver=:netcdf or driver=:zarr.

Warning

overwrite = true, deletes ALL your data and it will create a new file.

source


# YAXArrays.Datasets.to_datasetMethod.

to_dataset(c;datasetaxis = "Variable", layername = "layer")

Convert a Data Cube into a Dataset. It is possible to treat one of the Cube's axes as a "DatasetAxis" i.e. the cube will be split into different parts that become variables in the Dataset. If no such axis is specified or found, there will only be a single variable in the dataset with the name layername

source


Internal API

# YAXArrays.YAXDefaultsConstant.

Default configuration for YAXArrays, has the following fields:

source


# YAXArrays.findAxisMethod.
julia
findAxis(desc, c)

Internal function

Extended Help

Given an Axis description and a cube return the index of the Axis.

The Axis description can be:

source


# YAXArrays.getOutAxisMethod.
julia
getOutAxis

source


# YAXArrays.get_descriptorMethod.
julia
get_descriptor(a)

Get the descriptor of an Axis. This is used to dispatch on the descriptor.

source


# YAXArrays.match_axisMethod.
julia
match_axis

Internal function

Extended Help

Match the Axis based on the AxisDescriptor.
+This is used to find different axes and to make certain axis description the same.
+For example to disregard differences of captialisation.

source


# YAXArrays.Cubes.CleanMeType.
julia
mutable struct CleanMe

Struct which describes data paths and their persistency. Non-persistend paths/files are removed at finalize step

source


# YAXArrays.Cubes.cleanMethod.
julia
clean(c::CleanMe)

finalizer function for CleanMe struct. The main process removes all directories/files which are not persistent.

source


# YAXArrays.Cubes.copydataMethod.
julia
copydata(outar, inar, copybuf)

Internal function which copies the data from the input inar into the output outar at the copybuf positions.

source


# YAXArrays.Cubes.optifuncMethod.
julia
optifunc(s, maxbuf, incs, outcs, insize, outsize, writefac)

Internal

This function is going to be minimized to detect the best possible chunk setting for the rechunking of the data.

source


# YAXArrays.DAT.DATConfigType.

Configuration object of a DAT process. This holds all necessary information to perform the calculations. It contains the following fields:

source


# YAXArrays.DAT.InputCubeType.

Internal representation of an input cube for DAT operations

source


# YAXArrays.DAT.OutputCubeType.

Internal representation of an output cube for DAT operations

Fields

source


# YAXArrays.DAT.YAXColumnType.
julia
YAXColumn

A struct representing a single column of a YAXArray partitioned Table # Fields

source


# YAXArrays.DAT.cmpcachmissesMethod.

Function that compares two cache miss specifiers by their importance

source


# YAXArrays.DAT.getFrontPermMethod.

Calculate an axis permutation that brings the wanted dimensions to the front

source


# YAXArrays.DAT.getLoopCacheSizeMethod.

Calculate optimal Cache size to DAT operation

source


# YAXArrays.DAT.getOuttypeMethod.
julia
getOuttype(outtype, cdata)

Internal function

Get the element type for the output cube

source


# YAXArrays.DAT.getloopchunksMethod.
julia
getloopchunks(dc::DATConfig)

Internal function

Returns the chunks that can be looped over toghether for all dimensions.
+This computation of the size of the chunks is handled by [\`DiskArrays.approx_chunksize\`](@ref)

source


# YAXArrays.DAT.permuteloopaxesMethod.
julia
permuteloopaxes(dc)

Internal function

Permute the dimensions of the cube, so that the axes that are looped through are in the first positions. This is necessary for a faster looping through the data.

source


# YAXArrays.Cubes.setchunksMethod.
julia
setchunks(c::Dataset,chunks)

Resets the chunks of all or a subset YAXArrays in the dataset and returns a new Dataset. Note that this will not change the chunking of the underlying data itself, it will just make the data "look" like it had a different chunking. If you need a persistent on-disk representation of this chunking, use savedataset on the resulting array. The chunks argument can take one of the following forms:

where a description of the desired variable chunks can take one of the following forms:

source


# YAXArrays.Datasets.collectfromhandleMethod.

Extracts a YAXArray from a dataset handle that was just created from a arrayinfo

source


# YAXArrays.Datasets.createdatasetMethod.

function createdataset(DS::Type,axlist; kwargs...)

Creates a new dataset with axes specified in axlist. Each axis must be a subtype of CubeAxis. A new empty Zarr array will be created and can serve as a sink for mapCube operations.

Keyword arguments

source


# YAXArrays.Datasets.getarrayinfoMethod.

Extract necessary information to create a YAXArrayBase dataset from a name and YAXArray pair

source


# YAXArrays.Datasets.testrangeMethod.

Test if data in x can be approximated by a step range

source


`,100)]))}const b=a(r,[["render",o]]);export{u as __pageData,b as default}; diff --git a/previews/PR437/assets/app.DRWAkRGp.js b/previews/PR437/assets/app.DRWAkRGp.js new file mode 100644 index 00000000..2f5ef8f4 --- /dev/null +++ b/previews/PR437/assets/app.DRWAkRGp.js @@ -0,0 +1 @@ +import{R as p}from"./chunks/theme.C_rChtpL.js";import{R as o,a6 as u,a7 as c,a8 as l,a9 as f,aa as d,ab as m,ac as h,ad as g,ae as A,af as v,d as P,u as R,v as w,s as y,ag as C,ah as b,ai as E,a5 as S}from"./chunks/framework.BxolPc_T.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(p),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),b(),E(),s.setup&&s.setup(),()=>S(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=j(),a=_();a.provide(c,e);const t=l(e.route);return a.provide(f,t),a.component("Content",d),a.component("ClientOnly",m),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:h}),{app:a,router:e,data:t}}function _(){return g(T)}function j(){let e=o,a;return A(t=>{let n=v(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{u(a.route,t.site),e.mount("#app")})});export{D as createApp}; diff --git a/previews/PR437/assets/byjkepm.BBOgXAcy.png b/previews/PR437/assets/byjkepm.BBOgXAcy.png new file mode 100644 index 00000000..6368753f Binary files /dev/null and b/previews/PR437/assets/byjkepm.BBOgXAcy.png differ diff --git a/previews/PR437/assets/chunks/@localSearchIndexroot.Dgdb-kc0.js b/previews/PR437/assets/chunks/@localSearchIndexroot.Dgdb-kc0.js new file mode 100644 index 00000000..35d02e86 --- /dev/null +++ b/previews/PR437/assets/chunks/@localSearchIndexroot.Dgdb-kc0.js @@ -0,0 +1 @@ +const e='{"documentCount":95,"nextId":95,"documentIds":{"0":"/YAXArrays.jl/previews/PR437/UserGuide/cache.html#Caching-YAXArrays","1":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Chunk-YAXArrays","2":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Chunking-YAXArrays","3":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Chunking-Datasets","4":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Set-Chunks-by-Axis","5":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Set-chunking-by-Variable","6":"/YAXArrays.jl/previews/PR437/UserGuide/chunk.html#Set-chunking-for-all-variables","7":"/YAXArrays.jl/previews/PR437/UserGuide/combine.html#Combine-YAXArrays","8":"/YAXArrays.jl/previews/PR437/UserGuide/combine.html#cat-along-an-existing-dimension","9":"/YAXArrays.jl/previews/PR437/UserGuide/combine.html#concatenatecubes-to-a-new-dimension","10":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#Compute-YAXArrays","11":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#Modify-elements-of-a-YAXArray","12":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#arithmetics","13":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#map","14":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#mapslices","15":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#mapCube","16":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#Operations-over-several-YAXArrays","17":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#Creating-a-vector-array","18":"/YAXArrays.jl/previews/PR437/UserGuide/compute.html#Distributed-Computation","19":"/YAXArrays.jl/previews/PR437/UserGuide/convert.html#Convert-YAXArrays","20":"/YAXArrays.jl/previews/PR437/UserGuide/convert.html#Convert-Base.Array","21":"/YAXArrays.jl/previews/PR437/UserGuide/convert.html#Convert-Raster","22":"/YAXArrays.jl/previews/PR437/UserGuide/convert.html#Convert-DimArray","23":"/YAXArrays.jl/previews/PR437/UserGuide/create.html#Create-YAXArrays-and-Datasets","24":"/YAXArrays.jl/previews/PR437/UserGuide/create.html#Create-a-YAXArray","25":"/YAXArrays.jl/previews/PR437/UserGuide/create.html#Create-a-Dataset","26":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Frequently-Asked-Questions-(FAQ)","27":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Extract-the-axes-names-from-a-Cube","28":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#rebuild","29":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Obtain-values-from-axes-and-data-from-the-cube","30":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#How-do-I-concatenate-cubes","31":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#How-do-I-subset-a-YAXArray-(-Cube-)-or-Dataset?","32":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Subsetting-a-YAXArray","33":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Subsetting-a-Dataset","34":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Subsetting-a-Dataset-whose-variables-share-all-their-dimensions","35":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Subsetting-a-Dataset-whose-variables-share-some-but-not-all-of-their-dimensions","36":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#How-do-I-apply-map-algebra?","37":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#How-do-I-use-the-CubeTable-function?","38":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#How-do-I-assign-variable-names-to-YAXArrays-in-a-Dataset","39":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#One-variable-name","40":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Multiple-variable-names","41":"/YAXArrays.jl/previews/PR437/UserGuide/faq.html#Ho-do-I-construct-a-Dataset-from-a-TimeArray","42":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#Group-YAXArrays-and-Datasets","43":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#Seasonal-Averages-from-Time-Series-of-Monthly-Means","44":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#Download-the-data","45":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#GroupBy:-seasons","46":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#dropdims","47":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#seasons","48":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#GroupBy:-weight","49":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#weights","50":"/YAXArrays.jl/previews/PR437/UserGuide/group.html#weighted-seasons","51":"/YAXArrays.jl/previews/PR437/UserGuide/read.html#Read-YAXArrays-and-Datasets","52":"/YAXArrays.jl/previews/PR437/UserGuide/read.html#Read-Zarr","53":"/YAXArrays.jl/previews/PR437/UserGuide/read.html#Read-NetCDF","54":"/YAXArrays.jl/previews/PR437/UserGuide/read.html#Read-GDAL-(GeoTIFF,-GeoJSON)","55":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Select-YAXArrays-and-Datasets","56":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Select-a-YAXArray","57":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Select-elements","58":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Select-ranges","59":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Closed-and-open-intervals","60":"/YAXArrays.jl/previews/PR437/UserGuide/select.html#Get-a-dimension","61":"/YAXArrays.jl/previews/PR437/UserGuide/types.html#types","62":"/YAXArrays.jl/previews/PR437/UserGuide/types.html#yaxarray","63":"/YAXArrays.jl/previews/PR437/UserGuide/types.html#dataset","64":"/YAXArrays.jl/previews/PR437/UserGuide/types.html#(Data)-Cube","65":"/YAXArrays.jl/previews/PR437/UserGuide/types.html#dimension","66":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Write-YAXArrays-and-Datasets","67":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Write-Zarr","68":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Write-NetCDF","69":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Overwrite-a-Dataset","70":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Append-to-a-Dataset","71":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Save-Skeleton","72":"/YAXArrays.jl/previews/PR437/UserGuide/write.html#Update-values-of-dataset","73":"/YAXArrays.jl/previews/PR437/api.html#API-Reference","74":"/YAXArrays.jl/previews/PR437/api.html#Public-API","75":"/YAXArrays.jl/previews/PR437/api.html#Internal-API","76":"/YAXArrays.jl/previews/PR437/development/contribute.html#Contribute-to-YAXArrays.jl","77":"/YAXArrays.jl/previews/PR437/development/contribute.html#Contribute-to-Documentation","78":"/YAXArrays.jl/previews/PR437/development/contribute.html#Build-docs-locally","79":"/YAXArrays.jl/previews/PR437/get_started.html#Getting-Started","80":"/YAXArrays.jl/previews/PR437/get_started.html#installation","81":"/YAXArrays.jl/previews/PR437/get_started.html#quickstart","82":"/YAXArrays.jl/previews/PR437/get_started.html#updates","83":"/YAXArrays.jl/previews/PR437/tutorials/mean_seasonal_cycle.html#Mean-Seasonal-Cycle-for-a-single-pixel","84":"/YAXArrays.jl/previews/PR437/tutorials/mean_seasonal_cycle.html#Define-the-cube","85":"/YAXArrays.jl/previews/PR437/tutorials/mean_seasonal_cycle.html#Plot-results:-mean-seasonal-cycle","86":"/YAXArrays.jl/previews/PR437/tutorials/other_tutorials.html#Other-tutorials","87":"/YAXArrays.jl/previews/PR437/tutorials/other_tutorials.html#General-overview-of-the-functionality-of-YAXArrays","88":"/YAXArrays.jl/previews/PR437/tutorials/other_tutorials.html#Table-style-iteration-over-YAXArrays","89":"/YAXArrays.jl/previews/PR437/tutorials/other_tutorials.html#Combining-multiple-tiff-files-into-a-zarr-based-datacube","90":"/YAXArrays.jl/previews/PR437/tutorials/plottingmaps.html#Plotting-maps","91":"/YAXArrays.jl/previews/PR437/tutorials/plottingmaps.html#Heatmap-plot","92":"/YAXArrays.jl/previews/PR437/tutorials/plottingmaps.html#Wintri-Projection","93":"/YAXArrays.jl/previews/PR437/tutorials/plottingmaps.html#Moll-projection","94":"/YAXArrays.jl/previews/PR437/tutorials/plottingmaps.html#3D-sphere-plot"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[2,1,86],"1":[2,1,58],"2":[2,2,57],"3":[2,2,9],"4":[4,4,76],"5":[4,4,76],"6":[5,4,81],"7":[2,1,31],"8":[5,2,80],"9":[5,2,89],"10":[2,1,117],"11":[5,2,30],"12":[1,2,70],"13":[1,2,118],"14":[1,2,88],"15":[1,2,22],"16":[4,3,210],"17":[4,3,248],"18":[2,2,138],"19":[2,1,52],"20":[3,2,84],"21":[2,2,116],"22":[2,2,120],"23":[4,1,14],"24":[3,4,106],"25":[3,4,45],"26":[5,1,19],"27":[7,5,75],"28":[1,11,90],"29":[8,5,75],"30":[5,5,87],"31":[10,5,33],"32":[3,14,144],"33":[3,14,18],"34":[9,14,69],"35":[13,14,157],"36":[7,5,112],"37":[8,5,169],"38":[11,5,1],"39":[3,15,24],"40":[3,15,37],"41":[8,5,140],"42":[4,1,23],"43":[8,4,35],"44":[3,4,67],"45":[2,4,136],"46":[1,6,102],"47":[1,6,49],"48":[2,4,107],"49":[1,6,87],"50":[2,6,349],"51":[4,1,14],"52":[2,4,188],"53":[2,4,206],"54":[5,4,38],"55":[4,1,165],"56":[3,4,106],"57":[2,4,117],"58":[2,4,131],"59":[4,4,144],"60":[3,4,73],"61":[1,1,16],"62":[1,1,113],"63":[1,1,78],"64":[3,1,70],"65":[1,1,32],"66":[4,1,146],"67":[2,4,19],"68":[2,4,20],"69":[3,4,80],"70":[4,4,157],"71":[2,4,154],"72":[4,4,93],"73":[2,1,10],"74":[2,2,559],"75":[2,2,467],"76":[4,1,15],"77":[3,4,40],"78":[3,5,75],"79":[2,1,1],"80":[1,2,34],"81":[1,2,196],"82":[1,2,49],"83":[7,1,73],"84":[3,7,132],"85":[5,7,48],"86":[2,1,49],"87":[6,2,12],"88":[5,2,38],"89":[9,2,1],"90":[2,1,136],"91":[2,2,21],"92":[2,1,46],"93":[2,2,33],"94":[3,2,57]},"averageFieldLength":[3.463157894736843,3.7157894736842105,91.34736842105264],"storedFields":{"0":{"title":"Caching YAXArrays","titles":[]},"1":{"title":"Chunk YAXArrays","titles":[]},"2":{"title":"Chunking YAXArrays","titles":["Chunk YAXArrays"]},"3":{"title":"Chunking Datasets","titles":["Chunk YAXArrays"]},"4":{"title":"Set Chunks by Axis","titles":["Chunk YAXArrays","Chunking Datasets"]},"5":{"title":"Set chunking by Variable","titles":["Chunk YAXArrays","Chunking Datasets"]},"6":{"title":"Set chunking for all variables","titles":["Chunk YAXArrays","Chunking Datasets"]},"7":{"title":"Combine YAXArrays","titles":[]},"8":{"title":"cat along an existing dimension","titles":["Combine YAXArrays"]},"9":{"title":"concatenatecubes to a new dimension","titles":["Combine YAXArrays"]},"10":{"title":"Compute YAXArrays","titles":[]},"11":{"title":"Modify elements of a YAXArray","titles":["Compute YAXArrays"]},"12":{"title":"Arithmetics","titles":["Compute YAXArrays"]},"13":{"title":"map","titles":["Compute YAXArrays"]},"14":{"title":"mapslices","titles":["Compute YAXArrays"]},"15":{"title":"mapCube","titles":["Compute YAXArrays"]},"16":{"title":"Operations over several YAXArrays","titles":["Compute YAXArrays","mapCube"]},"17":{"title":"Creating a vector array","titles":["Compute YAXArrays","mapCube"]},"18":{"title":"Distributed Computation","titles":["Compute YAXArrays"]},"19":{"title":"Convert YAXArrays","titles":[]},"20":{"title":"Convert Base.Array","titles":["Convert YAXArrays"]},"21":{"title":"Convert Raster","titles":["Convert YAXArrays"]},"22":{"title":"Convert DimArray","titles":["Convert YAXArrays"]},"23":{"title":"Create YAXArrays and Datasets","titles":[]},"24":{"title":"Create a YAXArray","titles":["Create YAXArrays and Datasets"]},"25":{"title":"Create a Dataset","titles":["Create YAXArrays and Datasets"]},"26":{"title":"Frequently Asked Questions (FAQ)","titles":[]},"27":{"title":"Extract the axes names from a Cube","titles":["Frequently Asked Questions (FAQ)"]},"28":{"title":"rebuild","titles":["Frequently Asked Questions (FAQ)","Extract the axes names from a Cube"]},"29":{"title":"Obtain values from axes and data from the cube","titles":["Frequently Asked Questions (FAQ)"]},"30":{"title":"How do I concatenate cubes","titles":["Frequently Asked Questions (FAQ)"]},"31":{"title":"How do I subset a YAXArray ( Cube ) or Dataset?","titles":["Frequently Asked Questions (FAQ)"]},"32":{"title":"Subsetting a YAXArray","titles":["Frequently Asked Questions (FAQ)","How do I subset a YAXArray ( Cube ) or Dataset?"]},"33":{"title":"Subsetting a Dataset","titles":["Frequently Asked Questions (FAQ)","How do I subset a YAXArray ( Cube ) or Dataset?"]},"34":{"title":"Subsetting a Dataset whose variables share all their dimensions","titles":["Frequently Asked Questions (FAQ)","How do I subset a YAXArray ( Cube ) or Dataset?","Subsetting a Dataset"]},"35":{"title":"Subsetting a Dataset whose variables share some but not all of their dimensions","titles":["Frequently Asked Questions (FAQ)","How do I subset a YAXArray ( Cube ) or Dataset?","Subsetting a Dataset"]},"36":{"title":"How do I apply map algebra?","titles":["Frequently Asked Questions (FAQ)"]},"37":{"title":"How do I use the CubeTable function?","titles":["Frequently Asked Questions (FAQ)"]},"38":{"title":"How do I assign variable names to YAXArrays in a Dataset","titles":["Frequently Asked Questions (FAQ)"]},"39":{"title":"One variable name","titles":["Frequently Asked Questions (FAQ)","How do I assign variable names to YAXArrays in a Dataset"]},"40":{"title":"Multiple variable names","titles":["Frequently Asked Questions (FAQ)","How do I assign variable names to YAXArrays in a Dataset"]},"41":{"title":"Ho do I construct a Dataset from a TimeArray","titles":["Frequently Asked Questions (FAQ)"]},"42":{"title":"Group YAXArrays and Datasets","titles":[]},"43":{"title":"Seasonal Averages from Time Series of Monthly Means","titles":["Group YAXArrays and Datasets"]},"44":{"title":"Download the data","titles":["Group YAXArrays and Datasets"]},"45":{"title":"GroupBy: seasons","titles":["Group YAXArrays and Datasets"]},"46":{"title":"dropdims","titles":["Group YAXArrays and Datasets","GroupBy: seasons"]},"47":{"title":"seasons","titles":["Group YAXArrays and Datasets","GroupBy: seasons"]},"48":{"title":"GroupBy: weight","titles":["Group YAXArrays and Datasets"]},"49":{"title":"weights","titles":["Group YAXArrays and Datasets","GroupBy: weight"]},"50":{"title":"weighted seasons","titles":["Group YAXArrays and Datasets","GroupBy: weight"]},"51":{"title":"Read YAXArrays and Datasets","titles":[]},"52":{"title":"Read Zarr","titles":["Read YAXArrays and Datasets"]},"53":{"title":"Read NetCDF","titles":["Read YAXArrays and Datasets"]},"54":{"title":"Read GDAL (GeoTIFF, GeoJSON)","titles":["Read YAXArrays and Datasets"]},"55":{"title":"Select YAXArrays and Datasets","titles":[]},"56":{"title":"Select a YAXArray","titles":["Select YAXArrays and Datasets"]},"57":{"title":"Select elements","titles":["Select YAXArrays and Datasets"]},"58":{"title":"Select ranges","titles":["Select YAXArrays and Datasets"]},"59":{"title":"Closed and open intervals","titles":["Select YAXArrays and Datasets"]},"60":{"title":"Get a dimension","titles":["Select YAXArrays and Datasets"]},"61":{"title":"Types","titles":[]},"62":{"title":"YAXArray","titles":["Types"]},"63":{"title":"Dataset","titles":["Types"]},"64":{"title":"(Data) Cube","titles":["Types"]},"65":{"title":"Dimension","titles":["Types"]},"66":{"title":"Write YAXArrays and Datasets","titles":[]},"67":{"title":"Write Zarr","titles":["Write YAXArrays and Datasets"]},"68":{"title":"Write NetCDF","titles":["Write YAXArrays and Datasets"]},"69":{"title":"Overwrite a Dataset","titles":["Write YAXArrays and Datasets"]},"70":{"title":"Append to a Dataset","titles":["Write YAXArrays and Datasets"]},"71":{"title":"Save Skeleton","titles":["Write YAXArrays and Datasets"]},"72":{"title":"Update values of dataset","titles":["Write YAXArrays and Datasets"]},"73":{"title":"API Reference","titles":[]},"74":{"title":"Public API","titles":["API Reference"]},"75":{"title":"Internal API","titles":["API Reference"]},"76":{"title":"Contribute to YAXArrays.jl","titles":[]},"77":{"title":"Contribute to Documentation","titles":["Contribute to YAXArrays.jl"]},"78":{"title":"Build docs locally","titles":["Contribute to YAXArrays.jl","Contribute to Documentation"]},"79":{"title":"Getting Started","titles":[]},"80":{"title":"Installation","titles":["Getting Started"]},"81":{"title":"Quickstart","titles":["Getting Started"]},"82":{"title":"Updates","titles":["Getting Started"]},"83":{"title":"Mean Seasonal Cycle for a single pixel","titles":[]},"84":{"title":"Define the cube","titles":["Mean Seasonal Cycle for a single pixel"]},"85":{"title":"Plot results: mean seasonal cycle","titles":["Mean Seasonal Cycle for a single pixel"]},"86":{"title":"Other tutorials","titles":[]},"87":{"title":"General overview of the functionality of YAXArrays","titles":["Other tutorials"]},"88":{"title":"Table-style iteration over YAXArrays","titles":["Other tutorials"]},"89":{"title":"Combining multiple tiff files into a zarr based datacube","titles":["Other tutorials"]},"90":{"title":"Plotting maps","titles":[]},"91":{"title":"Heatmap plot","titles":["Plotting maps"]},"92":{"title":"Wintri Projection","titles":[]},"93":{"title":"Moll projection","titles":["Wintri Projection"]},"94":{"title":"3D sphere plot","titles":["Wintri Projection"]}},"dirtCount":0,"index":[["δlon",{"2":{"92":1}}],["`diskarrays",{"2":{"75":1}}],["`ds`",{"2":{"74":1}}],["`ordereddict`",{"2":{"74":1}}],["`fun`",{"2":{"74":1}}],["`a",{"2":{"32":1}}],["π",{"2":{"36":2,"83":1,"85":1}}],[">var",{"2":{"84":1}}],[">dates",{"2":{"84":1}}],[">month",{"2":{"74":1}}],[">abs",{"2":{"74":1}}],[">=",{"2":{"35":4}}],[">",{"2":{"35":2,"36":2,"84":1}}],["└──────────────────────────────────────────────────────────┘",{"2":{"32":1}}],["└─────────────────────────────────────────────────────────────┘",{"2":{"21":2}}],["└──────────────────────────────────────────────────────────────────┘",{"2":{"22":2}}],["└──────────────────────────────────────────────────────────────────────┘",{"2":{"24":1,"28":1}}],["└────────────────────────────────────────────────────────────────────────────────┘",{"2":{"57":1}}],["└──────────────────────────────────────────────────────────────────────────────┘",{"2":{"10":1,"12":1,"13":1,"14":2,"16":5,"17":4,"24":1,"27":1,"28":2,"29":1,"30":1,"32":4,"36":3,"37":3,"45":2,"46":1,"48":3,"49":2,"50":3,"52":1,"53":1,"56":2,"57":2,"58":3,"59":5,"71":1,"81":1,"84":1}}],["└───────────────────────────────────────────────────────────────────────┘",{"2":{"8":1}}],["└─────────────────────────────────────────────────────────────────────┘",{"2":{"20":1,"81":1}}],["└────────────────────────────────────────────────────────────────┘",{"2":{"9":1}}],["⬔",{"2":{"30":1,"81":1}}],["quickstart",{"0":{"81":1}}],["query",{"2":{"55":1}}],["questions",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["quot",{"2":{"16":2,"37":2,"69":2,"71":4,"74":16,"75":12}}],["jj+1",{"2":{"53":1,"55":1,"66":1,"70":1}}],["jj",{"2":{"53":1,"55":1,"66":1,"70":1}}],["joinname",{"2":{"74":1}}],["joinname=",{"2":{"74":1}}],["journal",{"2":{"53":1,"55":1,"66":1,"70":1}}],["joe",{"2":{"43":1,"50":1}}],["j",{"2":{"50":8}}],["jan",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["jl",{"0":{"76":1},"1":{"77":1,"78":1},"2":{"21":1,"22":1,"37":1,"41":2,"44":1,"50":1,"62":1,"65":1,"76":1,"78":2,"80":1,"81":2,"82":3,"88":1}}],["jussieu",{"2":{"53":1,"55":1,"66":1,"70":1}}],["just",{"2":{"17":1,"62":1,"64":1,"74":1,"75":2}}],["jul",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["juliaδlon",{"2":{"92":1}}],["juliaglmakie",{"2":{"91":1}}],["juliagetloopchunks",{"2":{"75":1}}],["juliagetouttype",{"2":{"75":1}}],["juliagetoutaxis",{"2":{"75":1}}],["juliaget",{"2":{"75":1}}],["juliagetaxis",{"2":{"74":1}}],["juliagettarrayaxes",{"2":{"41":1}}],["juliagen",{"2":{"16":1}}],["juliax",{"2":{"83":1}}],["juliapkg>",{"2":{"80":1,"82":1}}],["juliapermuteloopaxes",{"2":{"75":1}}],["juliaoptifunc",{"2":{"75":1}}],["juliaoutdims",{"2":{"74":1}}],["juliaoffset",{"2":{"13":1}}],["juliaindims",{"2":{"74":1}}],["juliaimport",{"2":{"14":1,"80":1}}],["juliacopydata",{"2":{"75":1}}],["juliacollect",{"2":{"29":1,"60":1}}],["juliaclean",{"2":{"75":1}}],["juliacube",{"2":{"74":1}}],["juliacubefittable",{"2":{"74":1}}],["juliacubetable",{"2":{"74":1}}],["juliacaxes",{"2":{"74":1}}],["juliasavecube",{"2":{"74":1}}],["juliasavedataset",{"2":{"67":1,"68":1,"69":1}}],["juliasetchunks",{"2":{"74":1,"75":1}}],["juliaseasons",{"2":{"47":1}}],["julialon",{"2":{"90":1}}],["julialookup",{"2":{"60":1}}],["julialatitudes",{"2":{"35":1}}],["juliawith",{"2":{"50":1}}],["julia>",{"2":{"50":1,"78":1,"84":1}}],["juliaurl",{"2":{"44":1}}],["juliausing",{"2":{"0":1,"2":1,"4":1,"5":1,"6":1,"8":1,"9":1,"10":1,"16":1,"17":1,"18":2,"20":1,"21":1,"22":1,"24":2,"27":1,"28":1,"30":1,"32":1,"34":1,"35":1,"37":2,"41":1,"42":1,"50":1,"52":1,"53":1,"54":1,"55":1,"57":1,"59":1,"66":1,"67":1,"68":1,"71":1,"81":2,"83":1,"90":1,"94":1}}],["juliakeylist",{"2":{"40":1}}],["juliaylonlat",{"2":{"32":1}}],["juliaytime3",{"2":{"32":1}}],["juliaytime2",{"2":{"32":1}}],["juliaytime",{"2":{"32":1}}],["juliay",{"2":{"32":1}}],["juliayaxcolumn",{"2":{"75":1}}],["juliayaxarray",{"2":{"74":1}}],["juliayax",{"2":{"0":1,"41":2}}],["juliatos",{"2":{"56":2,"57":2,"58":3,"59":1,"60":1}}],["juliatempo",{"2":{"48":1}}],["juliat",{"2":{"32":1,"37":1,"83":1}}],["juliatspan",{"2":{"16":1}}],["juliadataset",{"2":{"74":1}}],["juliadata3",{"2":{"25":1}}],["juliads2",{"2":{"70":1}}],["juliads",{"2":{"34":1,"35":1,"52":1,"53":1,"71":2,"72":3}}],["juliadim",{"2":{"22":1}}],["juliadimarray",{"2":{"17":1}}],["juliareadcubedata",{"2":{"74":1}}],["juliaregions",{"2":{"17":2}}],["juliar",{"2":{"71":1}}],["juliaras2",{"2":{"21":1}}],["juliamutable",{"2":{"75":1}}],["juliamatch",{"2":{"75":1}}],["juliamapcube",{"2":{"74":2}}],["juliamapslices",{"2":{"14":1,"18":1}}],["juliamovingwindow",{"2":{"74":1}}],["juliamean",{"2":{"50":1}}],["juliam2",{"2":{"20":1}}],["julia",{"2":{"19":1,"75":1,"78":1,"80":2,"82":2}}],["juliavector",{"2":{"17":1}}],["juliajulia>",{"2":{"16":5,"27":3,"28":2,"29":1,"30":1,"36":3,"37":3,"39":1,"40":1,"41":2,"45":2,"46":1,"48":2,"49":2,"50":3,"59":4,"70":1,"71":1,"84":2,"90":3}}],["juliaall",{"2":{"71":1}}],["juliaaxs",{"2":{"44":1}}],["juliaaxes",{"2":{"32":1}}],["juliaa2",{"2":{"12":2,"24":2,"81":1}}],["juliaa",{"2":{"2":1,"11":3}}],["juliafig",{"2":{"83":1,"85":1,"92":1,"93":1}}],["juliafindaxis",{"2":{"75":1}}],["juliafittable",{"2":{"74":2}}],["juliafunction",{"2":{"16":1,"45":1,"74":1,"84":1}}],["juliaf",{"2":{"2":1,"4":1,"5":1,"6":1,"16":1}}],["jun",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["∘",{"2":{"18":1}}],["|>",{"2":{"17":2}}],["⋱",{"2":{"17":1}}],["⋮",{"2":{"17":2,"60":1,"84":1}}],["925986",{"2":{"81":1}}],["921833",{"2":{"81":1}}],["985469",{"2":{"81":1}}],["986",{"2":{"50":1}}],["988263",{"2":{"21":1}}],["976249",{"2":{"72":2}}],["976121",{"2":{"72":2}}],["97649",{"2":{"50":1}}],["97047",{"2":{"50":1}}],["979087",{"2":{"20":1}}],["948197",{"2":{"72":2}}],["94534",{"2":{"50":1}}],["945109",{"2":{"17":1}}],["9404",{"2":{"45":1,"46":1}}],["9432",{"2":{"45":1,"46":1}}],["94",{"2":{"35":6}}],["90712",{"2":{"50":1}}],["90365",{"2":{"50":1}}],["903606",{"2":{"22":1}}],["90",{"2":{"35":2,"59":5}}],["9192",{"2":{"50":1}}],["91",{"2":{"27":1,"59":5}}],["912882",{"2":{"20":1}}],["95",{"2":{"50":1}}],["959",{"2":{"50":1}}],["956491",{"2":{"22":1}}],["95716",{"2":{"17":1}}],["9316",{"2":{"81":1}}],["9375",{"2":{"52":2,"90":1}}],["93743",{"2":{"50":1}}],["93618",{"2":{"81":1}}],["9362",{"2":{"50":1}}],["936887",{"2":{"22":1}}],["932986",{"2":{"21":1}}],["934129",{"2":{"20":1}}],["9",{"2":{"16":14,"17":2,"29":1,"32":1,"48":4,"58":4,"75":1}}],["96x71x19",{"2":{"53":1,"55":1,"66":1,"70":1}}],["96f0",{"2":{"53":1,"55":1,"66":1}}],["9682",{"2":{"45":1,"46":1}}],["960",{"2":{"17":1}}],["96757",{"2":{"17":1}}],["963886",{"2":{"17":1}}],["96",{"2":{"8":1,"9":1,"35":6,"57":2,"70":1}}],["840426",{"2":{"81":1}}],["84",{"2":{"60":1}}],["834933",{"2":{"81":1}}],["83",{"2":{"60":1}}],["831314",{"2":{"17":1}}],["82",{"2":{"60":1}}],["823196",{"2":{"22":1}}],["89",{"2":{"52":4,"53":2,"55":1,"56":2,"57":1,"58":1,"59":5,"60":1,"66":1,"70":1,"90":2}}],["8984",{"2":{"50":1}}],["89237",{"2":{"50":1}}],["891881",{"2":{"22":1}}],["899311",{"2":{"20":1}}],["861755",{"2":{"81":1}}],["86",{"2":{"60":1}}],["86457",{"2":{"50":1}}],["864794",{"2":{"21":1}}],["865549",{"2":{"21":1}}],["884596",{"2":{"81":1}}],["88",{"2":{"30":1,"52":4,"60":1,"81":1,"90":2}}],["885421",{"2":{"21":1}}],["880753",{"2":{"17":1}}],["85",{"2":{"60":1,"92":1,"93":1}}],["850",{"2":{"50":1}}],["85ºn",{"2":{"35":1}}],["85881",{"2":{"21":1}}],["859051",{"2":{"21":1}}],["851063",{"2":{"21":1}}],["85714",{"2":{"17":1}}],["81",{"2":{"24":1,"60":1}}],["81669",{"2":{"21":1}}],["810377",{"2":{"21":1}}],["818753",{"2":{"20":1}}],["877461",{"2":{"72":2}}],["87705",{"2":{"50":1}}],["877062",{"2":{"17":1}}],["87",{"2":{"60":1}}],["875862",{"2":{"22":1}}],["874109",{"2":{"21":1}}],["879286",{"2":{"17":1}}],["879515",{"2":{"17":1}}],["8",{"2":{"16":12,"17":2,"29":1,"32":1,"53":2,"55":1,"56":2,"66":1,"70":1,"84":1}}],["80759",{"2":{"50":1}}],["800129",{"2":{"81":1}}],["800",{"2":{"28":3,"29":1,"32":1}}],["809426",{"2":{"17":1}}],["80",{"2":{"16":1,"35":2}}],["v",{"2":{"53":1,"55":1,"66":1,"70":1}}],["v1",{"2":{"53":2,"55":2,"66":2,"70":2,"80":1}}],["v20190710",{"2":{"52":1,"90":2}}],["vol",{"2":{"53":1,"55":1,"66":1,"70":1}}],["volume",{"2":{"41":4}}],["voilà",{"2":{"41":1}}],["video",{"2":{"86":1}}],["videos",{"2":{"86":1}}],["visualization",{"2":{"37":1}}],["vice",{"2":{"19":1}}],["view",{"2":{"17":1,"81":1}}],["version",{"2":{"52":1,"53":1,"55":1,"66":1,"70":1,"82":2,"90":1}}],["versa",{"2":{"19":1}}],["verify",{"2":{"49":1,"72":1}}],["very",{"2":{"13":1,"37":1,"62":1}}],["vector",{"0":{"17":1},"2":{"17":4,"29":1,"45":1,"47":1,"48":2,"49":3,"50":2,"60":1,"62":1,"74":2,"75":3}}],["val",{"2":{"29":2,"60":1}}],["vals",{"2":{"17":1}}],["value",{"2":{"12":1,"14":3,"16":2,"36":1,"53":1,"56":2,"57":3,"58":3,"59":5,"74":4,"75":1}}],["values=ds1",{"2":{"37":1}}],["values",{"0":{"29":1,"72":1},"2":{"9":1,"17":2,"23":1,"24":2,"27":2,"28":1,"29":1,"35":3,"37":4,"41":2,"58":1,"60":2,"62":1,"63":1,"71":1,"72":3,"74":9,"81":1,"90":1}}],["vararg",{"2":{"75":2}}],["varoables",{"2":{"74":1}}],["variant",{"2":{"52":1,"90":1}}],["variable=at",{"2":{"81":1}}],["variable",{"0":{"5":1,"38":1,"39":1,"40":1},"1":{"39":1,"40":1},"2":{"5":1,"9":3,"35":3,"41":5,"52":1,"71":2,"74":4,"75":7,"81":3,"83":1,"84":1,"85":1,"90":1}}],["variables=at",{"2":{"36":2}}],["variables",{"0":{"6":1,"34":1,"35":1},"2":{"4":5,"5":4,"6":2,"9":2,"19":1,"25":1,"30":2,"33":1,"34":2,"35":11,"39":1,"40":4,"41":6,"52":4,"53":1,"55":1,"63":1,"64":1,"66":1,"70":4,"71":1,"74":2,"90":4}}],["varlist",{"2":{"40":2}}],["var2=var2",{"2":{"34":1}}],["var2",{"2":{"30":2,"34":3,"36":1}}],["var1=var1",{"2":{"34":1}}],["var1",{"2":{"30":2,"34":3,"36":1}}],["var",{"2":{"9":2,"83":2,"84":2,"85":2}}],["uv",{"2":{"94":1}}],["u",{"2":{"84":1}}],["up",{"2":{"74":1}}],["updating",{"2":{"72":1}}],["updates",{"0":{"82":1}}],["updated",{"2":{"72":1}}],["update",{"0":{"72":1},"2":{"72":2,"74":1}}],["ucar",{"2":{"53":1,"55":1,"63":1,"66":1}}],["urls",{"2":{"51":1}}],["url",{"2":{"44":1,"52":1}}],["unpermuted",{"2":{"75":2}}],["unpractical",{"2":{"44":1}}],["underlying",{"2":{"74":1,"75":1,"82":1}}],["unlike",{"2":{"64":1}}],["unique",{"2":{"84":1}}],["unidata",{"2":{"53":1,"55":1,"63":1,"66":1}}],["units",{"2":{"52":1,"53":2,"56":4,"57":6,"58":6,"59":10}}],["unitrange",{"2":{"45":2,"46":2,"50":6}}],["union",{"2":{"14":2,"16":4,"17":1,"36":1,"37":2,"53":1,"56":2,"57":3,"58":3,"59":5,"71":2,"72":1}}],["unweighted",{"2":{"45":1,"50":1}}],["unordered",{"2":{"41":4,"45":2,"46":1,"47":1,"48":2,"49":2,"50":3}}],["unnecessary",{"2":{"17":1}}],["unchanged",{"2":{"13":1}}],["usually",{"2":{"52":1,"62":2,"63":2}}],["usual",{"2":{"45":1}}],["us",{"2":{"17":1}}],["useable",{"2":{"74":1}}],["uses",{"2":{"37":1}}],["used",{"2":{"17":1,"18":1,"32":1,"55":1,"60":1,"61":1,"62":1,"65":1,"74":4,"75":3}}],["userguide",{"2":{"77":2}}],["users",{"2":{"75":1}}],["user",{"2":{"10":2,"12":1,"13":1,"18":1,"24":3,"25":1,"75":1}}],["use",{"0":{"37":1},"2":{"0":1,"8":1,"9":1,"10":4,"13":1,"18":2,"27":2,"32":1,"34":1,"35":1,"36":1,"37":2,"41":2,"42":1,"44":1,"46":1,"59":2,"64":1,"71":1,"74":3,"75":1,"86":1,"88":1,"90":2}}],["useful",{"2":{"0":1,"64":1}}],["using",{"2":{"0":1,"8":1,"9":1,"10":1,"16":2,"17":2,"18":7,"22":1,"27":1,"28":2,"30":1,"32":2,"34":2,"35":2,"36":1,"37":1,"41":1,"42":4,"52":2,"53":3,"54":2,"55":2,"57":3,"58":2,"66":2,"70":1,"71":3,"82":1,"83":2,"84":1,"90":3}}],["+proj=moll",{"2":{"93":1}}],["+",{"2":{"12":2,"13":1,"16":2,"83":1,"92":1}}],["kwargs",{"2":{"74":4,"75":2}}],["k",{"2":{"41":5,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["key",{"2":{"74":1}}],["keyword",{"2":{"70":1,"74":6,"75":2}}],["keyset",{"2":{"41":1}}],["keys",{"2":{"41":7,"74":1}}],["keylist",{"2":{"40":1}}],["keeps",{"2":{"13":1}}],["keep",{"2":{"0":1,"75":1}}],["kb",{"2":{"10":1,"12":1,"13":1,"14":1,"16":2,"17":1,"21":1,"24":2,"27":1,"30":1,"32":4,"36":3,"37":1,"57":1,"58":3,"59":5,"81":1,"84":1}}],["↗",{"2":{"10":1,"12":1,"13":1,"16":2,"17":1,"21":2,"24":3,"25":1,"27":3,"30":1,"32":5,"34":2,"36":3,"45":1,"52":2,"53":2,"55":1,"56":2,"58":3,"59":5,"66":1,"70":2,"71":2,"81":1,"90":1}}],["├─────────────────────────┴──────────────────────────",{"2":{"32":1}}],["├─────────────────────────┴─────────────────────────────────────",{"2":{"81":1}}],["├─────────────────────────┴──────────────────────────────────────────────",{"2":{"29":1,"37":1}}],["├─────────────────────────┴──────────────────────────────────────",{"2":{"28":1}}],["├─────────────────────────┴──────────────────────────────────",{"2":{"22":2}}],["├─────────────────────────┴────────────────────────────────",{"2":{"9":1}}],["├──────────────────────────┴────────────────────────────",{"2":{"21":1}}],["├──────────────────────────┴────────────────────────────────────",{"2":{"20":1}}],["├──────────────────────────┴─────────────────────────────────────────────",{"2":{"17":1,"32":1}}],["├────────────────────────────┴───────────────────────────────────────────",{"2":{"32":2}}],["├────────────────────────────┴──────────────────────────",{"2":{"21":1}}],["├─────────────────────────────┴──────────────────────────────────",{"2":{"24":1}}],["├─────────────────────────────┴──────────────────────────────────────────",{"2":{"16":1,"27":1}}],["├───────────────────────────────┴────────────────────────────────────────",{"2":{"49":1}}],["├──────────────────────────────────┴─────────────────────────────────────",{"2":{"84":1}}],["├────────────────────────────────────┴───────────────────────────────────",{"2":{"52":1}}],["├──────────────────────────────────────────┴─────────────────────────────",{"2":{"17":1,"37":1}}],["├─────────────────────────────────────────────┴─────────────────",{"2":{"57":1}}],["├───────────────────────────────────────────────┴────────────────────────",{"2":{"37":1,"58":1,"59":5}}],["├───────────────────────────────────────────────",{"2":{"32":1}}],["├────────────────────────────────────────────────",{"2":{"32":1}}],["├──────────────────────────────────────────────────┴─────────────────────",{"2":{"45":1}}],["├──────────────────────────────────────────────────",{"2":{"21":1}}],["├───────────────────────────────────────────────────",{"2":{"21":2}}],["├─────────────────────────────────────────────────────",{"2":{"9":1,"21":1}}],["├───────────────────────────────────────────────────────",{"2":{"22":1}}],["├────────────────────────────────────────────────────────",{"2":{"22":2}}],["├──────────────────────────────────────────────────────────",{"2":{"20":1,"81":1}}],["├───────────────────────────────────────────────────────────",{"2":{"20":1,"24":1,"28":1,"81":1}}],["├────────────────────────────────────────────────────────────",{"2":{"8":1,"24":1,"28":1}}],["├──────────────────────────────────────────────────────────────────",{"2":{"45":1,"48":1}}],["├───────────────────────────────────────────────────────────────────",{"2":{"10":1,"12":1,"13":1,"14":2,"16":5,"17":2,"24":1,"27":1,"28":2,"29":1,"30":1,"32":4,"36":3,"37":3,"48":1,"52":1,"53":1,"56":2,"57":2,"58":3,"59":5,"71":1,"81":1,"84":1}}],["├─────────────────────────────────────────────────────────────────────",{"2":{"57":1}}],["├─────────────────────────────────────────────────────────────────────┴",{"2":{"57":1}}],["├────────────────────────────────────────────────────────────────────────",{"2":{"45":1,"46":1,"48":1,"49":1,"50":3}}],["├────────────────────────────────────────────────────────────────────",{"2":{"10":1,"12":1,"13":1,"14":2,"16":5,"17":3,"24":1,"27":1,"28":2,"29":1,"30":1,"32":4,"36":3,"37":3,"45":2,"46":1,"48":3,"49":2,"50":3,"52":1,"53":1,"56":2,"57":2,"58":3,"59":5,"71":1,"81":1,"84":1}}],["├─────────────────────────────────────────────────────────────",{"2":{"8":1}}],["├──────────────────────────────────────────────────────",{"2":{"9":1}}],["├────────────────────────────────────────────────┴───────────────────────",{"2":{"14":1,"48":1,"53":1,"56":2,"57":2}}],["├──────────────────────────────────────────────┴─────────────────────────",{"2":{"16":2,"36":1,"58":2}}],["├───────────────────────────────────────────┴────────────────────────────",{"2":{"14":1,"71":1}}],["├────────────────────────────────┴───────────────────────────────────────",{"2":{"30":1,"81":1}}],["├────────────────────────────────┴────────────────────────────────",{"2":{"8":1}}],["├──────────────────────────────┴─────────────────────────────────────────",{"2":{"10":1,"12":1,"13":1,"16":2,"17":1,"24":1,"36":2,"48":1}}],["├───────────────────────────┴────────────────────────────────────────────",{"2":{"17":1,"28":2,"32":1}}],["╭────────────────────────────╮",{"2":{"21":1,"32":2}}],["╭─────────────────────────────╮",{"2":{"16":1,"24":1,"27":1}}],["╭───────────────────────────────╮",{"2":{"49":1}}],["╭──────────────────────────────────╮",{"2":{"84":1}}],["╭────────────────────────────────────╮",{"2":{"52":1}}],["╭──────────────────────────────────────────╮",{"2":{"17":1,"37":1}}],["╭─────────────────────────────────────────────╮",{"2":{"57":1}}],["╭──────────────────────────────────────────────────────────────────────────────╮",{"2":{"45":1,"46":1,"48":1,"49":1,"50":3}}],["╭──────────────────────────────────────────────────╮",{"2":{"45":1}}],["╭────────────────────────────────────────────────╮",{"2":{"14":1,"48":1,"53":1,"56":2,"57":2}}],["╭───────────────────────────────────────────────╮",{"2":{"37":1,"58":1,"59":5}}],["╭──────────────────────────────────────────────╮",{"2":{"16":2,"36":1,"58":2}}],["╭───────────────────────────────────────────╮",{"2":{"14":1,"71":1}}],["╭────────────────────────────────╮",{"2":{"8":1,"30":1,"81":1}}],["╭──────────────────────────────╮",{"2":{"10":1,"12":1,"13":1,"16":2,"17":1,"24":1,"36":2,"48":1}}],["╭───────────────────────────╮",{"2":{"17":1,"28":2,"32":1}}],["╭──────────────────────────╮",{"2":{"17":1,"20":1,"21":1,"32":1}}],["╭─────────────────────────╮",{"2":{"9":1,"22":2,"28":1,"29":1,"32":1,"37":1,"81":1}}],["0e8",{"2":{"74":1}}],["0f20",{"2":{"52":1,"53":2,"56":4,"57":6,"58":6,"59":10}}],["0f32",{"2":{"16":2}}],["08887819459347718",{"2":{"84":1}}],["0881536",{"2":{"72":2}}],["08292452722604059",{"2":{"84":1}}],["0845415",{"2":{"81":1}}],["08",{"2":{"48":1}}],["0804585",{"2":{"20":1}}],["091767",{"2":{"81":1}}],["0910572",{"2":{"20":1}}],["0951123",{"2":{"72":2}}],["09",{"2":{"48":1}}],["0024136950999947768",{"2":{"84":1}}],["00722034",{"2":{"50":1}}],["00709111",{"2":{"50":1}}],["00684233",{"2":{"50":1}}],["00693713",{"2":{"50":1}}],["00990356",{"2":{"50":1}}],["00939122",{"2":{"21":1}}],["0057",{"2":{"50":1}}],["00388",{"2":{"50":1}}],["00",{"2":{"41":16,"48":4,"52":9,"53":8,"55":4,"56":8,"57":8,"58":12,"59":20,"66":4,"70":4,"90":5}}],["0ºe",{"2":{"35":1}}],["05058428806431179",{"2":{"84":1}}],["0504114",{"2":{"17":1}}],["05254540122374988",{"2":{"84":1}}],["05846",{"2":{"50":1}}],["0589974",{"2":{"22":1}}],["0537",{"2":{"45":1,"46":1}}],["0536221",{"2":{"21":1}}],["05",{"2":{"32":3}}],["03315745304050341",{"2":{"84":1}}],["03361",{"2":{"50":1}}],["0328466",{"2":{"21":1}}],["03",{"2":{"21":1}}],["0391939",{"2":{"20":1}}],["023779014536715975",{"2":{"84":1}}],["02034926101455332",{"2":{"84":1}}],["02",{"2":{"52":1}}],["027089",{"2":{"20":1}}],["0264902",{"2":{"20":1}}],["0720417",{"2":{"81":1}}],["07",{"2":{"52":2,"90":1}}],["0750832",{"2":{"22":1}}],["0764503",{"2":{"22":1}}],["0746545",{"2":{"20":1}}],["0701065",{"2":{"17":1}}],["0462624",{"2":{"81":1}}],["0465",{"2":{"50":1}}],["0450445",{"2":{"17":1}}],["0443643",{"2":{"17":1}}],["0641324",{"2":{"72":2}}],["0645807",{"2":{"17":1}}],["0620288",{"2":{"72":2}}],["0625",{"2":{"52":2,"90":1}}],["06755",{"2":{"50":1}}],["0696778",{"2":{"17":1}}],["014073923933364077",{"2":{"84":1}}],["010730686374072013",{"2":{"84":1}}],["01t03",{"2":{"52":2,"90":1}}],["01t00",{"2":{"41":4,"52":2,"90":1}}],["0178074",{"2":{"50":1}}],["011564383769804764",{"2":{"84":1}}],["0115514",{"2":{"50":1}}],["0117519",{"2":{"50":1}}],["0127077",{"2":{"50":1}}],["0123091",{"2":{"50":1}}],["0121037",{"2":{"50":1}}],["019016",{"2":{"50":1}}],["018571",{"2":{"50":1}}],["0182373",{"2":{"50":1}}],["0180572",{"2":{"50":1}}],["0183003",{"2":{"50":1}}],["018",{"2":{"45":1,"46":1}}],["01",{"2":{"10":6,"12":3,"13":3,"14":3,"16":12,"17":9,"18":3,"24":9,"25":3,"32":22,"34":8,"35":11,"41":8,"52":5,"53":4,"55":2,"56":4,"57":6,"58":6,"59":10,"66":2,"70":2,"83":2,"84":4,"90":5}}],["0",{"2":{"8":1,"9":1,"10":6,"11":2,"12":6,"13":6,"14":7,"16":303,"17":75,"20":36,"21":36,"22":45,"24":12,"25":6,"28":3,"29":1,"30":9,"32":1,"35":4,"36":27,"37":11,"48":2,"49":40,"50":19,"52":7,"53":10,"55":6,"56":8,"57":6,"58":14,"59":20,"60":6,"66":6,"69":1,"70":6,"71":1,"72":40,"74":2,"75":1,"81":80,"82":1,"83":2,"84":19,"85":1,"90":4,"92":2,"93":2,"94":2}}],["┤",{"2":{"8":2,"9":2,"10":2,"12":2,"13":2,"14":4,"16":10,"17":5,"20":2,"21":4,"22":3,"24":4,"27":2,"28":6,"29":2,"30":2,"32":10,"36":6,"37":6,"45":4,"46":2,"48":6,"49":3,"50":6,"52":2,"53":2,"56":4,"57":5,"58":6,"59":10,"71":2,"81":4,"84":2}}],["┐",{"2":{"8":1,"9":1,"10":1,"12":1,"13":1,"14":2,"16":5,"17":4,"20":1,"21":2,"22":2,"24":2,"27":1,"28":3,"29":1,"30":1,"32":5,"36":3,"37":3,"45":1,"48":2,"49":1,"52":1,"53":1,"56":2,"57":4,"58":3,"59":5,"71":1,"81":2,"84":1}}],["│",{"2":{"8":2,"9":2,"10":2,"12":2,"13":2,"14":4,"16":10,"17":8,"20":2,"21":4,"22":4,"24":4,"27":2,"28":6,"29":2,"30":2,"32":10,"36":6,"37":6,"45":4,"46":2,"48":6,"49":4,"50":6,"52":2,"53":2,"56":4,"57":6,"58":6,"59":10,"71":2,"81":4,"84":2}}],["723246",{"2":{"81":1}}],["72",{"2":{"60":1}}],["728649",{"2":{"21":1}}],["788957",{"2":{"81":1}}],["788483",{"2":{"17":1}}],["783796",{"2":{"81":1}}],["78",{"2":{"58":1,"60":1}}],["708253",{"2":{"81":1}}],["70",{"2":{"58":3,"60":1}}],["79",{"2":{"53":2,"55":1,"56":2,"57":2,"58":4,"59":5,"60":1,"66":1,"70":1}}],["79502",{"2":{"50":1}}],["795153",{"2":{"20":1}}],["730",{"2":{"85":1}}],["7341",{"2":{"50":1}}],["73",{"2":{"50":1,"60":1}}],["75783",{"2":{"81":1}}],["75",{"2":{"60":1}}],["7593",{"2":{"50":1}}],["75891",{"2":{"50":1}}],["758648",{"2":{"21":1}}],["712428",{"2":{"81":1}}],["71243",{"2":{"81":1}}],["717",{"2":{"59":5}}],["71",{"2":{"58":1,"60":1}}],["7158",{"2":{"45":1,"46":1}}],["7119",{"2":{"45":1,"46":1}}],["71429",{"2":{"17":2}}],["776623",{"2":{"81":1}}],["77687",{"2":{"50":1}}],["773651",{"2":{"81":1}}],["771479",{"2":{"72":2}}],["77",{"2":{"60":1}}],["77587",{"2":{"50":1}}],["775785",{"2":{"22":1}}],["777976",{"2":{"20":1}}],["76",{"2":{"60":1}}],["769308",{"2":{"22":1}}],["764827",{"2":{"21":1}}],["74",{"2":{"60":1}}],["747443",{"2":{"22":1}}],["748974",{"2":{"22":1}}],["743847",{"2":{"21":1}}],["745998",{"2":{"17":1}}],["7",{"2":{"8":1,"16":10,"17":1,"21":1,"24":1,"29":1,"52":1,"90":1}}],["→",{"2":{"4":1,"5":1,"6":1,"9":1,"10":1,"12":1,"13":1,"14":1,"16":2,"17":6,"20":1,"21":3,"22":3,"24":3,"25":1,"27":3,"28":3,"29":1,"30":1,"32":6,"34":2,"35":2,"36":3,"37":2,"40":2,"41":4,"45":1,"52":2,"53":2,"55":1,"56":2,"57":1,"58":3,"59":5,"66":1,"70":2,"71":2,"81":2,"90":1}}],["↓",{"2":{"4":3,"5":3,"6":1,"8":1,"9":1,"10":1,"12":1,"13":1,"14":2,"16":5,"17":6,"20":1,"21":3,"22":3,"24":3,"25":1,"27":3,"28":3,"29":1,"30":1,"32":6,"34":2,"35":8,"36":3,"37":3,"39":1,"40":3,"41":4,"45":3,"46":1,"48":4,"49":2,"50":3,"52":2,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":2,"71":2,"81":2,"84":2,"90":1}}],["451794",{"2":{"81":1}}],["45×170×24",{"2":{"59":5}}],["48",{"2":{"81":1}}],["48367",{"2":{"50":1}}],["480",{"2":{"37":1}}],["4802525933892837",{"2":{"11":1}}],["497997",{"2":{"81":1}}],["498668",{"2":{"72":2}}],["49909",{"2":{"50":1}}],["4947",{"2":{"50":1}}],["409423",{"2":{"81":1}}],["40",{"2":{"35":2}}],["400935",{"2":{"81":1}}],["400",{"2":{"20":1,"71":1,"83":1,"85":1}}],["466542",{"2":{"81":1}}],["46506",{"2":{"50":1}}],["46",{"2":{"30":1,"81":1}}],["460901",{"2":{"21":1}}],["433215",{"2":{"81":1}}],["43254",{"2":{"50":1}}],["4325",{"2":{"45":1,"46":1}}],["434868",{"2":{"22":1}}],["438166",{"2":{"21":1}}],["4198",{"2":{"50":1}}],["41241",{"2":{"50":1}}],["41049",{"2":{"50":1}}],["410173",{"2":{"21":1}}],["41634",{"2":{"50":1}}],["417033",{"2":{"17":1}}],["478507",{"2":{"20":1}}],["44",{"2":{"32":1,"36":3}}],["448599",{"2":{"21":1}}],["442589",{"2":{"20":1}}],["440296",{"2":{"17":1}}],["4×30",{"2":{"17":1}}],["424205",{"2":{"81":1}}],["423459",{"2":{"21":1}}],["42857",{"2":{"17":2}}],["42",{"2":{"11":3}}],["4",{"2":{"4":4,"5":4,"16":4,"17":9,"22":1,"29":1,"30":1,"35":6,"45":2,"46":1,"47":1,"48":2,"49":2,"50":4,"71":3,"72":2,"81":3,"83":1,"85":1}}],["3d",{"0":{"94":1}}],["3hr",{"2":{"52":2,"90":3}}],["344472",{"2":{"81":1}}],["342288",{"2":{"81":1}}],["34218",{"2":{"50":1}}],["34818",{"2":{"50":1}}],["34832",{"2":{"50":1}}],["34549",{"2":{"50":1}}],["324527",{"2":{"81":1}}],["324908",{"2":{"17":1}}],["32555",{"2":{"50":1}}],["3252",{"2":{"45":1,"46":1}}],["32149",{"2":{"50":1}}],["3×20",{"2":{"37":1}}],["384×192×251288",{"2":{"52":1}}],["3866",{"2":{"50":1}}],["38364",{"2":{"50":1}}],["3835",{"2":{"45":1,"46":1}}],["38",{"2":{"32":1,"58":3}}],["37",{"2":{"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1}}],["372",{"2":{"50":1}}],["372063",{"2":{"22":1}}],["37878",{"2":{"50":1}}],["371974",{"2":{"17":1}}],["33565",{"2":{"50":1}}],["333059",{"2":{"21":1}}],["339863",{"2":{"20":1}}],["312",{"2":{"50":1}}],["31753",{"2":{"50":1}}],["317333",{"2":{"21":1}}],["3169",{"2":{"50":1}}],["3188",{"2":{"50":1}}],["318029",{"2":{"20":1}}],["31",{"2":{"32":2,"34":1,"35":1,"83":1,"84":2}}],["310425",{"2":{"21":1}}],["366",{"2":{"85":1}}],["365×1",{"2":{"84":1}}],["365",{"2":{"84":1,"85":4}}],["365121",{"2":{"20":1}}],["36126",{"2":{"50":1}}],["36142",{"2":{"50":1}}],["36836",{"2":{"50":1}}],["369",{"2":{"35":1}}],["36",{"2":{"32":1,"34":2,"35":1,"48":1}}],["3600",{"2":{"32":1,"34":2}}],["364872",{"2":{"20":1}}],["350231",{"2":{"81":1}}],["358056",{"2":{"81":1}}],["358337",{"2":{"81":1}}],["358242",{"2":{"72":2}}],["35700351866494",{"2":{"52":4,"90":2}}],["35432",{"2":{"50":1}}],["35483",{"2":{"50":1}}],["354703",{"2":{"17":1}}],["359363",{"2":{"72":2}}],["359023",{"2":{"72":2}}],["359",{"2":{"35":1,"52":2,"53":2,"55":1,"56":2,"57":1,"60":2,"66":1,"70":1,"90":1}}],["351172",{"2":{"20":1}}],["35",{"2":{"10":1,"12":1,"13":1,"17":1,"24":1}}],["307f8f0e584a39a050c042849004e6a2bd674f99",{"2":{"54":1}}],["3069",{"2":{"50":1}}],["306701",{"2":{"20":1}}],["30018",{"2":{"50":1}}],["30142",{"2":{"50":1}}],["30113",{"2":{"50":1}}],["305112",{"2":{"22":1}}],["30×15×10",{"2":{"16":1}}],["30×10×15",{"2":{"10":1,"12":1,"13":1,"17":1,"24":1}}],["30",{"2":{"10":3,"12":1,"13":1,"14":2,"16":5,"17":5,"18":2,"21":10,"24":4,"25":2,"50":2,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"90":1}}],["397222",{"2":{"81":1}}],["39914",{"2":{"81":1}}],["394272",{"2":{"72":2}}],["396465",{"2":{"20":1}}],["391744",{"2":{"20":1}}],["39",{"2":{"10":1,"16":3,"28":1,"30":1,"32":1,"34":1,"35":1,"36":2,"50":1,"55":1,"65":1,"74":2,"77":4,"84":3}}],["3",{"2":{"4":8,"5":8,"6":10,"10":1,"11":3,"12":3,"13":2,"16":4,"17":6,"21":2,"22":1,"24":3,"27":5,"29":1,"32":4,"36":4,"37":5,"41":1,"45":2,"50":31,"52":1,"53":1,"56":2,"58":4,"59":5,"70":1,"71":3,"74":1,"81":3,"83":2}}],["zoom",{"2":{"94":1}}],["zopen",{"2":{"52":1,"72":1,"90":1}}],["zeros",{"2":{"71":3,"84":1}}],["z",{"2":{"4":2,"5":3,"6":2,"70":2}}],["zarray",{"2":{"72":1}}],["zarr",{"0":{"52":1,"67":1,"89":1},"2":{"0":1,"2":2,"4":2,"5":2,"6":2,"16":5,"18":1,"22":1,"52":3,"67":5,"69":3,"70":4,"71":6,"72":2,"74":2,"75":2,"90":1}}],["xticklabelalign",{"2":{"83":1,"85":1}}],["xticklabelrotation",{"2":{"83":1,"85":1}}],["xlabel=",{"2":{"83":1,"85":1}}],["xx",{"2":{"53":1,"55":1,"66":1,"70":1}}],["xarray",{"2":{"43":1,"44":1}}],["xin",{"2":{"17":3,"36":3}}],["x26",{"2":{"17":12,"35":12}}],["x3c",{"2":{"17":12,"35":4}}],["xout",{"2":{"16":2,"17":3}}],["x",{"2":{"4":2,"5":3,"6":2,"13":2,"21":4,"22":3,"36":4,"45":2,"46":1,"50":3,"62":1,"72":2,"75":1,"81":5,"83":1,"84":6}}],["ndata",{"2":{"92":2,"93":1,"94":1}}],["ndays",{"2":{"84":4}}],["nlon",{"2":{"92":2,"93":1}}],["npy",{"2":{"83":2,"84":2}}],["ntuple",{"2":{"75":2}}],["ntr",{"2":{"75":1}}],["nthreads",{"2":{"74":2}}],["nin",{"2":{"75":2}}],["nvalid",{"2":{"74":1}}],["nbsp",{"2":{"69":1,"74":24,"75":24}}],["n",{"2":{"61":1,"74":3}}],["n256",{"2":{"50":1}}],["nan",{"2":{"44":1,"45":48,"46":48,"50":384}}],["name=cube",{"2":{"74":1}}],["namedtuple",{"2":{"74":1,"75":3}}],["named",{"2":{"55":1,"57":1,"58":1,"62":1,"74":2,"82":1}}],["names",{"0":{"27":1,"38":1,"40":1},"1":{"28":1,"39":1,"40":1},"2":{"24":2,"41":1,"47":1,"62":2,"74":2,"75":1}}],["namely",{"2":{"16":1}}],["name",{"0":{"39":1},"2":{"2":1,"50":1,"52":3,"53":4,"56":8,"57":12,"58":12,"59":20,"65":1,"71":2,"74":6,"75":5,"81":1}}],["nc",{"2":{"44":2,"53":2,"55":2,"66":2,"68":2}}],["number",{"2":{"43":1,"48":1,"74":2,"75":1,"84":1}}],["numbers",{"2":{"10":1,"81":1}}],["nout",{"2":{"75":2}}],["normal",{"2":{"74":1,"94":1}}],["nometadata",{"2":{"45":3,"46":2,"48":1,"49":1,"50":10}}],["november",{"2":{"53":1,"55":1,"66":1,"70":1}}],["nov",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["nonmissingtype",{"2":{"75":1}}],["none",{"2":{"35":2,"40":1,"41":1,"52":1,"70":1,"90":1}}],["non",{"2":{"18":1,"74":1,"75":1,"83":1}}],["now",{"2":{"16":3,"17":1,"28":1,"30":1,"32":1,"37":1,"41":1,"45":1,"46":1,"48":1,"50":1,"71":2,"72":1,"78":1}}],["no",{"2":{"14":1,"22":1,"31":1,"71":1,"74":1,"75":1}}],["nothing",{"2":{"50":3,"54":1,"69":1,"74":1,"75":1}}],["notation",{"2":{"32":1,"59":1}}],["note",{"2":{"9":1,"13":1,"16":4,"17":1,"28":1,"35":1,"46":1,"71":1,"74":1,"75":1}}],["not",{"0":{"35":1},"2":{"0":1,"1":1,"13":1,"31":1,"35":3,"41":2,"44":1,"71":2,"74":2,"75":3}}],["neighbour",{"2":{"74":1}}],["neighboring",{"2":{"13":1}}],["needed",{"2":{"74":1}}],["need",{"2":{"72":1,"74":1,"75":1,"77":1}}],["near",{"2":{"52":2,"59":1,"90":1}}],["next",{"2":{"36":1,"37":1,"47":1,"78":2}}],["netcdf",{"0":{"53":1,"68":1},"2":{"22":1,"42":1,"53":4,"55":2,"63":3,"66":2,"68":3,"69":1,"74":1}}],["necessary",{"2":{"16":1,"43":1,"44":1,"72":1,"75":4}}],["new",{"0":{"9":1},"2":{"10":1,"12":1,"16":1,"24":1,"27":1,"28":3,"44":1,"47":1,"64":1,"69":1,"70":1,"71":1,"74":5,"75":4,"77":6,"84":1}}],["bits",{"2":{"74":2}}],["big",{"2":{"62":1}}],["black",{"2":{"85":1}}],["blocks",{"2":{"74":1}}],["blue",{"2":{"63":1}}],["bonito",{"2":{"94":1}}],["boundaries",{"2":{"75":1}}],["bounds",{"2":{"74":1}}],["bool=true",{"2":{"75":1}}],["bool=false",{"2":{"74":1,"75":1}}],["bool",{"2":{"75":6}}],["boolean",{"2":{"74":3}}],["bold",{"2":{"50":1}}],["bwr",{"2":{"50":1}}],["b`",{"2":{"32":1}}],["brightness",{"2":{"62":1,"63":1}}],["brings",{"2":{"75":1}}],["bring",{"2":{"29":1}}],["broad",{"2":{"87":1}}],["broadcasts",{"2":{"75":1}}],["broadcast",{"2":{"45":1,"50":1}}],["broadcasted",{"2":{"16":2,"74":1,"75":1}}],["brown",{"2":{"85":1}}],["browser",{"2":{"78":1}}],["broken",{"2":{"54":1}}],["branch",{"2":{"52":1,"90":1}}],["bug",{"2":{"76":1}}],["bundle",{"2":{"63":1}}],["build",{"0":{"78":1},"2":{"27":1,"41":1,"78":1}}],["but",{"0":{"35":1},"2":{"8":1,"16":2,"27":1,"28":2,"35":2,"41":2,"57":1,"58":1,"74":2}}],["b",{"2":{"17":13,"40":2,"59":2}}],["backgroundcolor=",{"2":{"94":1}}],["back",{"2":{"74":1}}],["backendlist",{"2":{"74":1}}],["backend",{"2":{"69":2,"74":8}}],["backend=",{"2":{"2":1,"16":2,"70":1}}],["based",{"0":{"89":1},"2":{"75":1}}],["base",{"0":{"20":1},"2":{"4":4,"5":4,"6":2,"20":4,"24":3,"27":9,"28":6,"39":1,"40":5,"71":6,"75":1,"81":2}}],["by=",{"2":{"37":2,"74":2}}],["bytes",{"2":{"8":1,"9":1,"14":1,"16":3,"17":1,"20":1,"22":1,"28":3,"29":1,"32":1,"37":2,"48":1,"57":2,"71":1,"81":1}}],["by",{"0":{"4":1,"5":1},"2":{"2":1,"10":2,"14":1,"16":1,"17":1,"23":1,"24":1,"28":1,"31":1,"32":6,"35":2,"37":1,"43":1,"47":1,"48":1,"49":1,"50":1,"52":1,"62":3,"64":1,"65":1,"69":1,"72":2,"74":12,"75":6,"77":1,"78":1,"80":1,"84":1}}],["beware",{"2":{"86":1}}],["best",{"2":{"75":1,"88":1}}],["become",{"2":{"74":1}}],["because",{"2":{"1":1,"13":1,"14":1,"16":1}}],["before",{"2":{"71":1,"74":1,"78":1}}],["belonging",{"2":{"63":1}}],["belongs",{"2":{"17":1}}],["being",{"2":{"41":1}}],["been",{"2":{"35":1,"72":1}}],["between",{"2":{"21":1,"22":1,"32":1,"34":1,"35":2,"59":1,"74":1}}],["begin",{"2":{"18":1}}],["be",{"2":{"0":5,"2":1,"3":1,"4":1,"13":1,"15":1,"16":2,"17":1,"19":1,"32":1,"35":1,"36":1,"37":2,"41":1,"44":1,"52":2,"53":1,"54":1,"60":1,"62":1,"64":2,"69":1,"70":1,"71":1,"74":22,"75":9,"77":1,"82":1,"86":1,"90":1}}],["666752",{"2":{"72":2}}],["621626",{"2":{"81":1}}],["621891",{"2":{"72":2}}],["623244",{"2":{"72":2}}],["63006",{"2":{"50":1}}],["634033",{"2":{"20":1}}],["634789",{"2":{"17":1}}],["600",{"2":{"83":1,"85":1,"91":1,"92":1,"93":1}}],["60265",{"2":{"52":1,"90":1}}],["60918",{"2":{"50":1}}],["60175",{"2":{"50":1}}],["606617",{"2":{"20":1}}],["606578",{"2":{"17":1}}],["65105",{"2":{"50":1}}],["651427",{"2":{"21":1}}],["649498",{"2":{"81":1}}],["64976",{"2":{"50":1}}],["642",{"2":{"44":1}}],["645149",{"2":{"22":1}}],["682179",{"2":{"81":1}}],["689982",{"2":{"22":1}}],["680373",{"2":{"22":1}}],["6122",{"2":{"50":1}}],["61197",{"2":{"50":1}}],["611842",{"2":{"20":1}}],["619",{"2":{"45":1,"46":1}}],["613363",{"2":{"22":1}}],["695756",{"2":{"81":1}}],["698795",{"2":{"81":1}}],["69",{"2":{"52":1}}],["69085",{"2":{"50":1}}],["692366",{"2":{"22":1}}],["697013",{"2":{"17":1}}],["6×6×25",{"2":{"21":2}}],["6×2",{"2":{"9":1}}],["675918",{"2":{"17":1}}],["6",{"2":{"2":6,"4":6,"5":6,"6":6,"8":4,"9":5,"16":8,"17":1,"29":1,"32":1,"35":6,"52":1,"90":1}}],["1e8",{"2":{"75":1}}],["192",{"2":{"92":1}}],["19241",{"2":{"50":1}}],["19438512289805546",{"2":{"84":1}}],["198967",{"2":{"81":1}}],["1983",{"2":{"48":1}}],["1980",{"2":{"48":1}}],["197869",{"2":{"20":1}}],["19",{"2":{"16":16,"58":3,"59":5}}],["186312",{"2":{"81":1}}],["18583",{"2":{"50":1}}],["18892",{"2":{"50":1}}],["18434",{"2":{"50":1}}],["180×170",{"2":{"57":1}}],["180×170×24",{"2":{"53":1,"56":2}}],["180",{"2":{"35":2,"59":5,"92":1}}],["180ºe",{"2":{"35":1}}],["187958",{"2":{"20":1}}],["18",{"2":{"16":18}}],["14516899355200824",{"2":{"84":1}}],["14719040256891566",{"2":{"84":1}}],["1437",{"2":{"50":1}}],["14209",{"2":{"20":1}}],["14286",{"2":{"17":1}}],["14",{"2":{"16":20,"22":1}}],["138529",{"2":{"81":1}}],["138996",{"2":{"81":1}}],["137422",{"2":{"81":1}}],["1372",{"2":{"45":1,"46":1}}],["136",{"2":{"53":1,"55":1,"66":1,"70":1}}],["1363",{"2":{"45":1,"46":1}}],["13z",{"2":{"52":2,"90":1}}],["139694",{"2":{"17":1}}],["13",{"2":{"16":20,"22":1,"53":1,"55":1,"66":1,"70":1}}],["171584",{"2":{"81":1}}],["170",{"2":{"60":1}}],["179",{"2":{"59":5}}],["17434",{"2":{"50":1}}],["178559",{"2":{"81":1}}],["17852",{"2":{"50":1}}],["17863",{"2":{"50":1}}],["17647",{"2":{"50":1}}],["1762",{"2":{"45":1,"46":1}}],["17t00",{"2":{"48":1}}],["17",{"2":{"14":1,"16":22,"37":1,"58":1}}],["165788",{"2":{"81":1}}],["16581",{"2":{"50":1}}],["16t00",{"2":{"53":4,"55":2,"56":4,"57":4,"58":6,"59":10,"66":2,"70":2}}],["16t12",{"2":{"48":1}}],["1644",{"2":{"50":1}}],["16824",{"2":{"50":1}}],["16631",{"2":{"50":1}}],["16713",{"2":{"50":1}}],["16258",{"2":{"50":1}}],["162016",{"2":{"21":1}}],["16",{"2":{"10":1,"12":1,"13":1,"16":20,"17":1,"24":1,"53":2,"55":1,"56":2,"57":4,"58":3,"59":5,"66":1,"70":1}}],["15227894345884566",{"2":{"84":1}}],["152689",{"2":{"81":1}}],["159",{"2":{"58":1}}],["159973",{"2":{"21":1}}],["15644",{"2":{"50":1}}],["15532",{"2":{"50":1}}],["15752",{"2":{"20":1}}],["15×10×30",{"2":{"16":1}}],["15×10",{"2":{"16":2}}],["15",{"2":{"10":1,"16":25,"17":6,"18":1,"22":4,"24":1,"25":1,"30":2,"37":1,"81":1}}],["128",{"2":{"94":1}}],["12128913574359863",{"2":{"84":1}}],["12143335632591595",{"2":{"84":1}}],["122751",{"2":{"81":1}}],["1242",{"2":{"50":1}}],["12575",{"2":{"50":1}}],["123279",{"2":{"22":1}}],["1200",{"2":{"91":1,"92":1,"93":1}}],["120628",{"2":{"22":1}}],["120",{"2":{"16":1}}],["12",{"2":{"8":4,"16":20,"22":1,"32":10,"34":3,"35":4,"53":2,"55":1,"56":2,"57":2,"58":3,"59":5,"66":1,"70":1,"83":1,"84":2}}],["1=5",{"2":{"2":1}}],["11322047410821301",{"2":{"84":1}}],["113553",{"2":{"49":3}}],["119",{"2":{"57":1}}],["1181",{"2":{"50":1}}],["118396",{"2":{"22":1}}],["112319",{"2":{"49":12}}],["114815",{"2":{"49":6}}],["11",{"2":{"2":6,"4":6,"5":6,"6":6,"8":1,"16":18,"22":1,"45":4,"46":4,"50":4,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1}}],["1",{"2":{"2":12,"4":19,"5":20,"6":22,"8":5,"9":3,"10":8,"11":3,"12":7,"13":5,"14":6,"16":24,"17":34,"18":3,"20":1,"21":7,"22":6,"24":15,"25":4,"27":3,"28":3,"29":8,"30":8,"32":23,"34":10,"35":8,"36":15,"37":14,"39":1,"40":3,"41":1,"45":4,"46":2,"48":6,"49":11,"50":55,"52":4,"53":8,"55":4,"56":8,"57":13,"58":18,"59":15,"60":2,"66":4,"70":11,"71":2,"72":2,"75":1,"81":11,"83":2,"84":5,"85":5,"90":3,"92":4,"93":2,"94":5}}],["1095",{"2":{"84":1}}],["10989",{"2":{"49":6}}],["104073",{"2":{"81":1}}],["10mb",{"2":{"74":2}}],["1083",{"2":{"50":1}}],["108696",{"2":{"49":6}}],["100",{"2":{"35":7}}],["1000",{"2":{"0":1,"92":1,"93":1}}],["10×170×24",{"2":{"58":1}}],["10×10×24",{"2":{"58":2}}],["10×10×8",{"2":{"32":1}}],["10×10×12",{"2":{"32":1}}],["10×10×36",{"2":{"32":1}}],["10×10×5",{"2":{"27":1}}],["10×10",{"2":{"28":3,"29":1,"32":1}}],["10×15×20",{"2":{"36":1}}],["10×15",{"2":{"14":1,"17":2,"37":1,"81":1}}],["10×20×5",{"2":{"24":1}}],["103704",{"2":{"49":3}}],["103772",{"2":{"21":1}}],["103921",{"2":{"22":1}}],["10x15",{"2":{"17":1}}],["10",{"2":{"2":14,"4":16,"5":18,"6":17,"10":3,"12":1,"13":1,"14":1,"16":21,"17":15,"18":3,"20":2,"22":4,"24":6,"25":2,"27":8,"28":12,"29":5,"30":4,"32":16,"34":10,"36":3,"37":2,"39":2,"40":4,"52":1,"53":1,"56":2,"57":3,"58":6,"59":5,"70":2,"80":1,"81":3}}],["garbage",{"2":{"75":1}}],["gc",{"2":{"75":2}}],["gt",{"2":{"74":1,"75":3,"78":1}}],["gdalworkshop",{"2":{"54":1}}],["gdal",{"0":{"54":1},"2":{"54":1}}],["gb",{"2":{"52":1}}],["gn",{"2":{"52":1,"90":2}}],["gs",{"2":{"52":1,"90":2}}],["ggplot2",{"2":{"50":1}}],["github",{"2":{"44":2,"54":1,"76":1}}],["gives",{"2":{"17":1}}],["given",{"2":{"2":1,"17":2,"62":1,"64":1,"69":1,"74":6,"75":3,"81":1}}],["globalproperties=dict",{"2":{"75":1}}],["global",{"2":{"74":1,"75":1}}],["glmakie",{"2":{"37":2,"90":2}}],["glue",{"2":{"8":1}}],["gradient",{"2":{"91":1,"92":1,"93":1,"94":1}}],["gradually",{"2":{"71":1}}],["grey25",{"2":{"94":1}}],["grey15",{"2":{"37":1,"50":1}}],["green",{"2":{"63":1}}],["grouped",{"2":{"74":1}}],["groups",{"2":{"49":1}}],["groupby",{"0":{"45":1,"48":1},"1":{"46":1,"47":1,"49":1,"50":1},"2":{"42":1,"44":1,"45":6,"46":1,"47":1,"48":3,"49":3,"50":3,"74":1,"84":1}}],["group",{"0":{"42":1},"1":{"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1},"2":{"45":1,"47":1,"48":2,"63":1,"74":3}}],["grouping",{"2":{"37":2,"47":2}}],["grid=false",{"2":{"50":1}}],["grid",{"2":{"18":1,"62":1,"74":1}}],["gridchunks",{"2":{"2":3,"4":1,"5":1,"6":1,"74":1,"75":1}}],["go",{"2":{"78":2}}],["going",{"2":{"75":1}}],["good",{"2":{"50":1}}],["goal",{"2":{"28":1,"43":1}}],["goes",{"2":{"16":2,"74":1,"75":1}}],["guide",{"2":{"10":2,"12":1,"13":1,"18":1,"24":3,"25":1}}],["gen",{"2":{"16":6}}],["general",{"0":{"87":1},"2":{"74":1}}],["generated",{"2":{"53":1,"55":1,"66":1,"70":1,"75":1}}],["generate",{"2":{"16":2,"32":1,"34":1,"35":1,"74":1,"78":1}}],["generic",{"2":{"16":2,"24":1}}],["getting",{"0":{"79":1},"1":{"80":1,"81":1,"82":1}}],["gettarrayaxes",{"2":{"41":1}}],["getarrayinfo",{"2":{"75":1}}],["getaxis",{"2":{"29":1,"37":2,"74":1}}],["getloopchunks",{"2":{"75":1}}],["getloopcachesize",{"2":{"75":1}}],["getouttype",{"2":{"75":1}}],["getoutaxis",{"2":{"75":1}}],["getfrontperm",{"2":{"75":1}}],["gets",{"2":{"74":1,"75":1}}],["get",{"0":{"60":1},"2":{"10":1,"27":1,"44":1,"48":1,"56":1,"58":1,"60":1,"75":3,"81":1,"84":1,"90":1}}],["geoaxis",{"2":{"92":1,"93":1}}],["geometrybasics",{"2":{"90":1}}],["geomakie",{"2":{"90":1,"92":2,"93":1}}],["geojson",{"0":{"54":1}}],["geotiff",{"0":{"54":1}}],["geo",{"2":{"1":1}}],["g",{"2":{"7":1,"10":1,"11":1,"13":1,"16":4,"18":1,"24":1,"45":26,"46":2,"47":2,"48":2,"49":1,"50":18,"60":1,"62":1,"65":1,"74":5,"90":2}}],["2π",{"2":{"83":1}}],["2×3",{"2":{"81":1}}],["2×2×3",{"2":{"4":1,"5":1,"6":1}}],["2×2",{"2":{"2":3}}],["2x2l31",{"2":{"53":1,"55":1,"66":1,"70":1}}],["28422753251364",{"2":{"52":4,"90":2}}],["28008",{"2":{"50":1}}],["2894",{"2":{"50":1}}],["288",{"2":{"48":1}}],["2818",{"2":{"45":1,"46":1}}],["28",{"2":{"21":2,"32":1,"45":3,"46":3,"50":3}}],["28571",{"2":{"17":2}}],["2857142857142857",{"2":{"10":1,"12":1,"13":1,"14":1,"17":3,"24":2,"25":1,"30":1,"36":3,"37":1,"81":1}}],["27831029907148686",{"2":{"84":1}}],["272109",{"2":{"81":1}}],["2747",{"2":{"50":1}}],["27394",{"2":{"81":1}}],["273",{"2":{"48":1}}],["276",{"2":{"48":2}}],["270",{"2":{"48":1}}],["275×205×9",{"2":{"45":4}}],["27",{"2":{"21":2,"45":1,"46":1,"50":1}}],["279857",{"2":{"20":1}}],["290209",{"2":{"81":1}}],["290659",{"2":{"20":1}}],["291145",{"2":{"81":1}}],["291786",{"2":{"81":1}}],["293101",{"2":{"72":2}}],["29473",{"2":{"50":1}}],["294336",{"2":{"21":1}}],["29816",{"2":{"50":1}}],["298586",{"2":{"20":1}}],["29564",{"2":{"50":1}}],["29",{"2":{"21":2}}],["296448",{"2":{"20":1}}],["263174",{"2":{"81":1}}],["267431",{"2":{"81":1}}],["266521",{"2":{"72":2}}],["26274",{"2":{"50":1}}],["26",{"2":{"16":2,"21":2,"52":2,"90":1}}],["253557",{"2":{"81":1}}],["25153",{"2":{"50":1}}],["25",{"2":{"16":4,"21":10,"32":1,"83":1}}],["249043",{"2":{"81":1}}],["24375",{"2":{"50":1}}],["2434",{"2":{"50":1}}],["245293",{"2":{"21":1}}],["24",{"2":{"16":6,"37":1,"57":2}}],["240",{"2":{"14":1,"16":1,"22":1}}],["239879",{"2":{"81":1}}],["238743",{"2":{"72":2}}],["230696",{"2":{"22":1}}],["231698",{"2":{"17":1}}],["23",{"2":{"16":8,"36":3,"50":1,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1}}],["22211",{"2":{"50":1}}],["22",{"2":{"16":10}}],["213509",{"2":{"81":1}}],["21t06",{"2":{"52":2,"90":1}}],["21t19",{"2":{"41":4}}],["210596",{"2":{"81":1}}],["2101",{"2":{"52":2,"90":1}}],["210902",{"2":{"17":1}}],["21699",{"2":{"50":1}}],["21626",{"2":{"21":1}}],["21209",{"2":{"50":1}}],["21498",{"2":{"17":1}}],["21",{"2":{"16":12,"45":8,"46":8,"50":8}}],["2=10",{"2":{"2":1}}],["2",{"2":{"2":3,"4":8,"5":9,"6":10,"8":1,"9":1,"11":3,"12":2,"13":1,"14":1,"17":9,"18":1,"20":2,"22":3,"24":1,"27":3,"28":6,"29":3,"32":1,"37":6,"40":4,"41":1,"45":1,"46":1,"50":40,"52":3,"53":3,"55":1,"56":4,"57":2,"58":2,"59":5,"60":2,"66":1,"70":2,"71":2,"74":2,"81":5,"90":3,"92":2,"94":1}}],["2003",{"2":{"53":1,"55":1,"66":1,"70":1}}],["2004",{"2":{"53":1,"55":1,"66":1,"70":1}}],["2005",{"2":{"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1}}],["2002",{"2":{"53":3,"55":2,"56":2,"57":2,"58":3,"59":5,"66":2,"70":1}}],["2001",{"2":{"53":3,"55":2,"56":2,"57":3,"58":3,"59":5,"66":2,"70":1}}],["2000",{"2":{"21":4}}],["2019",{"2":{"52":2,"90":1}}],["2015",{"2":{"52":2,"53":1,"55":1,"66":1,"70":1,"90":2}}],["201471",{"2":{"22":1}}],["20×10×15",{"2":{"36":2}}],["20×10×15×2",{"2":{"30":1,"81":1}}],["20ºn",{"2":{"35":1}}],["2023",{"2":{"83":1,"84":2}}],["2021",{"2":{"32":9,"83":1,"84":2,"85":1}}],["2020",{"2":{"32":5,"34":3,"35":4,"41":8,"64":1}}],["2024",{"2":{"21":4}}],["202429",{"2":{"17":1}}],["2022",{"2":{"10":4,"12":2,"13":2,"14":2,"16":8,"17":6,"18":2,"24":6,"25":2,"32":5,"34":3,"35":4,"85":1}}],["20",{"2":{"2":7,"4":10,"5":10,"6":10,"16":14,"24":2,"30":4,"35":2,"36":3,"37":1,"50":1,"70":2,"81":3}}],["55",{"2":{"84":1}}],["558735",{"2":{"20":1}}],["56083",{"2":{"81":1}}],["565253",{"2":{"81":1}}],["56632",{"2":{"50":1}}],["541399",{"2":{"81":1}}],["546641",{"2":{"17":1}}],["5e8",{"2":{"69":1,"74":1}}],["538223",{"2":{"81":1}}],["53",{"2":{"57":1}}],["536345",{"2":{"21":1}}],["5743",{"2":{"50":1}}],["57873",{"2":{"50":1}}],["57695",{"2":{"50":1}}],["57143",{"2":{"17":2}}],["52419",{"2":{"50":1}}],["59212",{"2":{"50":1}}],["59085",{"2":{"50":1}}],["598932",{"2":{"22":1}}],["5×4",{"2":{"72":2}}],["5×4×5",{"2":{"71":1}}],["5×6×36",{"2":{"32":1}}],["5×6",{"2":{"22":2}}],["5×10",{"2":{"20":2}}],["5173",{"2":{"78":1}}],["517644",{"2":{"21":1}}],["512244",{"2":{"21":1}}],["515763",{"2":{"17":1}}],["5843",{"2":{"45":1,"46":1}}],["586712",{"2":{"22":1}}],["58618",{"2":{"22":1}}],["587901",{"2":{"17":1}}],["582551",{"2":{"17":1}}],["58",{"2":{"16":2}}],["5",{"2":{"2":7,"4":16,"5":18,"6":7,"10":2,"12":3,"13":2,"14":1,"16":6,"17":10,"18":1,"20":2,"22":4,"24":5,"25":1,"27":4,"29":1,"30":2,"32":3,"34":4,"36":3,"37":2,"40":4,"50":5,"53":4,"55":2,"56":4,"57":3,"58":10,"59":10,"60":19,"66":2,"70":4,"71":6,"72":3,"81":2,"82":1,"85":2,"94":2}}],["50089",{"2":{"50":1}}],["500",{"2":{"0":1,"50":1,"94":2}}],["500mb",{"2":{"0":2}}],["rotate",{"2":{"94":1}}],["row",{"2":{"65":1,"74":1}}],["rowgap",{"2":{"50":1}}],["right",{"2":{"83":1,"85":1}}],["rights",{"2":{"72":1}}],["r",{"2":{"71":1}}],["r1i1p1f1",{"2":{"52":2,"90":3}}],["running",{"2":{"78":1}}],["run",{"2":{"18":1,"78":3}}],["runs",{"2":{"13":1,"75":1}}],["rafaqz",{"2":{"44":1}}],["raw",{"2":{"44":1,"54":1}}],["rasm",{"2":{"44":2}}],["ras",{"2":{"21":3}}],["rasters",{"2":{"21":2}}],["raster",{"0":{"21":1},"2":{"17":11,"21":5}}],["ranges",{"0":{"58":1},"2":{"29":1,"55":1}}],["range",{"2":{"10":2,"16":2,"17":2,"18":2,"24":2,"30":3,"32":1,"75":1,"81":3,"83":1}}],["randn",{"2":{"83":1}}],["random",{"2":{"35":2,"41":3,"81":1}}],["rand",{"2":{"2":1,"4":3,"5":3,"6":3,"8":2,"9":2,"10":1,"17":1,"18":1,"20":1,"21":1,"22":1,"24":2,"25":1,"27":1,"28":2,"30":2,"35":3,"37":1,"39":1,"40":3,"70":1,"72":1,"81":2}}],["relational",{"2":{"62":1}}],["related",{"2":{"44":1}}],["recommend",{"2":{"82":1}}],["recommended",{"2":{"59":1}}],["rechunking",{"2":{"75":1}}],["recalculate",{"2":{"75":1}}],["recal",{"2":{"75":1}}],["recently",{"2":{"0":1}}],["rewrote",{"2":{"52":1,"53":1,"55":1,"66":1,"70":1,"90":1}}],["realization",{"2":{"53":1,"55":1,"66":1,"70":1}}],["realm",{"2":{"52":1,"90":1}}],["readcubedata",{"2":{"35":2,"74":1}}],["read",{"0":{"51":1,"52":1,"53":1,"54":1},"1":{"52":1,"53":1,"54":1},"2":{"1":1,"35":1,"44":1,"51":1,"54":1,"58":1,"74":1}}],["red",{"2":{"50":1,"63":1}}],["reduce",{"2":{"10":1,"14":1}}],["reverse",{"2":{"50":1}}],["reverseordered",{"2":{"9":1,"81":1}}],["resets",{"2":{"74":1,"75":1}}],["respectively",{"2":{"63":1}}],["reshape",{"2":{"32":1,"34":2}}],["result",{"2":{"29":1,"37":1}}],["resulting",{"2":{"8":1,"9":1,"14":1,"74":1,"75":1}}],["results",{"0":{"85":1},"2":{"2":1,"5":1,"50":2,"74":1,"75":1}}],["references",{"2":{"53":1,"55":1,"66":1,"70":1}}],["reference",{"0":{"73":1},"1":{"74":1,"75":1},"2":{"41":1}}],["ref",{"2":{"30":1,"74":1,"75":1}}],["rebuild",{"0":{"28":1},"2":{"27":1,"28":2,"41":2,"44":1}}],["repeat",{"2":{"83":1}}],["repl",{"2":{"80":1}}],["replace",{"2":{"18":1,"44":1,"94":1}}],["repository",{"2":{"76":1,"86":1}}],["reports",{"2":{"76":1}}],["reproduces",{"2":{"43":1}}],["represented",{"2":{"74":1,"88":1}}],["represents",{"2":{"63":1}}],["representing",{"2":{"17":2,"75":1}}],["representation",{"2":{"1":1,"74":2,"75":3}}],["re",{"2":{"17":1}}],["returned",{"2":{"74":1}}],["returns",{"2":{"74":5,"75":2}}],["return",{"2":{"17":4,"45":1,"74":1,"75":1,"84":1}}],["registration",{"2":{"75":2}}],["registered",{"2":{"75":1}}],["regions",{"2":{"17":8}}],["region",{"2":{"17":12}}],["regular",{"2":{"4":4,"5":4,"6":2,"8":1,"9":1,"10":3,"12":3,"13":3,"14":3,"16":9,"17":8,"20":2,"21":6,"22":4,"24":9,"25":3,"27":9,"28":6,"29":2,"30":3,"32":14,"34":6,"35":4,"36":9,"37":3,"39":1,"40":5,"45":2,"46":2,"50":6,"52":2,"53":4,"55":2,"56":4,"57":2,"58":3,"59":10,"60":2,"66":2,"70":5,"71":6,"81":5,"84":1,"90":1}}],["regularchunks",{"2":{"2":6,"4":3,"5":3,"6":3}}],["requests",{"2":{"76":1}}],["requested",{"2":{"13":1}}],["requirements",{"2":{"53":1,"55":1,"66":1,"70":1}}],["required",{"2":{"32":1}}],["requires",{"2":{"16":1}}],["removes",{"2":{"75":1}}],["remove",{"2":{"46":1}}],["removed",{"2":{"15":1,"75":1}}],["remote",{"2":{"0":1}}],["http",{"2":{"78":1}}],["https",{"2":{"44":2,"53":1,"54":1,"55":1,"63":1,"66":1}}],["html",{"2":{"63":1}}],["hr",{"2":{"52":1,"90":2}}],["history",{"2":{"52":2,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1,"90":1}}],["hidedecorations",{"2":{"50":1}}],["highclip",{"2":{"50":4}}],["high",{"2":{"41":4}}],["hm",{"2":{"50":8}}],["hold",{"2":{"74":1}}],["holds",{"2":{"74":1,"75":1}}],["ho",{"0":{"41":1}}],["however",{"2":{"19":1,"32":1}}],["how",{"0":{"30":1,"31":1,"36":1,"37":1,"38":1},"1":{"32":1,"33":1,"34":1,"35":1,"39":1,"40":1},"2":{"6":1,"7":1,"10":1,"19":1,"23":1,"26":1,"37":1,"51":1,"72":1,"74":1,"86":1,"88":1}}],["happens",{"2":{"75":1}}],["had",{"2":{"72":1,"74":1,"75":1}}],["hamman",{"2":{"43":1,"50":1}}],["handled",{"2":{"75":1}}],["handle",{"2":{"62":1,"75":1}}],["handling",{"2":{"9":1,"74":1}}],["handy",{"2":{"37":1}}],["has",{"2":{"8":1,"9":1,"17":1,"21":1,"22":1,"35":1,"43":1,"46":1,"75":1}}],["half",{"2":{"8":5}}],["have",{"2":{"6":1,"9":1,"17":1,"24":1,"33":1,"35":2,"64":1,"74":3}}],["having",{"2":{"1":1,"17":1}}],["help",{"2":{"74":1,"75":2}}],["height",{"2":{"52":2,"90":1}}],["heatmap",{"0":{"91":1},"2":{"37":1,"50":3,"91":1}}],["hereby",{"2":{"17":1}}],["here",{"2":{"8":1,"9":1,"13":1,"16":2,"17":1,"31":1,"37":1,"58":1,"71":1,"77":2}}],["hence",{"2":{"1":1}}],["yeesian",{"2":{"54":1}}],["years",{"2":{"32":1,"83":1,"84":1}}],["year",{"2":{"8":4,"85":1}}],["yyyy",{"2":{"53":2,"55":2,"66":2,"70":2}}],["ylabel=",{"2":{"83":1,"85":1}}],["ylabel",{"2":{"50":3}}],["yasxa",{"2":{"35":6}}],["yaxcolumn",{"2":{"75":1}}],["yaxconvert",{"2":{"22":2}}],["yaxdefaults",{"2":{"75":1}}],["yaxarraybase",{"2":{"22":1,"74":1,"75":1}}],["yaxarray",{"0":{"11":1,"24":1,"31":1,"32":1,"56":1,"62":1},"1":{"32":1,"33":1,"34":1,"35":1},"2":{"2":1,"4":4,"5":4,"6":4,"7":1,"8":3,"9":3,"10":2,"12":1,"13":1,"14":2,"16":8,"17":3,"18":1,"20":4,"21":3,"22":5,"24":5,"25":2,"27":3,"28":5,"29":1,"30":3,"31":1,"32":15,"34":4,"35":6,"36":3,"37":4,"39":2,"40":4,"41":4,"44":2,"45":7,"46":1,"48":9,"49":1,"50":3,"52":2,"53":2,"55":2,"56":2,"57":3,"58":3,"59":5,"62":1,"64":1,"66":1,"67":1,"68":1,"70":2,"71":4,"74":10,"75":3,"81":5,"84":2,"88":1,"90":1}}],["yaxarrays",{"0":{"0":1,"1":1,"2":1,"7":1,"10":1,"16":1,"19":1,"23":1,"38":1,"42":1,"51":1,"55":1,"66":1,"76":1,"87":1,"88":1},"1":{"2":1,"3":1,"4":1,"5":1,"6":1,"8":1,"9":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"20":1,"21":1,"22":1,"24":1,"25":1,"39":1,"40":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"52":1,"53":1,"54":1,"56":1,"57":1,"58":1,"59":1,"60":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"77":1,"78":1},"2":{"0":3,"2":1,"4":1,"5":1,"6":1,"8":1,"9":1,"10":2,"16":4,"17":1,"18":2,"19":2,"20":1,"24":1,"27":1,"28":1,"30":1,"31":1,"32":1,"33":1,"34":2,"35":4,"39":1,"40":1,"41":2,"42":1,"51":1,"52":1,"53":1,"54":2,"55":1,"61":1,"63":1,"66":1,"69":1,"71":1,"74":27,"75":28,"76":1,"78":1,"80":3,"81":3,"82":2,"84":1,"86":1,"87":1,"90":1}}],["yax",{"2":{"0":1,"28":1,"41":3}}],["y",{"2":{"4":2,"5":3,"6":2,"21":4,"22":3,"32":4,"36":4,"45":2,"46":1,"50":3,"62":1,"81":5}}],["you",{"2":{"1":1,"18":1,"31":1,"35":3,"74":1,"75":2,"77":1,"78":2,"80":2,"82":1,"86":3,"88":2}}],["yourself",{"2":{"78":1}}],["your",{"2":{"1":2,"35":2,"69":2,"71":1,"74":1,"77":4,"78":4}}],["circshift",{"2":{"92":1}}],["ct1",{"2":{"90":4,"91":1}}],["cycle",{"0":{"83":1,"85":1},"1":{"84":1,"85":1},"2":{"84":4}}],["cycle=12",{"2":{"45":2,"46":1,"48":2,"49":2,"50":3}}],["cdata",{"2":{"75":1}}],["center",{"2":{"74":1,"83":1,"85":1}}],["certain",{"2":{"55":2,"75":1}}],["cell",{"2":{"52":2,"53":1,"56":2,"57":3,"58":3,"59":5,"74":1}}],["cf",{"2":{"52":2,"53":2,"55":2,"66":2,"70":2,"90":2}}],["cftime",{"2":{"45":4,"48":7,"49":5,"50":5,"53":6,"55":3,"56":6,"57":7,"58":9,"59":15,"66":3,"70":3}}],["cmpcachmisses",{"2":{"75":1}}],["cm4",{"2":{"53":4,"55":4,"66":4,"70":4}}],["cmip",{"2":{"52":1,"90":1}}],["cmip6",{"2":{"52":3,"90":6}}],["cmor",{"2":{"52":2,"53":3,"55":2,"56":2,"57":3,"58":3,"59":5,"66":2,"70":2,"90":1}}],["c54",{"2":{"50":1}}],["cb",{"2":{"50":1}}],["cbar",{"2":{"37":1}}],["cgrad",{"2":{"37":1}}],["cl",{"2":{"92":1,"93":1}}],["cl=lines",{"2":{"92":1,"93":1}}],["clean",{"2":{"75":1}}],["cleanme",{"2":{"75":4}}],["cleaner",{"2":{"74":2}}],["climate",{"2":{"53":1,"55":1,"66":1,"70":1}}],["closedinterval",{"2":{"59":1}}],["closed",{"0":{"59":1},"2":{"59":3}}],["close",{"2":{"41":4}}],["cloud",{"2":{"11":1,"52":1}}],["classes=classes",{"2":{"37":1}}],["classes",{"2":{"37":8}}],["classification",{"2":{"37":2}}],["class",{"2":{"37":3}}],["clustermanagers",{"2":{"18":2}}],["cluster",{"2":{"18":1}}],["cpus",{"2":{"18":1}}],["cpu",{"2":{"18":1}}],["c",{"2":{"17":11,"27":5,"28":7,"29":3,"37":2,"40":2,"63":1,"74":3,"75":3,"84":4,"90":2}}],["custom",{"2":{"24":1,"74":1}}],["current",{"2":{"17":2,"63":1,"74":1,"85":1}}],["currently",{"2":{"16":1,"41":1,"44":1,"86":1}}],["cubeaxis",{"2":{"75":1}}],["cubeaxes",{"2":{"74":1}}],["cubedir",{"2":{"75":1}}],["cube2",{"2":{"74":1}}],["cube1",{"2":{"74":1}}],["cubelist",{"2":{"74":1}}],["cubefittable",{"2":{"37":2,"74":1}}],["cubetable",{"0":{"37":1},"2":{"37":3,"74":3}}],["cubes",{"0":{"30":1},"2":{"9":2,"30":2,"35":1,"36":2,"37":1,"56":1,"64":1,"74":18,"75":9}}],["cube",{"0":{"27":1,"29":1,"31":1,"64":1,"84":1},"1":{"28":1,"32":1,"33":1,"34":1,"35":1},"2":{"2":1,"4":1,"5":1,"6":1,"16":11,"27":1,"29":1,"31":2,"35":1,"36":1,"37":2,"44":1,"64":3,"71":1,"74":34,"75":19,"88":1}}],["chose",{"2":{"63":1}}],["child",{"2":{"52":1,"90":1}}],["check",{"2":{"16":1,"71":1,"82":1}}],["changed",{"2":{"82":1,"86":1}}],["change",{"2":{"10":1,"74":1,"75":1}}],["chunkoffset",{"2":{"75":1}}],["chunksize`",{"2":{"75":1}}],["chunksizes",{"2":{"74":2}}],["chunksize",{"2":{"74":1,"75":3}}],["chunks",{"0":{"4":1},"2":{"2":5,"4":1,"5":1,"6":2,"74":4,"75":11}}],["chunked",{"2":{"2":5}}],["chunking",{"0":{"2":1,"3":1,"5":1,"6":1},"1":{"4":1,"5":1,"6":1},"2":{"1":1,"5":1,"74":4,"75":3}}],["chunk",{"0":{"1":1},"1":{"2":1,"3":1,"4":1,"5":1,"6":1},"2":{"1":1,"2":1,"4":1,"5":1,"74":4,"75":4}}],["criteria",{"2":{"37":1}}],["creating",{"0":{"17":1},"2":{"10":1,"28":1,"32":1,"71":1,"77":1}}],["createdataset",{"2":{"75":2}}],["created",{"2":{"75":2}}],["creates",{"2":{"37":1,"74":2,"75":1}}],["create",{"0":{"23":1,"24":1,"25":1},"1":{"24":1,"25":1},"2":{"10":1,"16":1,"17":2,"23":1,"24":1,"28":1,"30":1,"32":2,"37":1,"41":1,"44":1,"48":1,"66":1,"69":1,"71":3,"74":1,"75":1,"81":1,"83":1}}],["crucial",{"2":{"1":1}}],["coastlines",{"2":{"92":3,"93":1}}],["cosd",{"2":{"74":1}}],["country",{"2":{"74":4}}],["country=cube2",{"2":{"74":1}}],["could",{"2":{"28":1,"41":1}}],["copies",{"2":{"75":1}}],["copied",{"2":{"71":1}}],["copybuf",{"2":{"75":2}}],["copydata",{"2":{"75":1}}],["copy",{"2":{"27":1,"74":1,"78":1}}],["coordinates",{"2":{"52":1}}],["college",{"2":{"86":1}}],["collected",{"2":{"75":1}}],["collectfromhandle",{"2":{"75":1}}],["collection",{"2":{"26":1,"62":1}}],["collect",{"2":{"20":1,"29":3,"84":1}}],["colonperm",{"2":{"75":1}}],["color=",{"2":{"85":3}}],["color",{"2":{"83":1,"92":1,"93":1,"94":1}}],["colormap=",{"2":{"50":1}}],["colormap=makie",{"2":{"37":1}}],["colormap",{"2":{"50":3,"91":1,"92":1,"93":1,"94":1}}],["colorrange=",{"2":{"50":1}}],["colorrange",{"2":{"50":3}}],["colorbar",{"2":{"37":1,"50":2}}],["column",{"2":{"65":1,"75":1}}],["colgap",{"2":{"50":1}}],["colnames",{"2":{"41":1}}],["configuration",{"2":{"75":2}}],["concatenating",{"2":{"74":1}}],["concatenates",{"2":{"74":1}}],["concatenate",{"0":{"30":1},"2":{"30":2}}],["concatenatecubes",{"0":{"9":1},"2":{"9":2,"30":2,"74":2}}],["concrete",{"2":{"74":2}}],["contributing",{"2":{"77":1}}],["contribute",{"0":{"76":1,"77":1},"1":{"77":1,"78":2}}],["contrast",{"2":{"74":1}}],["content",{"2":{"74":1}}],["contact",{"2":{"53":1,"55":1,"66":1,"70":1}}],["contains",{"2":{"59":1,"74":1,"75":1}}],["contain",{"2":{"52":1,"53":1,"75":1}}],["containing",{"2":{"8":1,"37":1,"63":1,"64":1,"74":1}}],["continue",{"2":{"45":1}}],["constant",{"2":{"75":1}}],["constructor",{"2":{"74":1}}],["constructs",{"2":{"74":1}}],["construct",{"0":{"41":1},"2":{"74":2}}],["consolidated=true",{"2":{"52":1,"90":1}}],["consistent",{"2":{"52":1,"90":1}}],["consisting",{"2":{"8":1}}],["considering",{"2":{"43":1}}],["considered",{"2":{"37":1}}],["consider",{"2":{"28":1}}],["convinient",{"2":{"26":1}}],["conventions",{"2":{"53":1,"55":1,"66":1,"70":1}}],["convenient",{"2":{"18":1}}],["conversion",{"2":{"19":1,"21":1,"22":1}}],["conversions",{"2":{"19":1}}],["converted",{"2":{"64":1}}],["convert",{"0":{"19":1,"20":1,"21":1,"22":1},"1":{"20":1,"21":1,"22":1},"2":{"19":1,"20":2,"22":2,"74":1,"75":1}}],["corresponding",{"2":{"7":1,"17":2,"64":1,"74":1}}],["combining",{"0":{"89":1}}],["combined",{"2":{"9":2,"64":2}}],["combine",{"0":{"7":1},"1":{"8":1,"9":1},"2":{"7":1,"8":1,"9":1,"88":1}}],["comment",{"2":{"52":1}}],["common",{"2":{"35":5,"74":1}}],["com",{"2":{"44":2,"54":1}}],["compiler",{"2":{"82":1}}],["compares",{"2":{"75":1}}],["compatible",{"2":{"54":1}}],["compuation",{"2":{"74":1}}],["computing",{"2":{"37":1}}],["computations",{"2":{"13":1,"36":1}}],["computation",{"0":{"18":1},"2":{"13":1,"62":1,"74":3,"75":3}}],["computed",{"2":{"75":1}}],["compute",{"0":{"10":1},"1":{"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1},"2":{"84":1}}],["comply",{"2":{"53":1,"55":1,"66":1,"70":1}}],["complexity",{"2":{"36":1}}],["complex",{"2":{"10":2,"81":1}}],["comes",{"2":{"1":1}}],["code",{"2":{"6":1,"13":1,"18":2,"26":1}}],["captialisation",{"2":{"75":1}}],["cameracontrols",{"2":{"94":1}}],["came",{"2":{"64":1}}],["cairomakie",{"2":{"50":1,"83":2}}],["caxes",{"2":{"27":2,"74":2}}],["car",{"2":{"17":1}}],["cartesianindex",{"2":{"17":11}}],["caluclate",{"2":{"74":1}}],["calculations",{"2":{"50":1,"75":1}}],["calculating",{"2":{"14":1,"74":1}}],["calculates",{"2":{"74":1}}],["calculated",{"2":{"37":2,"45":1}}],["calculate",{"2":{"14":1,"17":1,"37":2,"42":1,"43":2,"45":1,"50":1,"75":2,"84":1}}],["calling",{"2":{"50":1}}],["called",{"2":{"16":1,"62":3,"75":1}}],["call",{"2":{"1":1,"18":1}}],["case",{"2":{"13":1,"35":1,"47":1,"52":1}}],["cases",{"2":{"0":1,"59":1,"86":1}}],["cataxis",{"2":{"74":2}}],["categoricalaxis",{"2":{"74":1}}],["categorical",{"2":{"9":1,"17":1,"30":1,"37":1,"41":4,"45":2,"46":1,"47":1,"48":2,"49":2,"50":3,"74":1,"75":1,"81":1}}],["cat",{"0":{"8":1},"2":{"8":2}}],["cache=1gb```",{"2":{"74":1}}],["cache=1e9",{"2":{"16":2}}],["cache=",{"2":{"74":1}}],["cache=5",{"2":{"74":1}}],["cache=yaxdefaults",{"2":{"74":1}}],["caches",{"2":{"0":1}}],["cachesize",{"2":{"0":2,"75":1}}],["cache",{"2":{"0":6,"69":1,"74":4,"75":7}}],["caching",{"0":{"0":1}}],["can",{"2":{"0":5,"2":1,"3":1,"13":2,"14":1,"16":3,"17":1,"18":3,"24":2,"30":1,"31":1,"33":1,"35":1,"36":1,"37":2,"41":1,"46":1,"50":1,"52":2,"53":1,"54":1,"60":1,"62":3,"63":2,"64":1,"70":1,"71":1,"72":1,"74":11,"75":6,"77":1,"80":2,"86":2}}],["msc",{"2":{"84":3,"85":2}}],["mscarray",{"2":{"84":2}}],["md",{"2":{"77":2}}],["mdash",{"2":{"69":1,"74":24,"75":24}}],["mm",{"2":{"53":2,"55":2,"66":2,"70":2}}],["mpi",{"2":{"52":1,"90":2}}],["m",{"2":{"20":2}}],["miss",{"2":{"75":1}}],["missing",{"2":{"14":2,"16":6,"17":2,"36":1,"37":2,"53":2,"56":4,"57":6,"58":6,"59":10,"71":3,"72":1,"74":2,"75":2,"94":1}}],["minimized",{"2":{"75":1}}],["minutes",{"2":{"53":1,"56":2,"57":3,"58":3,"59":5}}],["might",{"2":{"19":1,"86":1}}],["mymean",{"2":{"18":4}}],["my",{"2":{"16":2}}],["manager",{"2":{"80":1}}],["many",{"2":{"62":1,"75":1}}],["mahecha",{"2":{"64":1}}],["mar",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["marketdata",{"2":{"41":2}}],["master",{"2":{"44":1}}],["mask",{"2":{"37":2}}],["makie",{"2":{"50":1,"94":1}}],["making",{"2":{"11":1,"55":1}}],["make",{"2":{"34":1,"35":2,"71":1,"74":1,"75":2,"78":1,"94":1}}],["main",{"2":{"31":1,"75":1}}],["machine",{"2":{"18":1,"62":1}}],["matching",{"2":{"81":1}}],["match",{"2":{"75":2}}],["matched",{"2":{"74":1}}],["mat",{"2":{"17":4}}],["matrix",{"2":{"16":2,"17":1,"20":1,"41":1,"46":1,"50":2,"62":1,"72":2,"84":1}}],["maximal",{"2":{"75":1}}],["maximum",{"2":{"36":1,"74":1,"75":1}}],["maxbuf",{"2":{"75":1}}],["max",{"2":{"16":2,"69":1,"74":7,"75":2}}],["maxsize",{"2":{"0":2}}],["may",{"2":{"10":1,"15":1,"45":4,"46":2,"47":1,"48":4,"49":4,"50":6,"52":1,"53":1,"82":1}}],["maps",{"0":{"90":1},"1":{"91":1}}],["mapslice",{"2":{"18":1}}],["mapslices",{"0":{"14":1},"2":{"10":1,"13":1,"14":1,"18":1,"36":1,"84":1}}],["mapped",{"2":{"74":1}}],["mapping",{"2":{"74":1,"75":3}}],["mapcube",{"0":{"15":1},"1":{"16":1,"17":1},"2":{"10":1,"13":1,"15":1,"16":4,"17":2,"18":3,"74":5,"75":2}}],["map",{"0":{"13":1,"36":1},"2":{"10":1,"13":2,"17":3,"18":3,"36":4,"37":1,"45":2,"49":1,"50":1,"74":2,"81":1,"84":2}}],["moll",{"0":{"93":1}}],["mowingwindow",{"2":{"74":1}}],["movingwindow",{"2":{"74":4}}],["module",{"2":{"74":2}}],["model",{"2":{"53":1,"55":1,"63":2,"66":1,"70":1}}],["modification",{"2":{"11":1,"18":1}}],["modify",{"0":{"11":1}}],["monthday",{"2":{"84":4}}],["monthly",{"0":{"43":1}}],["month",{"2":{"32":7,"34":3,"35":4,"43":1,"45":4,"46":1,"47":1,"48":5,"49":2,"50":3,"74":1,"84":2}}],["moment",{"2":{"22":1}}],["more",{"2":{"9":1,"10":1,"31":1,"36":1,"37":1,"58":1,"59":1,"64":1,"69":1,"74":3,"75":1,"81":1}}],["most",{"2":{"1":1,"15":1,"19":1}}],["mesh",{"2":{"94":2}}],["merely",{"2":{"71":1}}],["measured",{"2":{"63":1,"64":1}}],["measure",{"2":{"62":1}}],["measures",{"2":{"52":1}}],["means",{"0":{"43":1},"2":{"14":1,"74":1}}],["mean",{"0":{"83":1,"85":1},"1":{"84":1,"85":1},"2":{"10":1,"14":3,"18":4,"37":4,"45":10,"46":2,"47":1,"50":2,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"74":1,"84":5}}],["meter",{"2":{"52":1}}],["method",{"2":{"16":2,"74":17,"75":18}}],["methods",{"2":{"7":1,"18":1,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["metadata",{"2":{"8":1,"9":1,"10":1,"12":1,"13":1,"14":2,"16":5,"17":3,"19":1,"20":1,"21":2,"22":3,"24":2,"27":1,"28":3,"29":1,"30":1,"32":5,"36":3,"37":3,"45":2,"46":1,"48":3,"49":2,"50":3,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"71":2,"74":1,"81":3,"84":1}}],["members",{"2":{"75":1}}],["member",{"2":{"6":1}}],["memory",{"2":{"1":1,"17":1,"19":3,"35":4,"44":1,"62":1,"71":1,"74":2,"75":1}}],["multiplying",{"2":{"36":1}}],["multiply",{"2":{"10":1,"36":1}}],["multiple",{"0":{"40":1,"89":1},"2":{"7":1,"18":1,"52":1,"53":1,"62":1,"74":1}}],["must",{"2":{"0":1,"64":1,"74":1,"75":1}}],["mb",{"2":{"0":1,"53":1,"56":2}}],["pkg",{"2":{"80":2}}],["pkg>",{"2":{"78":1}}],["purple",{"2":{"83":1}}],["purpose",{"2":{"26":1,"36":1}}],["pull",{"2":{"76":1}}],["public",{"0":{"74":1}}],["published",{"2":{"50":1}}],["plt",{"2":{"91":1}}],["place",{"2":{"75":1}}],["plots",{"2":{"94":1}}],["plot",{"0":{"85":1,"91":1,"94":1},"2":{"50":2}}],["plotting",{"0":{"90":1},"1":{"91":1},"2":{"0":1}}],["plus",{"2":{"44":1,"74":1}}],["pydata",{"2":{"44":1}}],["p",{"2":{"35":10,"53":1,"55":1,"66":1,"70":1}}],["picture",{"2":{"62":1,"63":1}}],["pieces",{"2":{"26":1}}],["pixel",{"0":{"83":1},"1":{"84":1,"85":1},"2":{"18":2}}],["post=getpostfunction",{"2":{"74":1}}],["positions",{"2":{"75":2}}],["position",{"2":{"62":1}}],["positional",{"2":{"57":1,"58":1}}],["possible",{"2":{"18":2,"19":1,"30":1,"71":1,"74":3,"75":1}}],["pos",{"2":{"17":2}}],["point3f",{"2":{"94":1}}],["point",{"2":{"17":3,"52":1,"81":1}}],["points",{"2":{"4":4,"5":4,"6":2,"8":1,"9":1,"10":3,"12":3,"13":3,"14":4,"16":9,"17":16,"18":1,"20":2,"21":6,"22":4,"24":9,"25":3,"27":9,"28":6,"29":2,"30":3,"32":14,"34":6,"35":21,"36":9,"37":5,"39":1,"40":5,"41":4,"45":3,"46":2,"48":2,"49":1,"50":7,"52":6,"53":6,"55":3,"56":6,"57":4,"58":9,"59":16,"60":2,"62":2,"63":1,"66":3,"70":6,"71":6,"81":5,"84":1,"90":3}}],["page",{"2":{"94":1}}],["paste",{"2":{"78":1}}],["pass",{"2":{"74":1}}],["passing",{"2":{"74":3}}],["passed",{"2":{"74":4}}],["pair",{"2":{"75":1}}],["partitioned",{"2":{"75":1}}],["participate",{"2":{"74":1}}],["particular",{"2":{"65":1}}],["parts",{"2":{"74":1}}],["parent",{"2":{"52":1,"90":1}}],["parallelized",{"2":{"75":1}}],["parallelisation",{"2":{"74":1}}],["parallel",{"2":{"18":1,"62":1}}],["package",{"2":{"18":1,"58":1,"60":1,"73":1,"80":1}}],["packages",{"2":{"16":1,"19":1}}],["paths",{"2":{"75":2}}],["path=",{"2":{"16":2,"52":1,"67":1,"68":1,"69":1,"70":1,"71":1,"75":1}}],["path=f",{"2":{"4":1,"5":1,"6":1}}],["path",{"2":{"0":1,"44":2,"52":3,"53":2,"54":2,"55":2,"66":2,"69":3,"74":4,"78":1}}],["pr",{"2":{"78":1}}],["printed",{"2":{"41":2}}],["prior",{"2":{"1":1}}],["projection",{"0":{"92":1,"93":1},"1":{"93":1,"94":1}}],["props",{"2":{"81":2}}],["properly",{"2":{"43":1}}],["properties=dict",{"2":{"75":1}}],["properties",{"2":{"10":2,"18":2,"24":3,"25":3,"44":1,"50":1,"52":1,"53":1,"55":1,"66":1,"70":1,"74":5,"75":1,"90":1}}],["probably",{"2":{"75":1}}],["provide",{"2":{"74":1}}],["provides",{"2":{"62":1,"87":1}}],["provided",{"2":{"31":1,"71":1,"74":1}}],["process",{"2":{"62":1,"75":2}}],["processed",{"2":{"13":1}}],["progressmeter",{"2":{"74":1}}],["progress",{"2":{"44":1,"86":1,"88":1}}],["product",{"2":{"17":1}}],["pressing",{"2":{"80":1}}],["pre",{"2":{"74":2}}],["previous",{"2":{"50":1,"69":1,"71":1,"74":1}}],["previously",{"2":{"37":1}}],["prepared",{"2":{"53":1,"55":1,"66":1,"70":1}}],["prep",{"2":{"9":2}}],["precipitation",{"2":{"9":2,"63":1,"64":1,"81":2}}],["permute",{"2":{"75":1}}],["permuteloopaxes",{"2":{"75":1}}],["permutation",{"2":{"75":1}}],["persistend",{"2":{"75":1}}],["persistency",{"2":{"75":1}}],["persistent",{"2":{"74":1,"75":2}}],["persist",{"2":{"69":1,"74":1,"75":1}}],["perform",{"2":{"75":1}}],["performed",{"2":{"13":2}}],["performing",{"2":{"10":1}}],["per",{"2":{"7":1,"14":1,"45":1,"48":1,"49":1}}],["=interval",{"2":{"59":2}}],["===",{"2":{"41":1}}],["==",{"2":{"12":1,"41":1,"84":1}}],["=>nan",{"2":{"94":1}}],["=>",{"2":{"10":2,"12":1,"13":1,"16":2,"17":5,"18":1,"24":3,"25":3,"39":1,"40":1,"41":5,"44":1,"45":5,"46":1,"48":3,"49":2,"50":3,"52":20,"53":20,"55":10,"56":20,"57":30,"58":30,"59":50,"66":10,"70":10,"81":6,"90":10}}],["=>2",{"2":{"4":1}}],["=>10",{"2":{"4":1}}],["=>5",{"2":{"4":1,"5":1}}],["=",{"2":{"0":5,"2":4,"4":9,"5":15,"6":9,"8":5,"9":5,"10":4,"11":1,"12":1,"13":1,"16":14,"17":16,"18":5,"20":3,"21":8,"22":4,"24":5,"25":4,"27":1,"28":3,"30":6,"32":7,"34":6,"35":17,"37":7,"39":1,"40":3,"41":7,"44":8,"45":16,"46":1,"47":1,"48":4,"49":1,"50":22,"52":2,"53":2,"54":2,"55":2,"56":2,"57":6,"58":6,"59":3,"66":2,"69":8,"70":2,"71":4,"72":5,"74":11,"75":7,"81":5,"83":10,"84":11,"85":5,"90":8,"91":5,"92":7,"93":5,"94":6}}],["dc",{"2":{"75":2}}],["dkrz",{"2":{"52":1,"90":2}}],["drivers",{"2":{"74":1}}],["driver",{"2":{"69":2,"74":6}}],["driver=",{"2":{"4":1,"5":1,"6":1,"67":2,"68":2,"69":3,"70":1,"71":2,"74":3}}],["drop",{"2":{"50":1}}],["dropdims",{"0":{"46":1},"2":{"45":2,"46":2,"50":1}}],["dufresne",{"2":{"53":1,"55":1,"66":1,"70":1}}],["due",{"2":{"47":1}}],["dummy",{"2":{"30":1,"32":1,"83":1,"84":1}}],["during",{"2":{"17":1,"18":1,"19":1}}],["dd",{"2":{"27":1,"84":1}}],["d",{"2":{"17":5,"41":5,"50":3,"84":1}}],["dash",{"2":{"85":1}}],["danger",{"2":{"69":1}}],["daysinmonth",{"2":{"45":1,"48":1}}],["days",{"2":{"43":1,"45":2,"47":1,"48":2,"49":2}}],["dayofyear",{"2":{"16":1}}],["day",{"2":{"10":2,"12":1,"13":1,"14":1,"16":4,"17":3,"18":1,"24":3,"25":1,"83":1,"84":4,"85":1}}],["datconfig",{"2":{"75":2}}],["datset",{"2":{"74":1}}],["dat",{"2":{"74":8,"75":16}}],["datetime360day",{"2":{"53":6,"55":3,"56":6,"57":7,"58":9,"59":15,"66":3,"70":3}}],["datetimenoleap",{"2":{"45":4,"48":7,"49":5,"50":5}}],["datetime",{"2":{"41":5,"52":2,"90":1}}],["date",{"2":{"10":5,"12":3,"13":3,"14":3,"16":12,"17":11,"18":3,"24":8,"25":3,"32":24,"34":8,"35":11,"62":1,"83":2,"84":5,"90":1}}],["datesid",{"2":{"84":2}}],["dates",{"2":{"10":2,"12":1,"13":1,"14":1,"16":5,"17":3,"18":1,"24":3,"25":1,"32":8,"34":4,"35":5,"42":1,"64":1,"83":1,"84":2,"90":1}}],["data=cube1",{"2":{"74":1}}],["databases",{"2":{"62":1}}],["dataframe",{"2":{"37":1,"74":1}}],["dataframes",{"2":{"37":1}}],["datacubes",{"2":{"74":1}}],["datacube",{"0":{"89":1},"2":{"37":2,"71":1,"74":1}}],["datatypes",{"2":{"31":1}}],["data1",{"2":{"30":2}}],["data3",{"2":{"25":1}}],["data2",{"2":{"24":2,"30":2}}],["datasetaxis",{"2":{"74":2,"75":1}}],["datasetaxis=",{"2":{"74":1,"75":1}}],["dataset",{"0":{"25":1,"31":1,"33":1,"34":1,"35":1,"38":1,"41":1,"63":1,"69":1,"70":1,"72":1},"1":{"32":1,"33":1,"34":2,"35":2,"39":1,"40":1},"2":{"0":3,"3":1,"4":4,"5":2,"6":3,"9":1,"10":1,"19":1,"25":2,"33":1,"34":3,"35":5,"39":2,"40":2,"41":5,"52":3,"53":3,"54":2,"55":3,"56":1,"63":3,"64":2,"66":3,"67":1,"68":1,"69":3,"70":4,"71":2,"72":2,"74":18,"75":9,"90":2}}],["datasets",{"0":{"3":1,"23":1,"42":1,"51":1,"55":1,"66":1},"1":{"4":1,"5":1,"6":1,"24":1,"25":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"52":1,"53":1,"54":1,"56":1,"57":1,"58":1,"59":1,"60":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1},"2":{"0":2,"19":1,"23":1,"35":1,"51":1,"69":1,"74":8,"75":4,"88":1}}],["data",{"0":{"29":1,"44":1,"64":1},"2":{"0":3,"1":2,"7":1,"8":1,"10":2,"11":1,"16":4,"17":2,"18":2,"20":1,"21":1,"29":1,"32":1,"34":1,"35":2,"37":2,"44":8,"52":2,"53":4,"55":3,"56":2,"57":3,"58":3,"59":5,"61":1,"62":3,"63":2,"64":3,"66":3,"69":2,"70":3,"71":3,"72":1,"74":20,"75":12,"81":4,"82":1,"83":2,"84":1,"88":4,"90":5,"92":1}}],["dev",{"2":{"78":1}}],["dependencies",{"2":{"78":1}}],["detect",{"2":{"74":1,"75":1}}],["determined",{"2":{"75":1}}],["determines",{"2":{"74":1}}],["determine",{"2":{"1":1,"74":1}}],["defaultfillval",{"2":{"75":1}}],["defaults",{"2":{"74":7}}],["default",{"2":{"71":1,"74":1,"75":4}}],["definition",{"2":{"64":1}}],["defining",{"2":{"18":1}}],["defines",{"2":{"74":1}}],["defined",{"2":{"21":1,"22":1,"37":1,"50":1,"60":1,"62":1,"65":1,"71":1,"81":1}}],["define",{"0":{"84":1},"2":{"16":2,"32":1,"37":1,"50":1,"74":2,"83":1}}],["deletes",{"2":{"69":1,"74":1}}],["delete",{"2":{"69":2,"71":1}}],["denoting",{"2":{"74":1}}],["dense",{"2":{"62":1}}],["denvil",{"2":{"53":2,"55":2,"66":2,"70":2}}],["degc",{"2":{"53":1,"56":2,"57":3,"58":3,"59":5}}],["dec",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["dest",{"2":{"93":1}}],["desc",{"2":{"74":3,"75":3}}],["descriptor",{"2":{"75":4}}],["descriptors",{"2":{"74":2}}],["descriptions",{"2":{"74":1}}],["description",{"2":{"31":1,"74":4,"75":11}}],["described",{"2":{"88":1}}],["describe",{"2":{"74":2}}],["describes",{"2":{"7":1,"10":1,"19":1,"23":1,"51":1,"59":1,"61":1,"73":1,"75":1}}],["describing",{"2":{"74":1}}],["designed",{"2":{"19":2,"62":1}}],["desired",{"2":{"16":1,"75":4}}],["demand",{"2":{"13":1}}],["diverging",{"2":{"50":1}}],["divided",{"2":{"36":1}}],["differing",{"2":{"74":1}}],["difference",{"2":{"50":1}}],["differences",{"2":{"41":1,"45":1,"50":1,"75":1}}],["different",{"2":{"9":2,"16":1,"18":1,"27":1,"28":1,"43":1,"63":1,"74":3,"75":2,"86":1}}],["diff",{"2":{"45":2,"50":3}}],["directory",{"2":{"52":1,"67":2,"68":2}}],["directories",{"2":{"51":1,"75":1}}],["direct",{"2":{"41":1}}],["directly",{"2":{"16":1,"22":1,"23":1,"24":1,"72":2}}],["dictionary",{"2":{"63":1,"74":3}}],["dict",{"2":{"4":1,"5":1,"8":1,"9":1,"10":2,"12":1,"13":1,"14":2,"16":5,"17":4,"18":1,"20":1,"21":2,"22":3,"24":4,"25":2,"27":1,"28":3,"29":1,"30":1,"32":5,"36":3,"37":3,"41":2,"45":3,"46":2,"48":4,"49":3,"50":3,"52":2,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1,"71":1,"74":3,"81":3,"84":1,"90":1}}],["dime",{"2":{"52":1}}],["dimensional",{"2":{"61":1,"62":2,"74":1}}],["dimensionaldata",{"2":{"17":1,"22":2,"27":1,"28":1,"32":1,"34":1,"35":1,"41":1,"42":1,"44":1,"45":16,"46":10,"48":6,"49":6,"50":39,"58":1,"59":2,"60":3,"62":1,"65":1,"81":1,"82":3,"84":1,"90":1}}],["dimensions",{"0":{"34":1,"35":1},"2":{"9":1,"10":1,"13":1,"15":1,"16":2,"17":2,"18":1,"24":2,"28":1,"30":1,"33":1,"35":3,"36":2,"44":1,"45":16,"46":10,"48":6,"49":6,"50":39,"55":1,"60":2,"62":3,"63":1,"74":8,"75":3,"81":3,"82":1}}],["dimension",{"0":{"8":1,"9":1,"60":1,"65":1},"2":{"2":1,"8":2,"9":1,"10":1,"14":2,"16":3,"17":3,"32":1,"35":1,"46":1,"47":1,"50":1,"58":1,"60":1,"62":1,"64":1,"65":1,"74":3,"75":3,"81":1}}],["dimgroupbyarray",{"2":{"45":1,"48":1}}],["dimarray",{"0":{"22":1},"2":{"17":3,"22":6,"45":1,"46":1,"48":1,"49":2,"50":3,"62":1}}],["dims=2",{"2":{"84":1}}],["dims=",{"2":{"14":2,"18":1,"36":1,"45":5,"46":1,"48":1,"50":1}}],["dims",{"2":{"8":3,"9":1,"10":1,"12":1,"13":1,"14":2,"16":5,"17":4,"20":1,"21":3,"22":2,"24":2,"27":3,"28":4,"29":1,"30":1,"32":5,"36":3,"37":3,"41":1,"44":1,"45":6,"46":1,"48":5,"49":2,"50":5,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"71":1,"81":2,"84":1}}],["dim",{"2":{"2":2,"4":7,"5":8,"6":2,"8":2,"9":3,"10":3,"16":3,"17":4,"18":3,"20":2,"22":2,"24":7,"27":9,"28":6,"29":3,"30":4,"32":3,"34":3,"35":2,"39":1,"40":5,"41":2,"45":2,"46":2,"50":6,"70":3,"71":6,"81":4,"84":1}}],["disregard",{"2":{"75":1}}],["dispatch",{"2":{"75":1}}],["discribe",{"2":{"74":2}}],["distribute",{"2":{"18":1}}],["distributed",{"0":{"18":1},"2":{"0":1,"18":2}}],["diskarray",{"2":{"74":1}}],["diskarrays",{"2":{"2":9,"4":4,"5":4,"6":4,"74":2,"75":1}}],["disk",{"2":{"1":1,"16":1,"22":1,"62":1,"71":3,"72":2,"74":1,"75":2}}],["dodgerblue",{"2":{"85":1}}],["dot",{"2":{"85":1}}],["documenter",{"2":{"94":1}}],["documentation",{"0":{"77":1},"1":{"78":1}}],["doc",{"2":{"69":1}}],["docstring",{"2":{"74":1}}],["docs",{"0":{"78":1},"2":{"63":1,"77":2,"78":6,"82":1}}],["download",{"0":{"44":1},"2":{"44":1,"53":2,"54":2,"55":2,"66":2}}],["downloads",{"2":{"42":1,"44":1,"53":1,"54":1,"55":1,"66":1}}],["done",{"2":{"28":1,"36":1,"50":1,"77":2}}],["doing",{"2":{"18":1,"27":1,"29":1,"78":1}}],["does",{"2":{"18":1,"71":1,"74":1,"75":1}}],["do",{"0":{"30":1,"31":1,"36":1,"37":1,"38":1,"41":1},"1":{"32":1,"33":1,"34":1,"35":1,"39":1,"40":1},"2":{"1":1,"13":1,"16":1,"17":3,"18":1,"26":2,"36":1,"43":1,"50":1,"71":1,"72":1,"75":1,"78":1,"80":1}}],["dsw",{"2":{"45":2,"50":2}}],["dsfinal",{"2":{"30":1,"36":2,"37":2}}],["ds2",{"2":{"30":3,"36":1,"70":1}}],["ds1",{"2":{"30":3,"36":3,"37":1}}],["dschunked",{"2":{"4":3,"5":3,"6":3}}],["ds",{"2":{"0":3,"4":2,"5":2,"6":2,"25":1,"34":2,"35":12,"39":1,"40":1,"41":2,"44":5,"45":10,"48":1,"50":3,"52":1,"53":1,"54":1,"55":1,"56":2,"66":1,"67":3,"68":3,"69":3,"70":2,"71":1,"72":5,"74":3,"75":1,"94":2}}],["wglmakie",{"2":{"94":2}}],["would",{"2":{"74":2}}],["world",{"2":{"54":2}}],["workdir",{"2":{"75":1}}],["worker",{"2":{"74":1}}],["workers",{"2":{"74":1}}],["work",{"2":{"19":2,"44":1,"61":1,"74":1,"86":2,"88":1}}],["workload",{"2":{"18":1}}],["working",{"2":{"16":1,"72":1}}],["works",{"2":{"6":1,"29":1,"34":1,"35":1,"71":1}}],["workflows",{"2":{"1":1}}],["written",{"2":{"74":1,"75":1}}],["writing",{"2":{"72":1}}],["writefac",{"2":{"75":1}}],["writefac=4",{"2":{"69":1,"74":1}}],["writes",{"2":{"74":1}}],["write",{"0":{"66":1,"67":1,"68":1},"1":{"67":1,"68":1,"69":1,"70":1,"71":1,"72":1},"2":{"71":1,"74":2}}],["wrapping",{"2":{"47":1,"60":2}}],["wrapped",{"2":{"16":1}}],["wrap",{"2":{"0":1,"74":1}}],["www",{"2":{"53":1,"55":1,"66":1}}],["w",{"2":{"50":2,"72":2}}],["was",{"2":{"17":1,"18":1,"75":1}}],["way",{"2":{"15":1,"19":1,"27":1}}],["warning",{"2":{"11":1,"19":1,"27":1,"35":1,"44":1,"69":1,"71":1,"74":1}}],["wanted",{"2":{"75":1}}],["wants",{"2":{"71":1}}],["want",{"2":{"0":1,"1":1,"64":1,"75":1,"78":1,"88":1}}],["white",{"2":{"92":1,"93":1}}],["while",{"2":{"71":1}}],["which",{"2":{"9":1,"16":1,"17":2,"28":1,"35":2,"50":1,"56":1,"59":1,"60":1,"64":3,"74":5,"75":4,"88":1}}],["whose",{"0":{"34":1,"35":1}}],["whole",{"2":{"8":3}}],["whether",{"2":{"75":2}}],["when",{"2":{"1":1,"6":1,"13":1,"64":1,"74":2,"75":1}}],["whereas",{"2":{"62":1}}],["where",{"2":{"0":1,"18":1,"35":4,"43":1,"59":1,"72":1,"74":1,"75":4}}],["wintri",{"0":{"92":1},"1":{"93":1,"94":1}}],["windowloopinds",{"2":{"75":1}}],["window",{"2":{"74":1,"75":1}}],["without",{"2":{"75":1}}],["within",{"2":{"58":1}}],["with",{"2":{"4":1,"5":1,"8":1,"10":1,"12":1,"13":1,"16":7,"17":4,"18":2,"19":1,"24":3,"27":1,"28":1,"35":6,"36":2,"37":3,"40":1,"41":3,"45":3,"46":1,"48":2,"49":2,"50":5,"52":3,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"61":1,"63":1,"66":1,"69":1,"70":2,"71":2,"72":1,"74":11,"75":1,"77":1,"81":4,"82":3,"86":1,"88":1,"90":2,"92":1}}],["will",{"2":{"0":1,"1":1,"4":1,"5":1,"13":1,"16":3,"17":1,"31":1,"35":1,"36":2,"37":2,"41":1,"42":1,"47":2,"69":3,"71":3,"72":1,"74":12,"75":3,"88":1}}],["wether",{"2":{"74":1}}],["weight=",{"2":{"74":1}}],["weight=nothing",{"2":{"74":1}}],["weight",{"0":{"48":1},"1":{"49":1,"50":1},"2":{"47":1,"49":1,"50":1}}],["weights",{"0":{"49":1},"2":{"45":3,"49":2,"50":1}}],["weightedmean",{"2":{"74":1}}],["weighted",{"0":{"50":1},"2":{"37":1,"43":1,"45":8,"50":8,"74":3}}],["well",{"2":{"37":1,"41":1,"71":1,"74":1}}],["welcome",{"2":{"6":1,"76":1}}],["were",{"2":{"13":2,"59":1,"75":1,"83":1}}],["we",{"2":{"0":1,"8":2,"9":1,"13":2,"14":1,"16":5,"17":5,"18":2,"24":2,"28":1,"30":1,"31":1,"32":1,"33":1,"35":2,"36":2,"37":5,"41":3,"45":1,"46":1,"47":2,"50":1,"52":1,"58":1,"64":1,"71":3,"72":4,"82":2,"83":1,"90":1}}],["oob",{"2":{"74":1}}],["o1",{"2":{"53":2,"55":2,"66":2,"70":1}}],["ocean",{"2":{"53":1,"55":1,"66":1,"70":1}}],["oct",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["occuring",{"2":{"4":1}}],["o",{"2":{"44":4,"50":4,"74":5}}],["ohlcv",{"2":{"41":3}}],["ouput",{"2":{"78":1}}],["our",{"2":{"36":1,"37":1,"84":1}}],["outcube",{"2":{"75":1}}],["outcubes",{"2":{"75":1}}],["outcs",{"2":{"75":1}}],["outsize",{"2":{"75":1}}],["outar",{"2":{"75":2}}],["out",{"2":{"44":1,"74":2,"75":1}}],["outtype",{"2":{"16":2,"74":1,"75":2}}],["outdims=outdims",{"2":{"17":1,"18":1}}],["outdims",{"2":{"16":4,"74":6}}],["outputcube",{"2":{"75":3}}],["outputs",{"2":{"16":1}}],["output",{"2":{"6":1,"16":3,"17":1,"18":3,"53":1,"55":1,"66":1,"70":1,"74":11,"75":9,"94":1}}],["optimal",{"2":{"75":1}}],["optifunc",{"2":{"75":1}}],["optionally",{"2":{"74":1}}],["option",{"2":{"32":1,"34":1}}],["options",{"2":{"29":1}}],["operation",{"2":{"75":1}}],["operations",{"0":{"16":1},"2":{"10":1,"45":1,"74":2,"75":3}}],["operates",{"2":{"74":1}}],["openinterval",{"2":{"59":1}}],["open",{"0":{"59":1},"2":{"0":2,"41":4,"52":2,"53":2,"54":1,"55":2,"59":2,"66":1,"70":1,"72":6,"74":3,"90":1}}],["obj",{"2":{"37":2,"83":1,"85":1}}],["objects",{"2":{"74":2}}],["object",{"2":{"11":1,"52":1,"74":5,"75":3}}],["obtain",{"0":{"29":1},"2":{"41":1,"47":1}}],["otherwise",{"2":{"74":1}}],["others",{"2":{"41":1}}],["other",{"0":{"86":1},"1":{"87":1,"88":1,"89":1},"2":{"19":1,"86":1,"88":1}}],["omit",{"2":{"18":1}}],["overview",{"0":{"87":1},"2":{"86":1,"87":1}}],["overwrite",{"0":{"69":1},"2":{"69":3,"74":4,"75":2}}],["overwrite=true",{"2":{"16":2,"69":2,"71":3}}],["over",{"0":{"16":1,"88":1},"2":{"10":1,"15":1,"18":1,"50":1,"74":8,"75":1,"88":1}}],["ormax",{"2":{"74":1}}],["orca2",{"2":{"53":1,"55":1,"66":1,"70":1}}],["orangered",{"2":{"37":1}}],["ordered",{"2":{"62":1,"63":1}}],["ordereddict",{"2":{"17":1}}],["orderedcollections",{"2":{"17":1}}],["order",{"2":{"16":1,"43":1,"72":1}}],["original",{"2":{"53":2,"56":4,"57":6,"58":6,"59":10}}],["originates",{"2":{"9":1}}],["origin",{"2":{"10":2,"12":1,"13":1,"18":1,"24":3,"25":1,"81":2}}],["or",{"0":{"31":1},"1":{"32":1,"33":1,"34":1,"35":1},"2":{"1":2,"6":1,"10":1,"13":2,"15":1,"22":1,"28":1,"33":1,"52":1,"55":2,"62":3,"65":2,"69":1,"74":21,"75":7,"80":1,"81":2}}],["once",{"2":{"50":1,"64":1,"75":1,"77":1}}],["onlinestat",{"2":{"74":2}}],["onlinestats",{"2":{"37":2}}],["only",{"2":{"6":1,"13":1,"14":1,"16":1,"17":1,"19":1,"24":2,"36":1,"71":1,"74":2}}],["on",{"2":{"1":2,"6":1,"7":1,"10":2,"13":2,"16":1,"18":2,"26":1,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"62":1,"66":1,"70":1,"71":1,"74":5,"75":4}}],["ones",{"2":{"28":1}}],["oneto",{"2":{"4":4,"5":4,"6":2,"20":2,"24":3,"27":9,"28":6,"39":1,"40":5,"71":6,"81":2}}],["one",{"0":{"39":1},"2":{"0":1,"7":1,"8":2,"14":2,"17":2,"37":1,"41":1,"46":1,"62":2,"63":1,"71":2,"74":8,"75":3,"86":1}}],["own",{"2":{"0":1}}],["offline=true",{"2":{"94":1}}],["offsets",{"2":{"75":1}}],["offset",{"2":{"13":1}}],["often",{"2":{"7":1}}],["of",{"0":{"11":1,"35":1,"43":1,"72":1,"87":2},"2":{"0":2,"1":1,"6":1,"8":3,"9":1,"10":2,"11":1,"12":1,"13":2,"14":1,"15":1,"17":7,"18":3,"19":1,"21":1,"22":1,"26":3,"27":3,"31":1,"32":2,"33":1,"34":1,"35":2,"36":1,"37":1,"43":1,"44":1,"48":1,"53":1,"55":3,"56":1,"58":1,"60":1,"62":7,"63":1,"64":2,"65":2,"66":1,"70":1,"71":1,"72":1,"73":1,"74":50,"75":42,"81":1,"82":2,"84":2,"85":1,"86":1,"87":1}}],["eo",{"2":{"86":1}}],["esdltutorials",{"2":{"86":1}}],["esm1",{"2":{"52":1,"90":2}}],["eltype",{"2":{"81":1}}],["elementtype",{"2":{"75":1}}],["element",{"2":{"8":1,"9":1,"10":2,"13":2,"14":1,"16":3,"17":2,"29":1,"37":1,"45":2,"46":1,"47":1,"48":7,"49":2,"50":3,"57":2,"60":1,"63":1,"64":2,"74":1,"75":1,"84":1}}],["elements",{"0":{"11":1,"57":1},"2":{"8":1,"12":1,"13":2,"18":1,"55":1,"62":1,"74":1,"75":1}}],["empty",{"2":{"75":1}}],["embeds",{"2":{"74":1}}],["either",{"2":{"74":2}}],["error",{"2":{"69":1}}],["et",{"2":{"53":1,"55":1,"64":1,"66":1,"70":1}}],["edu",{"2":{"53":1,"55":1,"63":1,"66":1}}],["equivalent",{"2":{"50":1,"60":1}}],["equally",{"2":{"0":1}}],["effectively",{"2":{"36":1}}],["env",{"2":{"78":1}}],["enabling",{"2":{"24":1}}],["enter",{"2":{"80":1}}],["entire",{"2":{"17":1,"19":1,"67":1,"68":1}}],["entries",{"2":{"17":1,"41":1,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"72":1,"74":1,"81":1}}],["entry",{"2":{"10":1,"12":1,"13":1,"16":2,"24":2,"45":2,"46":1,"48":2,"49":2,"50":3,"74":1,"77":3}}],["enumerate",{"2":{"17":2,"50":2}}],["end",{"2":{"13":1,"16":1,"17":4,"18":2,"36":1,"45":2,"50":2,"84":2,"94":1}}],["exists",{"2":{"69":1,"74":1,"75":1}}],["existing",{"0":{"8":1},"2":{"69":1,"70":1}}],["exportable=true",{"2":{"94":1}}],["expression",{"2":{"74":1}}],["experiment",{"2":{"53":3,"55":3,"66":3,"70":3}}],["explicitly",{"2":{"13":1,"28":1,"31":1,"75":1}}],["external",{"2":{"52":1,"90":1}}],["extension",{"2":{"74":2}}],["extent",{"2":{"21":2}}],["extended",{"2":{"16":1,"74":1,"75":2}}],["extracts",{"2":{"75":1}}],["extract",{"0":{"27":1},"1":{"28":1},"2":{"75":1}}],["extra",{"2":{"18":1}}],["executes",{"2":{"74":1}}],["execute",{"2":{"18":1}}],["exactly",{"2":{"5":1,"29":1,"41":1}}],["examples",{"2":{"6":1,"29":2,"42":1,"53":1,"55":1,"66":1,"77":1}}],["example",{"2":{"0":1,"1":1,"5":1,"10":1,"18":2,"28":1,"34":1,"35":1,"36":1,"37":1,"43":1,"53":1,"55":2,"62":2,"63":1,"64":1,"66":2,"74":3,"75":1,"77":2,"81":2}}],["e",{"2":{"7":1,"8":1,"10":1,"11":1,"13":1,"17":2,"18":1,"21":1,"22":1,"24":1,"32":1,"60":1,"62":1,"65":1,"69":1,"74":6,"75":1,"78":1,"81":1}}],["easier",{"2":{"24":1,"55":1}}],["easily",{"2":{"0":1,"18":1}}],["easy",{"2":{"21":1,"22":1}}],["each",{"2":{"4":1,"5":1,"10":1,"13":1,"17":5,"18":2,"36":2,"37":2,"43":1,"47":1,"63":1,"65":1,"74":3,"75":3,"81":1}}],["everywhere",{"2":{"18":2}}],["every",{"2":{"0":1,"10":1,"13":1,"74":1}}],["features",{"2":{"87":1}}],["feb",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["fallback",{"2":{"75":1}}],["falls",{"2":{"74":1}}],["false",{"2":{"49":1,"50":1,"69":2,"74":3,"75":1}}],["faq",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["faster",{"2":{"75":1}}],["fastest",{"2":{"1":1}}],["fast",{"2":{"1":1,"13":1}}],["frame",{"2":{"88":1}}],["frames",{"2":{"62":1}}],["front",{"2":{"75":1}}],["from",{"0":{"27":1,"29":2,"41":1,"43":1},"1":{"28":1},"2":{"0":1,"8":1,"9":1,"19":1,"27":1,"28":1,"29":4,"35":3,"41":2,"59":1,"64":2,"72":1,"74":6,"75":6,"81":1,"84":1}}],["fr",{"2":{"53":1,"55":1,"66":1,"70":1}}],["frequently",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["fu",{"2":{"75":1}}],["funtion",{"2":{"84":1}}],["fun",{"2":{"74":4}}],["functionality",{"0":{"87":1}}],["functions",{"2":{"10":2,"62":2,"73":1,"74":1,"75":1}}],["function",{"0":{"37":1},"2":{"0":1,"1":1,"13":2,"15":1,"16":6,"18":6,"27":2,"30":1,"36":1,"37":1,"41":1,"42":1,"45":1,"47":1,"50":1,"59":1,"69":1,"71":1,"74":24,"75":13}}],["future",{"2":{"44":1}}],["further",{"2":{"13":1,"86":1}}],["flag",{"2":{"75":3}}],["float32",{"2":{"16":6,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5,"71":2,"72":4,"75":1}}],["float64",{"2":{"8":1,"9":1,"10":3,"12":3,"13":3,"14":4,"17":9,"20":2,"21":2,"22":4,"24":6,"25":2,"27":1,"28":3,"30":4,"36":12,"37":5,"41":2,"45":3,"46":2,"49":3,"50":6,"52":4,"53":4,"55":2,"56":4,"57":2,"58":6,"59":10,"60":3,"66":2,"70":2,"74":1,"75":1,"81":7,"84":2,"90":2}}],["flexible",{"2":{"9":1,"15":1}}],["folder",{"2":{"78":1}}],["follow",{"2":{"78":1,"86":1}}],["follows",{"2":{"16":2,"45":1,"50":1,"72":1}}],["following",{"2":{"2":1,"5":1,"6":1,"16":1,"18":1,"28":1,"42":1,"43":1,"44":1,"74":2,"75":4,"86":1}}],["found",{"2":{"74":1,"75":1}}],["fourth",{"2":{"53":2,"55":2,"66":2,"70":2}}],["fontsize=24",{"2":{"91":1}}],["fontsize=18",{"2":{"50":1}}],["font=",{"2":{"50":1}}],["forwarded",{"2":{"74":1}}],["forwardordered",{"2":{"4":4,"5":4,"6":2,"8":1,"9":1,"10":3,"12":3,"13":3,"14":3,"16":9,"17":9,"20":2,"21":6,"22":4,"24":9,"25":3,"27":9,"28":6,"29":2,"30":4,"32":14,"34":6,"35":10,"36":9,"37":5,"39":1,"40":5,"41":4,"45":3,"46":2,"48":2,"49":1,"50":7,"52":6,"53":6,"55":3,"56":6,"57":4,"58":9,"59":15,"60":2,"66":3,"70":6,"71":6,"81":5,"84":1,"90":3}}],["force",{"2":{"74":1}}],["forcing",{"2":{"52":1,"90":1}}],["forms",{"2":{"74":1,"75":2}}],["format",{"2":{"69":1,"74":1,"84":1}}],["formal",{"2":{"64":1}}],["former",{"2":{"27":1}}],["for",{"0":{"6":1,"83":1},"1":{"84":1,"85":1},"2":{"0":2,"1":3,"4":1,"5":1,"6":1,"17":4,"18":1,"32":1,"34":2,"35":2,"36":4,"37":6,"41":5,"44":1,"48":1,"50":3,"53":1,"55":1,"59":1,"60":1,"62":4,"63":3,"64":1,"66":1,"69":1,"70":1,"71":2,"74":19,"75":16,"83":1,"84":2,"86":1}}],["f",{"2":{"2":2,"16":3}}],["field",{"2":{"74":1}}],["fields",{"2":{"37":1,"74":1,"75":4}}],["figure=",{"2":{"85":1}}],["figure",{"2":{"50":2,"83":1,"85":1,"91":1,"92":1,"93":1,"94":1}}],["fig",{"2":{"37":3,"50":8,"83":1,"85":1,"91":2,"92":2,"93":2,"94":3}}],["filterig",{"2":{"84":1}}],["filter",{"2":{"74":2}}],["fillarrays",{"2":{"71":3}}],["fill",{"2":{"71":1,"74":1,"75":1}}],["fillvalue=",{"2":{"75":1}}],["fillvalue",{"2":{"44":3,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["filling",{"2":{"23":1,"24":1}}],["filename",{"2":{"44":2,"74":1}}],["files",{"0":{"89":1},"2":{"7":1,"51":1,"54":1,"75":2,"78":1}}],["file",{"2":{"2":1,"7":1,"8":2,"9":2,"10":2,"12":2,"13":2,"14":4,"16":10,"17":4,"20":2,"21":2,"22":3,"24":4,"27":2,"28":6,"29":2,"30":2,"32":10,"35":1,"36":6,"37":6,"48":2,"52":2,"53":4,"56":4,"57":6,"58":6,"59":10,"69":2,"71":3,"74":2,"77":4,"81":4,"84":2}}],["findaxis",{"2":{"75":1}}],["findall",{"2":{"17":1,"84":1}}],["find",{"2":{"31":1,"75":1,"86":1}}],["finalizer",{"2":{"75":1}}],["finalize",{"2":{"75":1}}],["finally",{"2":{"17":1,"74":1}}],["final",{"2":{"17":1}}],["firstly",{"2":{"32":1}}],["first",{"2":{"8":4,"16":3,"17":1,"37":1,"50":1,"72":1,"74":4,"75":1,"77":1,"81":1,"90":1}}],["fitting",{"2":{"74":1}}],["fittable",{"2":{"74":2}}],["fitcube",{"2":{"37":2}}],["fitsym",{"2":{"74":4}}],["fits",{"2":{"19":1}}],["fit",{"2":{"1":1,"62":1}}],["t=union",{"2":{"75":1}}],["typing",{"2":{"80":1}}],["typically",{"2":{"74":1}}],["type",{"2":{"28":1,"62":1,"64":1,"74":12,"75":8,"81":1,"82":1}}],["types",{"0":{"61":1},"1":{"62":1,"63":1,"64":1,"65":1},"2":{"19":2,"21":1,"22":1,"57":1,"63":1,"74":2,"82":1}}],["tutorial",{"2":{"86":2,"87":1,"88":1}}],["tutorials",{"0":{"86":1},"1":{"87":1,"88":1,"89":1},"2":{"59":1,"86":3}}],["turn",{"2":{"74":1}}],["tuple",{"2":{"2":3,"4":1,"5":1,"6":1,"45":2,"46":1,"48":2,"49":3,"50":5,"74":5,"75":3}}],["tbl",{"2":{"37":2}}],["target",{"2":{"75":1}}],["tab",{"2":{"74":4}}],["tables",{"2":{"88":1}}],["tableaggregator",{"2":{"74":1}}],["table",{"0":{"88":1},"2":{"37":2,"52":1,"53":2,"55":2,"66":2,"70":2,"74":4,"75":1,"90":1}}],["tas",{"2":{"52":5,"90":5}}],["tair",{"2":{"50":1,"74":1}}],["ta",{"2":{"41":3}}],["takes",{"2":{"74":4}}],["taken",{"2":{"35":2}}],["take",{"2":{"16":1,"74":1,"75":2,"78":1}}],["tesselation",{"2":{"94":1}}],["test",{"2":{"75":1,"90":1}}],["testrange",{"2":{"75":1}}],["terminal",{"2":{"78":1}}],["text",{"2":{"77":1}}],["tensors",{"2":{"62":1}}],["tell",{"2":{"31":1}}],["temporary",{"2":{"75":1}}],["temporal",{"2":{"36":1,"42":1,"62":1}}],["tempo",{"2":{"45":6,"48":4,"49":1}}],["temp",{"2":{"9":2}}],["temperature=temperature",{"2":{"35":1}}],["temperature",{"2":{"9":2,"35":4,"50":2,"52":3,"53":2,"56":5,"57":6,"58":6,"59":10,"62":1,"63":1,"64":1,"81":4}}],["tempname",{"2":{"2":1,"4":1,"5":1,"6":1}}],["tip",{"2":{"82":1}}],["tidy",{"2":{"74":1}}],["ticks",{"2":{"62":1}}],["ticks=false",{"2":{"50":1}}],["tick",{"2":{"60":1,"65":1,"81":1}}],["tiff",{"0":{"89":1}}],["tif",{"2":{"54":2}}],["title",{"2":{"50":1,"53":1,"55":1,"66":1,"70":1,"77":1}}],["ti=at",{"2":{"50":3}}],["ti=>cyclicbins",{"2":{"45":2,"46":1,"48":2,"49":2,"50":3}}],["ti",{"2":{"21":4,"45":15,"46":2,"47":1,"48":8,"49":3,"50":6,"52":2,"53":2,"55":1,"56":2,"57":2,"58":3,"59":5,"66":1,"70":1,"90":2}}],["time1",{"2":{"57":2}}],["timearray",{"0":{"41":1},"2":{"41":3}}],["time=1",{"2":{"81":1}}],["time=date",{"2":{"32":1}}],["time=at",{"2":{"32":1}}],["time=between",{"2":{"32":1}}],["time",{"0":{"43":1},"2":{"1":1,"7":1,"8":4,"9":3,"10":3,"12":1,"13":1,"14":7,"16":14,"17":8,"18":5,"21":2,"24":3,"25":1,"30":2,"32":8,"34":4,"35":7,"36":4,"37":3,"41":5,"46":1,"47":1,"50":1,"52":2,"53":1,"56":2,"57":4,"58":3,"59":5,"62":2,"63":1,"74":4,"81":4,"83":1,"84":4,"90":2}}],["timestamp",{"2":{"41":1}}],["timestep",{"2":{"37":1}}],["timeseries",{"2":{"41":3}}],["times",{"2":{"0":1}}],["treat",{"2":{"74":1}}],["treatment",{"2":{"74":1,"75":1}}],["treated",{"2":{"52":1}}],["tries",{"2":{"74":1}}],["translate",{"2":{"92":1,"93":1}}],["transformed",{"2":{"53":1,"55":1,"66":1,"70":1}}],["transformations",{"2":{"92":1}}],["transformation",{"2":{"17":1}}],["transform",{"2":{"17":2}}],["track",{"2":{"74":1}}],["true",{"2":{"12":1,"69":1,"71":1,"74":4,"75":1,"94":1}}],["tspan",{"2":{"16":1}}],["t",{"2":{"16":4,"32":1,"34":2,"35":2,"37":3,"53":1,"56":2,"57":3,"58":3,"59":5,"74":1,"75":2,"83":1,"84":1}}],["two",{"2":{"8":1,"9":1,"29":2,"30":1,"62":1,"75":1}}],["todo",{"2":{"84":1}}],["toghether",{"2":{"75":1}}],["together",{"2":{"41":1,"64":1}}],["toy",{"2":{"71":1}}],["touches",{"2":{"59":1}}],["tolerances",{"2":{"58":1}}],["tos",{"2":{"53":4,"55":2,"56":4,"57":4,"58":3,"59":9,"60":2,"66":2,"67":2,"68":2,"70":1}}],["top",{"2":{"50":1}}],["too",{"2":{"35":1,"62":1}}],["to",{"0":{"9":1,"38":1,"70":1,"76":1,"77":1},"1":{"39":1,"40":1,"77":1,"78":2},"2":{"0":4,"1":4,"3":1,"4":1,"6":2,"7":1,"8":1,"9":1,"10":8,"12":1,"15":1,"16":2,"17":2,"18":6,"19":3,"20":2,"22":3,"23":1,"26":2,"27":2,"29":3,"30":1,"32":2,"34":2,"35":6,"36":1,"37":1,"41":2,"42":1,"43":3,"44":2,"46":1,"47":1,"50":1,"51":1,"52":3,"53":1,"55":3,"59":1,"60":1,"61":1,"62":5,"63":3,"64":2,"65":2,"66":1,"67":2,"68":2,"69":1,"70":2,"71":4,"72":3,"74":47,"75":19,"77":2,"78":3,"82":2,"86":1,"88":3,"90":2,"94":1}}],["though",{"2":{"71":1}}],["those",{"2":{"11":1,"19":1,"21":1,"22":1,"63":1,"72":1}}],["through",{"2":{"74":5,"75":5,"80":1}}],["thrown",{"2":{"69":1}}],["three",{"2":{"31":1,"63":1,"83":1}}],["threads",{"2":{"74":2}}],["thread",{"2":{"18":1}}],["than",{"2":{"19":1,"31":1,"36":1,"37":1}}],["that",{"2":{"0":1,"9":2,"10":1,"13":1,"16":5,"17":2,"18":1,"19":1,"28":1,"30":1,"33":1,"35":2,"37":1,"41":1,"43":1,"46":1,"49":1,"60":1,"62":1,"63":2,"65":1,"71":2,"74":13,"75":13,"86":1,"88":1}}],["things",{"2":{"26":1}}],["think",{"2":{"1":1}}],["thinking",{"2":{"1":1}}],["this",{"2":{"0":1,"1":1,"4":1,"7":1,"10":1,"13":2,"16":4,"17":3,"18":1,"19":1,"23":1,"26":1,"29":1,"34":1,"35":2,"36":2,"37":2,"41":1,"43":1,"47":2,"51":1,"52":1,"54":1,"59":1,"61":1,"64":1,"72":2,"73":2,"74":6,"75":10,"77":1,"78":2,"87":1,"88":1}}],["they",{"2":{"41":4}}],["their",{"0":{"34":1,"35":1},"2":{"33":1,"35":1,"62":1,"74":3,"75":2}}],["then",{"2":{"17":2,"28":1,"36":1,"41":1,"71":1,"72":1,"78":2,"80":1}}],["thereby",{"2":{"74":1}}],["therefore",{"2":{"37":1,"82":1}}],["there",{"2":{"14":2,"22":1,"29":1,"41":2,"74":1}}],["theme",{"2":{"50":2}}],["them",{"2":{"7":1,"10":1,"31":1,"72":1,"74":1}}],["these",{"2":{"0":1,"6":1,"29":1,"31":1,"60":1,"62":1}}],["the",{"0":{"27":1,"29":1,"37":1,"44":1,"84":1,"87":1},"1":{"28":1},"2":{"0":5,"1":4,"2":3,"4":1,"5":4,"6":4,"8":6,"9":3,"10":1,"11":1,"13":3,"14":2,"15":1,"16":12,"17":14,"18":7,"19":2,"22":1,"24":3,"26":1,"27":3,"28":5,"29":3,"30":2,"31":2,"32":9,"34":3,"35":10,"36":3,"37":10,"41":7,"42":2,"43":5,"44":4,"45":2,"46":1,"47":2,"48":2,"49":2,"50":9,"53":1,"55":1,"56":5,"57":3,"58":5,"59":6,"60":1,"61":1,"62":5,"63":4,"64":4,"69":3,"70":1,"71":10,"72":2,"74":116,"75":83,"76":1,"77":1,"78":6,"80":2,"81":6,"82":8,"83":1,"84":4,"86":6,"87":1,"88":5,"90":1}}],["switched",{"2":{"82":1}}],["syntax",{"2":{"82":1,"86":1}}],["system",{"2":{"78":1}}],["symbol",{"2":{"10":1,"12":1,"13":1,"24":2,"41":5,"45":4,"46":2,"47":2,"48":4,"49":4,"50":6,"74":3,"75":1}}],["src",{"2":{"77":1}}],["sres",{"2":{"53":2,"55":2,"66":2,"70":2}}],["skipped",{"2":{"74":1}}],["skip",{"2":{"74":1}}],["skipmissing",{"2":{"18":1,"36":1}}],["skeleton=a",{"2":{"71":1}}],["skeleton=true",{"2":{"71":2}}],["skeleton=false",{"2":{"69":1,"74":1}}],["skeleton",{"0":{"71":1},"2":{"71":8,"72":4}}],["ssp585",{"2":{"52":1,"90":2}}],["scene",{"2":{"94":3}}],["scenarios",{"2":{"90":1}}],["scenariomip",{"2":{"52":1,"90":2}}],["scripts",{"2":{"78":1}}],["scope",{"2":{"74":1,"75":1}}],["scalar",{"2":{"52":1}}],["scattered",{"2":{"7":1}}],["snow3",{"2":{"37":1}}],["snippet",{"2":{"6":1}}],["small",{"2":{"26":1,"41":1}}],["slightly",{"2":{"86":1}}],["slicing",{"2":{"16":1}}],["slices",{"2":{"74":3}}],["slice",{"2":{"16":1,"90":4,"91":1}}],["slow",{"2":{"35":1}}],["slurmmanager",{"2":{"18":1}}],["shinclude",{"2":{"78":1}}],["shdocs>",{"2":{"78":1}}],["shnpm",{"2":{"78":2}}],["should",{"2":{"32":1,"41":1,"44":1,"74":3,"75":1,"77":1,"78":1}}],["shown",{"2":{"74":1}}],["showprog",{"2":{"74":1}}],["shows",{"2":{"50":1}}],["showing",{"2":{"41":1}}],["show",{"2":{"18":1,"72":1,"94":1}}],["shading=false",{"2":{"92":1,"93":1,"94":1}}],["shall",{"2":{"74":5,"75":1}}],["shares",{"2":{"35":1}}],["share",{"0":{"34":1,"35":1},"2":{"33":1,"35":1,"63":1,"74":1}}],["shared",{"2":{"4":1,"5":1,"6":1,"25":1,"30":1,"34":2,"35":3,"39":1,"40":1,"41":2,"52":1,"53":1,"55":1,"66":1,"70":1,"71":1,"90":1}}],["shape",{"2":{"6":1}}],["sure",{"2":{"94":1}}],["surface",{"2":{"50":2,"52":2,"53":2,"56":5,"57":6,"58":6,"59":10,"92":1,"93":1}}],["such",{"2":{"59":1,"74":1,"82":1}}],["subcubes",{"2":{"74":1}}],["subtype",{"2":{"62":1,"75":1,"82":1}}],["subtables",{"2":{"37":1}}],["subarray",{"2":{"49":1,"50":1}}],["subsetextensions",{"2":{"75":1}}],["subsetcube",{"2":{"74":1}}],["subseting",{"2":{"60":1}}],["subsetting",{"0":{"32":1,"33":1,"34":1,"35":1},"1":{"34":1,"35":1},"2":{"52":1,"53":1,"75":1,"84":1}}],["subset",{"0":{"31":1},"1":{"32":1,"33":1,"34":1,"35":1},"2":{"32":5,"35":4,"55":1,"58":1,"74":1,"75":1,"90":1}}],["subsets",{"2":{"15":1,"65":1}}],["supposed",{"2":{"74":1}}],["support",{"2":{"22":1,"41":1}}],["supertype",{"2":{"21":1,"22":1}}],["sum",{"2":{"17":2,"36":1,"45":4,"48":2,"49":4,"50":2}}],["suggestions",{"2":{"6":1}}],["s",{"2":{"10":1,"16":3,"28":1,"30":1,"32":1,"34":1,"35":2,"50":7,"55":1,"65":1,"71":1,"74":2,"75":1,"84":1}}],["style",{"0":{"88":1}}],["st",{"2":{"82":1}}],["stdzero",{"2":{"74":1}}],["stock3",{"2":{"41":4}}],["stock2",{"2":{"41":4}}],["stock1",{"2":{"41":4}}],["stocks",{"2":{"41":7}}],["storing",{"2":{"63":1}}],["storage",{"2":{"11":1,"52":1}}],["stored",{"2":{"62":3,"75":2}}],["stores",{"2":{"62":1,"74":1}}],["store",{"2":{"0":1,"52":4,"62":1,"63":1,"90":2}}],["struct",{"2":{"74":1,"75":4}}],["structures",{"2":{"61":1}}],["structure",{"2":{"28":2,"41":1,"64":1}}],["string",{"2":{"8":1,"9":2,"10":1,"12":1,"13":1,"14":2,"16":5,"17":6,"20":1,"21":2,"22":3,"24":3,"27":1,"28":3,"29":1,"30":2,"32":5,"36":3,"37":3,"45":1,"46":1,"48":2,"49":1,"50":1,"52":2,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"69":1,"70":1,"71":1,"74":6,"75":4,"81":4,"84":1,"90":1}}],["stable",{"2":{"82":1}}],["standard",{"2":{"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["standards",{"2":{"52":1,"53":1,"55":1,"66":1,"70":1,"90":1}}],["statistics",{"2":{"14":1,"18":1,"37":3,"42":1,"83":1}}],["started",{"0":{"79":1},"1":{"80":1,"81":1,"82":1}}],["start=12",{"2":{"45":2,"46":1,"48":2,"49":2,"50":3}}],["start=december",{"2":{"45":3,"48":1}}],["start",{"2":{"10":1,"32":1,"72":1}}],["still",{"2":{"8":1,"17":1,"63":1,"86":1}}],["step=3",{"2":{"45":2,"46":1,"48":2,"49":2,"50":3}}],["steps",{"2":{"10":1,"14":1,"50":1,"74":1,"78":1}}],["step",{"2":{"7":1,"14":1,"36":2,"74":1,"75":2,"90":1}}],["sphere",{"0":{"94":1},"2":{"94":3}}],["split",{"2":{"74":1}}],["splitted",{"2":{"2":1}}],["special",{"2":{"57":1,"74":1,"75":1}}],["specifiers",{"2":{"75":1}}],["specifier",{"2":{"74":1}}],["specifies",{"2":{"74":3}}],["specified",{"2":{"74":7,"75":1}}],["specific",{"2":{"32":1,"74":2}}],["specifying",{"2":{"74":2,"75":1}}],["specify",{"2":{"24":1,"74":1}}],["specs",{"2":{"52":1,"90":1}}],["spectral",{"2":{"50":1}}],["sparse",{"2":{"62":1}}],["spatio",{"2":{"36":1}}],["spatial",{"2":{"1":1,"14":1,"17":5,"18":1,"42":1,"62":1}}],["span",{"2":{"32":1,"83":1}}],["space",{"2":{"1":1,"16":1}}],["sampled",{"2":{"4":4,"5":4,"6":2,"8":1,"9":1,"10":3,"12":3,"13":3,"14":3,"16":9,"17":8,"20":2,"21":6,"22":4,"24":9,"25":3,"27":9,"28":6,"29":2,"30":3,"32":14,"34":6,"35":10,"36":9,"37":5,"39":1,"40":5,"41":4,"45":3,"46":2,"48":2,"49":1,"50":7,"52":6,"53":6,"55":3,"56":6,"57":4,"58":9,"59":15,"60":2,"66":3,"70":6,"71":6,"81":5,"84":1,"90":3}}],["same",{"2":{"0":1,"2":1,"5":1,"6":1,"9":1,"16":1,"17":2,"21":1,"22":1,"28":2,"29":2,"30":1,"35":1,"41":2,"56":1,"57":1,"58":1,"62":1,"63":3,"64":2,"74":1,"75":1,"78":1}}],["saves",{"2":{"69":1,"74":1}}],["save",{"0":{"71":1},"2":{"12":1,"22":1,"67":2,"68":2,"71":1,"74":2}}],["savecube",{"2":{"2":1,"67":1,"68":1,"71":1,"74":2}}],["savedataset",{"2":{"4":1,"5":1,"6":1,"69":2,"70":1,"71":2,"74":2,"75":1}}],["saved",{"2":{"2":1,"11":1,"69":1}}],["saving",{"2":{"1":1,"4":1,"5":1,"6":1,"16":1}}],["serve",{"2":{"75":1}}],["series",{"0":{"43":1},"2":{"18":1}}],["sequence",{"2":{"62":1}}],["seaborn",{"2":{"91":1,"92":1,"93":1,"94":1}}],["searching",{"2":{"74":1}}],["search",{"2":{"74":1}}],["sea",{"2":{"53":3,"55":1,"56":5,"57":6,"58":6,"59":10,"66":1,"70":1}}],["season",{"2":{"45":1,"48":2,"49":1}}],["seasons",{"0":{"45":1,"47":1,"50":1},"1":{"46":1,"47":1},"2":{"45":9,"48":1,"50":5}}],["seasonal",{"0":{"43":1,"83":1,"85":1},"1":{"84":1,"85":1},"2":{"43":1,"49":1,"50":1,"83":1,"84":4}}],["sebastien",{"2":{"53":2,"55":2,"66":2,"70":2}}],["separate",{"2":{"74":1,"75":1}}],["separated",{"2":{"63":1}}],["separately",{"2":{"5":1,"17":1,"18":1}}],["sep",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["selected",{"2":{"75":1,"83":1}}],["select",{"0":{"55":1,"56":1,"57":1,"58":1},"1":{"56":1,"57":1,"58":1,"59":1,"60":1},"2":{"35":1,"55":1}}],["selectors",{"2":{"59":1}}],["selector",{"2":{"35":1,"58":1}}],["selection",{"2":{"35":2}}],["selecting",{"2":{"32":1,"34":1,"35":1}}],["see",{"2":{"16":1,"59":1,"74":1,"82":1}}],["second",{"2":{"8":3,"74":1}}],["section",{"2":{"7":1,"10":1,"19":1,"23":1,"26":1,"41":1,"51":1,"61":1,"73":1}}],["setting",{"2":{"69":1,"74":1,"75":1}}],["sets",{"2":{"6":1,"44":1}}],["set",{"0":{"4":1,"5":1,"6":1},"2":{"4":1,"5":1,"17":1,"52":1,"69":1,"74":1,"75":2,"78":1}}],["setchunks",{"2":{"1":1,"2":2,"3":1,"4":1,"5":1,"6":1,"74":1,"75":1}}],["several",{"0":{"16":1},"2":{"0":1,"16":1,"30":1,"33":1}}],["sin",{"2":{"83":1}}],["sink",{"2":{"75":1}}],["single",{"0":{"83":1},"1":{"84":1,"85":1},"2":{"0":1,"7":1,"8":1,"64":1,"67":1,"68":1,"74":6,"75":1}}],["simulate",{"2":{"41":1}}],["simplicity",{"2":{"83":1}}],["simply",{"2":{"18":1,"72":1,"78":1}}],["simple",{"2":{"16":1,"26":1,"81":1}}],["situations",{"2":{"1":1}}],["size=",{"2":{"92":1,"93":1,"94":1}}],["sizes",{"2":{"2":1,"74":2,"75":2}}],["size",{"2":{"0":1,"1":1,"4":1,"5":1,"8":2,"9":2,"10":2,"12":2,"13":2,"14":4,"16":10,"17":4,"20":2,"21":2,"22":2,"24":4,"27":2,"28":6,"29":2,"30":2,"32":10,"36":6,"37":6,"48":2,"50":1,"52":2,"53":2,"56":4,"57":6,"58":6,"59":10,"71":2,"72":1,"74":3,"75":4,"81":5,"83":1,"84":3,"85":1,"91":1}}],["sosstsst",{"2":{"53":1,"56":2,"57":3,"58":3,"59":5}}],["software",{"2":{"53":1,"55":1,"66":1}}],["sort",{"2":{"17":1}}],["so",{"2":{"2":1,"18":1,"31":1,"35":1,"74":1,"75":1}}],["source",{"2":{"0":2,"53":1,"55":1,"66":1,"69":1,"70":1,"74":24,"75":24}}],["sometimes",{"2":{"71":1,"88":1}}],["some",{"0":{"35":1},"2":{"0":1,"11":1,"33":1,"35":1,"36":1,"41":2,"50":1,"74":1,"83":1,"92":1}}],["auto",{"2":{"74":1}}],["aug",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["again",{"2":{"69":1,"72":1}}],["agreement",{"2":{"50":1}}],["aggregation",{"2":{"18":1}}],["aggregate",{"2":{"17":1}}],["air",{"2":{"50":2,"52":3}}],["api",{"0":{"73":1,"74":1,"75":1},"1":{"74":1,"75":1}}],["apr",{"2":{"45":4,"46":2,"47":1,"48":4,"49":4,"50":6}}],["appropriate",{"2":{"77":1}}],["approximated",{"2":{"75":1}}],["approx",{"2":{"74":1,"75":1}}],["approach",{"2":{"9":1}}],["append=true",{"2":{"70":2}}],["append",{"0":{"70":1},"2":{"69":1,"74":1}}],["apply",{"0":{"36":1},"2":{"10":2,"13":1,"15":1,"18":1,"50":1,"84":1}}],["applies",{"2":{"13":1}}],["applied",{"2":{"0":1,"3":1,"4":1,"17":1,"74":2,"75":1}}],["applications",{"2":{"0":1}}],["a3",{"2":{"25":4}}],["a2",{"2":{"24":1,"25":3,"53":2,"55":2,"66":2,"70":2,"81":1}}],["a1",{"2":{"24":1}}],["abstractdict",{"2":{"74":1,"75":3}}],["abstractdimarray",{"2":{"21":1,"22":1,"62":1}}],["about",{"2":{"1":2,"31":1,"58":1,"81":1,"87":1}}],["above",{"2":{"0":1,"5":1,"16":1,"71":1,"80":1}}],["atol",{"2":{"58":1}}],["atmosphere",{"2":{"53":1,"55":1,"66":1,"70":1}}],["atmos",{"2":{"52":1,"90":1}}],["attributes",{"2":{"50":1,"74":1,"75":1}}],["at",{"2":{"17":4,"22":1,"35":1,"41":3,"50":1,"53":2,"55":1,"56":2,"57":6,"58":7,"59":5,"63":1,"64":2,"66":1,"69":2,"70":1,"74":3,"75":2,"76":1,"77":2,"78":2,"81":1,"86":2}}],["after",{"2":{"14":1,"16":1,"54":1,"74":3}}],["addargs",{"2":{"74":3,"75":1}}],["adds",{"2":{"62":2,"65":1}}],["addprocs",{"2":{"18":2}}],["addition",{"2":{"17":1,"19":1,"62":1}}],["additional",{"2":{"4":3,"5":3,"9":1,"16":1,"35":10,"40":4,"41":4,"52":2,"70":3,"74":4,"75":3,"90":2}}],["added",{"2":{"15":1,"70":1,"74":1,"75":1}}],["add",{"2":{"6":1,"10":1,"12":1,"36":1,"77":2,"80":2,"92":1}}],["asaxisarray",{"2":{"74":1}}],["assemble",{"2":{"81":1}}],["assessment",{"2":{"53":2,"55":2,"66":2,"70":2}}],["associated",{"2":{"74":1}}],["assign",{"0":{"38":1},"1":{"39":1,"40":1}}],["aspect=dataaspect",{"2":{"50":1,"91":1}}],["asked",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["as",{"2":{"5":1,"12":1,"16":5,"17":1,"18":1,"21":1,"22":2,"28":2,"29":1,"35":1,"37":1,"41":2,"45":2,"50":1,"52":1,"53":1,"54":1,"56":1,"59":1,"60":1,"62":1,"65":1,"71":1,"72":1,"74":11,"75":3,"82":1,"88":1,"90":1}}],["axs",{"2":{"44":1,"50":9}}],["ax",{"2":{"37":1,"83":3,"85":3,"91":1,"92":3,"93":3,"94":5}}],["axlist",{"2":{"10":2,"17":2,"18":2,"24":2,"25":1,"30":3,"75":5,"81":3}}],["axessmall",{"2":{"75":2}}],["axes",{"0":{"27":1,"29":1},"1":{"28":1},"2":{"4":4,"5":4,"6":1,"24":1,"25":1,"27":2,"28":1,"29":2,"32":2,"34":5,"35":13,"39":1,"40":5,"41":8,"52":3,"53":1,"55":2,"62":2,"66":1,"70":4,"71":1,"74":15,"75":11,"81":1,"84":2,"90":3}}],["axislegend",{"2":{"85":1}}],["axis=false",{"2":{"94":1}}],["axis=",{"2":{"83":1}}],["axisdescriptor",{"2":{"75":1}}],["axisdesc",{"2":{"74":3}}],["axis",{"0":{"4":1},"2":{"4":1,"9":2,"16":3,"29":1,"32":1,"34":1,"35":7,"41":1,"50":1,"60":1,"65":1,"71":1,"74":16,"75":14,"81":1,"85":1,"90":1,"91":1}}],["always",{"2":{"74":2,"75":1,"76":1,"82":1}}],["already",{"2":{"69":1,"74":1,"75":1}}],["al",{"2":{"53":1,"55":1,"64":1,"66":1,"70":1}}],["alternatives",{"2":{"74":1}}],["alternatively",{"2":{"0":1,"2":1,"74":1,"80":1}}],["altered",{"2":{"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["although",{"2":{"41":1,"59":1}}],["algebra",{"0":{"36":1},"2":{"36":1}}],["along",{"0":{"8":1},"2":{"8":1,"16":1,"74":3,"75":2,"86":1}}],["allaxes",{"2":{"75":1}}],["allinaxes",{"2":{"75":1}}],["allmissing",{"2":{"74":1}}],["allocate",{"2":{"71":1}}],["allocation",{"2":{"17":1}}],["allow",{"2":{"75":1}}],["allowing",{"2":{"21":1,"22":1,"63":1}}],["allows",{"2":{"18":1}}],["all",{"0":{"6":1,"34":1,"35":1},"2":{"4":1,"6":2,"10":1,"12":1,"13":1,"14":2,"17":1,"18":4,"33":1,"35":2,"41":3,"50":2,"54":1,"59":1,"62":1,"64":2,"69":3,"71":1,"73":1,"74":6,"75":7,"78":1}}],["also",{"2":{"2":1,"3":1,"14":1,"18":1,"24":1,"27":1,"35":1,"37":1,"62":2,"63":1,"71":2,"74":1,"80":1}}],["analog",{"2":{"63":1}}],["analyzing",{"2":{"1":1}}],["another",{"2":{"16":1,"35":1}}],["anynymous",{"2":{"74":1}}],["anyocean",{"2":{"74":1}}],["anymissing",{"2":{"74":1}}],["any",{"2":{"8":1,"9":1,"10":1,"11":1,"14":2,"16":5,"17":4,"20":1,"21":2,"22":3,"24":1,"27":1,"28":3,"29":1,"30":1,"32":6,"36":3,"37":3,"45":3,"46":2,"48":4,"49":3,"50":3,"52":2,"53":2,"55":1,"56":2,"57":3,"58":3,"59":5,"66":1,"70":1,"71":1,"74":4,"75":9,"81":1,"84":1,"90":1}}],["an",{"0":{"8":1},"2":{"9":1,"10":4,"12":1,"13":1,"15":1,"18":2,"28":1,"29":1,"34":1,"35":1,"37":1,"55":3,"58":1,"62":1,"63":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"74":19,"75":8}}],["and",{"0":{"23":1,"29":1,"42":1,"51":1,"55":1,"59":1,"66":1},"1":{"24":1,"25":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"52":1,"53":1,"54":1,"56":1,"57":1,"58":1,"59":1,"60":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1},"2":{"0":1,"2":1,"5":1,"6":1,"7":1,"8":1,"12":1,"16":4,"17":2,"19":1,"23":1,"24":1,"27":1,"30":1,"32":1,"35":6,"36":1,"37":6,"41":5,"42":1,"43":1,"45":1,"50":1,"51":2,"52":1,"53":1,"55":1,"59":1,"62":5,"63":3,"64":2,"66":1,"69":1,"70":1,"71":3,"72":1,"74":18,"75":6,"76":1,"78":4,"80":1,"81":2,"83":1,"90":1,"92":1}}],["available",{"2":{"59":2,"71":1,"73":1,"74":2,"80":1}}],["avariable",{"2":{"0":1}}],["avoids",{"2":{"17":1}}],["avoided",{"2":{"0":1}}],["averaging",{"2":{"14":1}}],["averages",{"0":{"43":1},"2":{"42":1}}],["average",{"2":{"14":1,"43":2}}],["artype",{"2":{"74":2}}],["archgdaldatasets",{"2":{"54":1}}],["archgdal",{"2":{"54":2}}],["arguments",{"2":{"50":1,"74":11,"75":3}}],["argument",{"2":{"18":1,"71":1,"74":4,"75":2}}],["arr2",{"2":{"22":1}}],["arr",{"2":{"17":7,"22":2}}],["arrayinfo",{"2":{"75":1}}],["arrays",{"2":{"6":1,"7":1,"8":2,"9":1,"11":1,"23":1,"25":2,"52":2,"53":2,"61":1,"62":4,"63":3,"64":3,"74":2,"75":1}}],["array",{"0":{"17":1,"20":1},"2":{"0":1,"1":1,"8":2,"9":2,"10":3,"12":2,"13":2,"15":1,"17":8,"20":2,"29":1,"45":1,"50":1,"55":1,"62":4,"63":1,"64":1,"65":2,"71":5,"72":5,"74":10,"75":4,"81":3}}],["arbitrary",{"2":{"16":1}}],["arithmetics",{"0":{"12":1},"2":{"10":1}}],["areas",{"2":{"74":1}}],["area",{"2":{"52":2,"74":1}}],["areacella",{"2":{"52":2,"90":1}}],["are",{"2":{"0":1,"11":1,"19":3,"29":1,"31":1,"35":1,"41":3,"50":2,"55":1,"59":1,"60":1,"62":3,"63":2,"64":3,"71":1,"74":11,"75":6,"76":1,"78":1,"86":2,"88":1}}],["according",{"2":{"74":1}}],["access",{"2":{"1":2,"13":1,"24":1,"62":1,"65":1}}],["accessed",{"2":{"0":2,"52":1,"53":1}}],["activate",{"2":{"37":1,"78":2,"83":1,"91":1,"94":1}}],["actually",{"2":{"75":1}}],["actual",{"2":{"13":1,"71":1,"75":1,"81":1}}],["achieves",{"2":{"28":1}}],["achieved",{"2":{"0":1}}],["across",{"2":{"0":1,"7":1,"16":1,"62":3}}],["a",{"0":{"9":1,"11":1,"17":1,"24":1,"25":1,"27":1,"31":1,"32":1,"33":1,"34":1,"35":1,"38":1,"41":2,"56":1,"60":1,"69":1,"70":1,"83":1,"89":1},"1":{"28":1,"32":1,"33":1,"34":2,"35":2,"39":1,"40":1,"84":1,"85":1},"2":{"0":4,"2":7,"3":1,"4":1,"7":1,"8":1,"9":2,"10":3,"11":1,"12":4,"13":2,"14":2,"15":1,"16":5,"17":75,"18":11,"20":2,"21":5,"22":8,"24":1,"26":1,"27":2,"28":2,"29":1,"31":4,"32":3,"33":1,"35":2,"37":3,"39":2,"40":2,"41":4,"43":1,"48":1,"50":2,"52":6,"53":3,"54":1,"58":2,"59":4,"60":1,"62":12,"63":4,"64":8,"65":1,"67":3,"68":3,"69":4,"71":5,"74":60,"75":31,"77":2,"78":2,"81":4,"82":1,"87":1,"88":1}}],["iall",{"2":{"75":1}}],["iwindow",{"2":{"75":1}}],["icolon",{"2":{"75":1}}],["icefire",{"2":{"91":1,"92":1,"93":1,"94":1}}],["ice",{"2":{"53":1,"55":1,"66":1,"70":1}}],["ipcc",{"2":{"53":3,"55":3,"66":3,"70":3}}],["ipsl",{"2":{"53":6,"55":6,"66":6,"70":6}}],["idx",{"2":{"84":3}}],["identical",{"2":{"74":1}}],["id",{"2":{"52":2,"53":2,"55":2,"66":2,"70":2,"90":2}}],["irregular",{"2":{"35":6,"37":2,"41":4,"45":1,"48":2,"49":1,"50":1,"52":4,"53":2,"55":1,"56":2,"57":2,"58":6,"59":5,"66":1,"70":1,"75":1,"90":2}}],["immutable",{"2":{"11":1}}],["improving",{"2":{"82":1}}],["improve",{"2":{"6":1}}],["implementing",{"2":{"74":1}}],["importance",{"2":{"75":1}}],["important",{"2":{"1":1}}],["impossible",{"2":{"11":1}}],["i",{"0":{"30":1,"31":1,"36":1,"37":1,"38":1,"41":1},"1":{"32":1,"33":1,"34":1,"35":1,"39":1,"40":1},"2":{"8":1,"17":3,"21":1,"22":1,"32":1,"50":2,"69":1,"74":7,"75":4,"78":2,"81":1,"84":3}}],["ispar",{"2":{"74":1,"75":1}}],["ismissing",{"2":{"71":1}}],["issues",{"2":{"44":1}}],["isequal",{"2":{"17":1}}],["is",{"2":{"1":2,"2":1,"6":1,"7":1,"9":1,"13":1,"14":2,"15":1,"16":4,"17":2,"18":3,"19":1,"22":1,"26":1,"28":2,"30":1,"31":1,"35":2,"36":1,"37":4,"41":2,"43":2,"44":2,"45":1,"49":1,"54":1,"56":1,"59":2,"60":1,"62":4,"63":1,"64":2,"65":1,"71":4,"72":1,"74":10,"75":10,"77":1,"80":1,"82":1,"86":1,"88":1}}],["if",{"2":{"0":1,"19":1,"35":3,"69":1,"71":2,"74":11,"75":6,"78":1,"86":1}}],["inline",{"2":{"94":2}}],["incubes",{"2":{"75":1}}],["incs",{"2":{"75":1}}],["include",{"2":{"74":2,"75":1}}],["included",{"2":{"59":1}}],["inarbc",{"2":{"75":1}}],["inar",{"2":{"75":2}}],["inplace",{"2":{"74":3,"75":1}}],["inputcube",{"2":{"75":2}}],["input",{"2":{"16":1,"18":2,"37":1,"74":12,"75":8}}],["innerchunks",{"2":{"75":1}}],["inner",{"2":{"74":9,"75":3}}],["installed",{"2":{"82":1}}],["installation",{"0":{"80":1}}],["install",{"2":{"78":1,"80":1}}],["instead",{"2":{"8":1,"9":1,"13":1,"27":1,"32":1,"59":1,"62":1}}],["insize",{"2":{"75":1}}],["inside",{"2":{"74":3}}],["initialization",{"2":{"52":1,"90":1}}],["initially",{"2":{"17":1}}],["inds",{"2":{"75":1}}],["indeed",{"2":{"72":1}}],["indexing",{"2":{"57":2,"58":2,"72":1,"82":1}}],["index",{"2":{"52":2,"75":2,"90":2}}],["independently",{"2":{"41":1}}],["indices",{"2":{"75":1,"84":1}}],["indicate",{"2":{"74":1}}],["indicating",{"2":{"9":1,"17":1,"74":1}}],["indims=indims",{"2":{"17":1,"18":1}}],["indims",{"2":{"16":8,"74":7}}],["individually",{"2":{"13":2}}],["individual",{"2":{"0":1,"52":1,"53":1}}],["information",{"2":{"69":1,"75":2}}],["info",{"2":{"16":2,"22":1,"27":1,"71":1,"82":1}}],["introducing",{"2":{"64":1}}],["int",{"2":{"28":1,"84":3}}],["interested",{"2":{"86":1}}],["internal",{"0":{"75":1},"2":{"75":9}}],["internally",{"2":{"63":1}}],["interface",{"2":{"74":2,"88":1}}],["interval",{"2":{"53":1,"56":2,"57":3,"58":4,"59":6}}],["intervalsets",{"2":{"59":1}}],["intervals",{"0":{"59":1},"2":{"32":1}}],["interactive",{"2":{"0":1}}],["integer",{"2":{"24":1,"57":1,"58":1,"62":1}}],["int64",{"2":{"4":4,"5":4,"6":2,"8":1,"9":1,"16":8,"20":2,"21":6,"22":2,"24":3,"27":9,"28":7,"29":4,"32":15,"34":4,"35":7,"37":3,"39":1,"40":5,"45":6,"46":6,"48":4,"49":1,"50":19,"70":3,"71":6,"75":1,"81":2}}],["into",{"0":{"89":1},"2":{"0":1,"1":1,"2":1,"7":1,"8":1,"16":1,"17":1,"19":2,"22":1,"35":4,"51":1,"64":2,"69":1,"72":1,"74":6,"75":3,"78":1,"94":1}}],["in",{"0":{"38":1},"1":{"39":1,"40":1},"2":{"0":5,"1":1,"2":1,"4":2,"5":1,"9":1,"11":1,"13":1,"14":2,"16":2,"17":6,"18":3,"19":2,"21":1,"22":1,"29":1,"33":1,"35":1,"37":2,"41":4,"43":2,"44":2,"47":3,"50":4,"52":2,"53":1,"56":2,"57":3,"58":4,"59":7,"60":1,"61":1,"62":5,"63":1,"64":2,"71":1,"72":1,"74":13,"75":9,"78":2,"80":1,"81":2,"84":1,"86":3,"88":4,"90":1}}],["iter",{"2":{"74":1}}],["iterate",{"2":{"88":1}}],["iteration",{"0":{"88":1}}],["iterator",{"2":{"37":1}}],["iterators",{"2":{"17":1}}],["iterable",{"2":{"37":2,"74":2}}],["itself",{"2":{"74":1,"75":1}}],["its",{"2":{"0":1}}],["it",{"2":{"0":2,"1":3,"12":1,"16":1,"18":2,"27":1,"29":1,"30":1,"35":2,"37":2,"41":2,"46":1,"48":1,"50":1,"55":1,"62":2,"63":1,"65":1,"69":1,"71":2,"72":1,"74":10,"75":5,"78":1,"80":1}}],["lscene",{"2":{"94":1}}],["lmdz",{"2":{"53":1,"55":1,"66":1,"70":1}}],["link",{"2":{"77":1}}],["linewidth=0",{"2":{"92":1,"93":1}}],["linewidth=2",{"2":{"85":2}}],["linewidth=1",{"2":{"83":1,"85":1}}],["linestyle=",{"2":{"85":2}}],["lines",{"2":{"83":1,"85":3}}],["line",{"2":{"37":1}}],["lim",{"2":{"53":1,"55":1,"66":1,"70":1}}],["libraries",{"2":{"32":1,"62":1}}],["libray",{"2":{"31":1}}],["little",{"2":{"18":1}}],["list",{"2":{"17":1,"41":5,"74":5,"75":6}}],["like",{"2":{"0":1,"37":1,"41":1,"74":2,"75":1,"77":1}}],["loopinds",{"2":{"75":2}}],["looping",{"2":{"74":1,"75":1}}],["loopcachesize",{"2":{"75":1}}],["loopchunksize",{"2":{"74":1}}],["loopaxes",{"2":{"75":1}}],["loopvars",{"2":{"74":1,"75":1}}],["loops",{"2":{"74":1}}],["loop",{"2":{"74":1,"75":2}}],["looped",{"2":{"74":3,"75":3}}],["look",{"2":{"69":1,"74":1,"75":1,"77":1,"78":1}}],["lookups",{"2":{"45":15,"46":10,"48":5,"49":5,"50":38,"60":3}}],["lookup",{"2":{"45":1,"47":1,"90":3}}],["looks",{"2":{"37":1,"41":1}}],["located",{"2":{"86":1}}],["locate",{"2":{"78":1}}],["location",{"2":{"75":3}}],["locations",{"2":{"63":1,"64":1}}],["localhost",{"2":{"78":1}}],["locally",{"0":{"78":1},"2":{"78":1}}],["local",{"2":{"18":1,"52":1}}],["lowclip",{"2":{"50":4}}],["low",{"2":{"41":4}}],["lost",{"2":{"19":1}}],["lo",{"2":{"16":4}}],["loadorgenerate",{"2":{"75":1}}],["loading",{"2":{"54":1,"72":1}}],["loaded",{"2":{"35":2}}],["load",{"2":{"16":1,"32":1,"35":2,"62":1}}],["long",{"2":{"50":1,"52":1,"53":1,"56":2,"57":3,"58":3,"59":5}}],["longitudes=longitudes",{"2":{"35":1}}],["longitudes",{"2":{"35":12}}],["longitude",{"2":{"32":1,"81":2}}],["lonlat",{"2":{"34":1}}],["lon=1",{"2":{"32":1,"34":1}}],["lon",{"2":{"10":2,"12":1,"13":1,"14":2,"16":10,"17":12,"18":1,"21":2,"24":3,"25":1,"30":2,"32":7,"34":3,"36":4,"37":3,"52":2,"53":2,"55":1,"56":2,"57":3,"58":6,"59":10,"60":2,"66":1,"70":1,"90":2,"92":3}}],["lazy",{"2":{"74":1}}],["lazily",{"2":{"13":1}}],["layername",{"2":{"74":2}}],["layername=",{"2":{"71":2,"75":1}}],["layer",{"2":{"71":1,"74":1,"75":1}}],["layout",{"2":{"50":2}}],["labelled",{"2":{"74":1}}],["labels",{"2":{"50":1,"60":1,"64":1,"65":1}}],["label=false",{"2":{"50":1}}],["label=",{"2":{"50":1,"85":3}}],["label=cb",{"2":{"50":1}}],["label",{"2":{"50":3,"52":1,"90":1}}],["last",{"2":{"16":1,"18":1}}],["la",{"2":{"16":4}}],["latest",{"2":{"82":1}}],["lat=5",{"2":{"32":1,"34":1}}],["latitudes=latitudes",{"2":{"35":1}}],["latitudes",{"2":{"35":11}}],["latitude",{"2":{"32":1,"81":2}}],["lat",{"2":{"10":2,"12":1,"13":1,"14":2,"16":7,"17":12,"18":1,"21":2,"24":3,"25":1,"30":2,"32":7,"34":3,"36":4,"37":3,"52":2,"53":2,"55":1,"56":2,"57":3,"58":5,"59":5,"60":1,"66":1,"70":1,"74":1,"90":3,"92":1,"93":1}}],["larger",{"2":{"19":1}}],["large",{"2":{"0":2,"19":1,"44":1,"62":1}}],["learn",{"2":{"88":1}}],["learning",{"2":{"62":1,"86":1}}],["leap",{"2":{"83":1}}],["least",{"2":{"35":1,"41":1,"74":1}}],["length",{"2":{"45":2,"46":1,"48":3,"74":1,"75":3}}],["length=365",{"2":{"83":1}}],["length=20",{"2":{"30":1,"81":1}}],["length=15",{"2":{"10":1,"17":1,"18":1,"24":1,"30":1,"81":1}}],["length=10",{"2":{"10":1,"17":1,"18":1,"24":1,"30":1,"81":1}}],["level",{"2":{"41":1,"77":1,"78":1}}],["left",{"2":{"14":2}}],["let",{"2":{"10":1,"16":2,"28":1,"30":1,"32":1,"34":1,"35":1,"50":1,"55":1,"84":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/previews/PR437/assets/chunks/VPLocalSearchBox.DHQW8c6e.js b/previews/PR437/assets/chunks/VPLocalSearchBox.DHQW8c6e.js new file mode 100644 index 00000000..123e6b7a --- /dev/null +++ b/previews/PR437/assets/chunks/VPLocalSearchBox.DHQW8c6e.js @@ -0,0 +1,7 @@ +var Nt=Object.defineProperty;var Ft=(a,e,t)=>e in a?Nt(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var Re=(a,e,t)=>Ft(a,typeof e!="symbol"?e+"":e,t);import{V as Ot,p as se,h as pe,aj as Xe,ak as Rt,al as Ct,q as je,am as Mt,d as At,D as ye,an as et,ao as Lt,ap as Dt,s as zt,aq as Pt,v as Ce,P as ue,O as we,ar as jt,as as Vt,W as $t,R as Bt,$ as Wt,o as q,b as Kt,j as S,a0 as Jt,k as D,at as Ut,au as qt,av as Gt,c as Y,n as tt,e as xe,C as st,F as nt,a as de,t as he,aw as Ht,ax as it,ay as Qt,a9 as Yt,af as Zt,az as Xt,_ as es}from"./framework.BxolPc_T.js";import{u as ts,d as ss}from"./theme.C_rChtpL.js";const ns={root:()=>Ot(()=>import("./@localSearchIndexroot.Dgdb-kc0.js"),[])};/*! +* tabbable 6.2.0 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/var vt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Ie=vt.join(","),mt=typeof Element>"u",ie=mt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,ke=!mt&&Element.prototype.getRootNode?function(a){var e;return a==null||(e=a.getRootNode)===null||e===void 0?void 0:e.call(a)}:function(a){return a==null?void 0:a.ownerDocument},Ne=function a(e,t){var s;t===void 0&&(t=!0);var n=e==null||(s=e.getAttribute)===null||s===void 0?void 0:s.call(e,"inert"),r=n===""||n==="true",i=r||t&&e&&a(e.parentNode);return i},is=function(e){var t,s=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return s===""||s==="true"},gt=function(e,t,s){if(Ne(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(Ie));return t&&ie.call(e,Ie)&&n.unshift(e),n=n.filter(s),n},bt=function a(e,t,s){for(var n=[],r=Array.from(e);r.length;){var i=r.shift();if(!Ne(i,!1))if(i.tagName==="SLOT"){var o=i.assignedElements(),l=o.length?o:i.children,c=a(l,!0,s);s.flatten?n.push.apply(n,c):n.push({scopeParent:i,candidates:c})}else{var h=ie.call(i,Ie);h&&s.filter(i)&&(t||!e.includes(i))&&n.push(i);var v=i.shadowRoot||typeof s.getShadowRoot=="function"&&s.getShadowRoot(i),p=!Ne(v,!1)&&(!s.shadowRootFilter||s.shadowRootFilter(i));if(v&&p){var b=a(v===!0?i.children:v.children,!0,s);s.flatten?n.push.apply(n,b):n.push({scopeParent:i,candidates:b})}else r.unshift.apply(r,i.children)}}return n},yt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},ne=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||is(e))&&!yt(e)?0:e.tabIndex},rs=function(e,t){var s=ne(e);return s<0&&t&&!yt(e)?0:s},as=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},wt=function(e){return e.tagName==="INPUT"},os=function(e){return wt(e)&&e.type==="hidden"},ls=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(s){return s.tagName==="SUMMARY"});return t},cs=function(e,t){for(var s=0;ssummary:first-of-type"),i=r?e.parentElement:e;if(ie.call(i,"details:not([open]) *"))return!0;if(!s||s==="full"||s==="legacy-full"){if(typeof n=="function"){for(var o=e;e;){var l=e.parentElement,c=ke(e);if(l&&!l.shadowRoot&&n(l)===!0)return rt(e);e.assignedSlot?e=e.assignedSlot:!l&&c!==e.ownerDocument?e=c.host:e=l}e=o}if(fs(e))return!e.getClientRects().length;if(s!=="legacy-full")return!0}else if(s==="non-zero-area")return rt(e);return!1},vs=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var s=0;s=0)},gs=function a(e){var t=[],s=[];return e.forEach(function(n,r){var i=!!n.scopeParent,o=i?n.scopeParent:n,l=rs(o,i),c=i?a(n.candidates):o;l===0?i?t.push.apply(t,c):t.push(o):s.push({documentOrder:r,tabIndex:l,item:n,isScope:i,content:c})}),s.sort(as).reduce(function(n,r){return r.isScope?n.push.apply(n,r.content):n.push(r.content),n},[]).concat(t)},bs=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Ve.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:ms}):s=gt(e,t.includeContainer,Ve.bind(null,t)),gs(s)},ys=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Fe.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):s=gt(e,t.includeContainer,Fe.bind(null,t)),s},re=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ie.call(e,Ie)===!1?!1:Ve(t,e)},ws=vt.concat("iframe").join(","),Me=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ie.call(e,ws)===!1?!1:Fe(t,e)};/*! +* focus-trap 7.6.0 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/function xs(a,e,t){return(e=_s(e))in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function at(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(a);e&&(s=s.filter(function(n){return Object.getOwnPropertyDescriptor(a,n).enumerable})),t.push.apply(t,s)}return t}function ot(a){for(var e=1;e0){var s=e[e.length-1];s!==t&&s.pause()}var n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap:function(e,t){var s=e.indexOf(t);s!==-1&&e.splice(s,1),e.length>0&&e[e.length-1].unpause()}},Es=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Ts=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},ve=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Is=function(e){return ve(e)&&!e.shiftKey},ks=function(e){return ve(e)&&e.shiftKey},ct=function(e){return setTimeout(e,0)},ut=function(e,t){var s=-1;return e.every(function(n,r){return t(n)?(s=r,!1):!0}),s},fe=function(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?g-1:0),E=1;E=0)d=s.activeElement;else{var u=i.tabbableGroups[0],g=u&&u.firstTabbableNode;d=g||h("fallbackFocus")}if(!d)throw new Error("Your focus-trap needs to have at least one focusable element");return d},p=function(){if(i.containerGroups=i.containers.map(function(d){var u=bs(d,r.tabbableOptions),g=ys(d,r.tabbableOptions),_=u.length>0?u[0]:void 0,E=u.length>0?u[u.length-1]:void 0,N=g.find(function(f){return re(f)}),F=g.slice().reverse().find(function(f){return re(f)}),m=!!u.find(function(f){return ne(f)>0});return{container:d,tabbableNodes:u,focusableNodes:g,posTabIndexesFound:m,firstTabbableNode:_,lastTabbableNode:E,firstDomTabbableNode:N,lastDomTabbableNode:F,nextTabbableNode:function(T){var A=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,C=u.indexOf(T);return C<0?A?g.slice(g.indexOf(T)+1).find(function(M){return re(M)}):g.slice(0,g.indexOf(T)).reverse().find(function(M){return re(M)}):u[C+(A?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(d){return d.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!h("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(d){return d.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},b=function(d){var u=d.activeElement;if(u)return u.shadowRoot&&u.shadowRoot.activeElement!==null?b(u.shadowRoot):u},y=function(d){if(d!==!1&&d!==b(document)){if(!d||!d.focus){y(v());return}d.focus({preventScroll:!!r.preventScroll}),i.mostRecentlyFocusedNode=d,Es(d)&&d.select()}},x=function(d){var u=h("setReturnFocus",d);return u||(u===!1?!1:d)},w=function(d){var u=d.target,g=d.event,_=d.isBackward,E=_===void 0?!1:_;u=u||Se(g),p();var N=null;if(i.tabbableGroups.length>0){var F=c(u,g),m=F>=0?i.containerGroups[F]:void 0;if(F<0)E?N=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:N=i.tabbableGroups[0].firstTabbableNode;else if(E){var f=ut(i.tabbableGroups,function(L){var j=L.firstTabbableNode;return u===j});if(f<0&&(m.container===u||Me(u,r.tabbableOptions)&&!re(u,r.tabbableOptions)&&!m.nextTabbableNode(u,!1))&&(f=F),f>=0){var T=f===0?i.tabbableGroups.length-1:f-1,A=i.tabbableGroups[T];N=ne(u)>=0?A.lastTabbableNode:A.lastDomTabbableNode}else ve(g)||(N=m.nextTabbableNode(u,!1))}else{var C=ut(i.tabbableGroups,function(L){var j=L.lastTabbableNode;return u===j});if(C<0&&(m.container===u||Me(u,r.tabbableOptions)&&!re(u,r.tabbableOptions)&&!m.nextTabbableNode(u))&&(C=F),C>=0){var M=C===i.tabbableGroups.length-1?0:C+1,I=i.tabbableGroups[M];N=ne(u)>=0?I.firstTabbableNode:I.firstDomTabbableNode}else ve(g)||(N=m.nextTabbableNode(u))}}else N=h("fallbackFocus");return N},O=function(d){var u=Se(d);if(!(c(u,d)>=0)){if(fe(r.clickOutsideDeactivates,d)){o.deactivate({returnFocus:r.returnFocusOnDeactivate});return}fe(r.allowOutsideClick,d)||d.preventDefault()}},R=function(d){var u=Se(d),g=c(u,d)>=0;if(g||u instanceof Document)g&&(i.mostRecentlyFocusedNode=u);else{d.stopImmediatePropagation();var _,E=!0;if(i.mostRecentlyFocusedNode)if(ne(i.mostRecentlyFocusedNode)>0){var N=c(i.mostRecentlyFocusedNode),F=i.containerGroups[N].tabbableNodes;if(F.length>0){var m=F.findIndex(function(f){return f===i.mostRecentlyFocusedNode});m>=0&&(r.isKeyForward(i.recentNavEvent)?m+1=0&&(_=F[m-1],E=!1))}}else i.containerGroups.some(function(f){return f.tabbableNodes.some(function(T){return ne(T)>0})})||(E=!1);else E=!1;E&&(_=w({target:i.mostRecentlyFocusedNode,isBackward:r.isKeyBackward(i.recentNavEvent)})),y(_||i.mostRecentlyFocusedNode||v())}i.recentNavEvent=void 0},K=function(d){var u=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=d;var g=w({event:d,isBackward:u});g&&(ve(d)&&d.preventDefault(),y(g))},G=function(d){(r.isKeyForward(d)||r.isKeyBackward(d))&&K(d,r.isKeyBackward(d))},W=function(d){Ts(d)&&fe(r.escapeDeactivates,d)!==!1&&(d.preventDefault(),o.deactivate())},V=function(d){var u=Se(d);c(u,d)>=0||fe(r.clickOutsideDeactivates,d)||fe(r.allowOutsideClick,d)||(d.preventDefault(),d.stopImmediatePropagation())},$=function(){if(i.active)return lt.activateTrap(n,o),i.delayInitialFocusTimer=r.delayInitialFocus?ct(function(){y(v())}):y(v()),s.addEventListener("focusin",R,!0),s.addEventListener("mousedown",O,{capture:!0,passive:!1}),s.addEventListener("touchstart",O,{capture:!0,passive:!1}),s.addEventListener("click",V,{capture:!0,passive:!1}),s.addEventListener("keydown",G,{capture:!0,passive:!1}),s.addEventListener("keydown",W),o},me=function(){if(i.active)return s.removeEventListener("focusin",R,!0),s.removeEventListener("mousedown",O,!0),s.removeEventListener("touchstart",O,!0),s.removeEventListener("click",V,!0),s.removeEventListener("keydown",G,!0),s.removeEventListener("keydown",W),o},P=function(d){var u=d.some(function(g){var _=Array.from(g.removedNodes);return _.some(function(E){return E===i.mostRecentlyFocusedNode})});u&&y(v())},H=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(P):void 0,J=function(){H&&(H.disconnect(),i.active&&!i.paused&&i.containers.map(function(d){H.observe(d,{subtree:!0,childList:!0})}))};return o={get active(){return i.active},get paused(){return i.paused},activate:function(d){if(i.active)return this;var u=l(d,"onActivate"),g=l(d,"onPostActivate"),_=l(d,"checkCanFocusTrap");_||p(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=s.activeElement,u==null||u();var E=function(){_&&p(),$(),J(),g==null||g()};return _?(_(i.containers.concat()).then(E,E),this):(E(),this)},deactivate:function(d){if(!i.active)return this;var u=ot({onDeactivate:r.onDeactivate,onPostDeactivate:r.onPostDeactivate,checkCanReturnFocus:r.checkCanReturnFocus},d);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,me(),i.active=!1,i.paused=!1,J(),lt.deactivateTrap(n,o);var g=l(u,"onDeactivate"),_=l(u,"onPostDeactivate"),E=l(u,"checkCanReturnFocus"),N=l(u,"returnFocus","returnFocusOnDeactivate");g==null||g();var F=function(){ct(function(){N&&y(x(i.nodeFocusedBeforeActivation)),_==null||_()})};return N&&E?(E(x(i.nodeFocusedBeforeActivation)).then(F,F),this):(F(),this)},pause:function(d){if(i.paused||!i.active)return this;var u=l(d,"onPause"),g=l(d,"onPostPause");return i.paused=!0,u==null||u(),me(),J(),g==null||g(),this},unpause:function(d){if(!i.paused||!i.active)return this;var u=l(d,"onUnpause"),g=l(d,"onPostUnpause");return i.paused=!1,u==null||u(),p(),$(),J(),g==null||g(),this},updateContainerElements:function(d){var u=[].concat(d).filter(Boolean);return i.containers=u.map(function(g){return typeof g=="string"?s.querySelector(g):g}),i.active&&p(),J(),this}},o.updateContainerElements(e),o};function Os(a,e={}){let t;const{immediate:s,...n}=e,r=se(!1),i=se(!1),o=p=>t&&t.activate(p),l=p=>t&&t.deactivate(p),c=()=>{t&&(t.pause(),i.value=!0)},h=()=>{t&&(t.unpause(),i.value=!1)},v=pe(()=>{const p=Xe(a);return(Array.isArray(p)?p:[p]).map(b=>{const y=Xe(b);return typeof y=="string"?y:Rt(y)}).filter(Ct)});return je(v,p=>{p.length&&(t=Fs(p,{...n,onActivate(){r.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){r.value=!1,e.onDeactivate&&e.onDeactivate()}}),s&&o())},{flush:"post"}),Mt(()=>l()),{hasFocus:r,isPaused:i,activate:o,deactivate:l,pause:c,unpause:h}}class oe{constructor(e,t=!0,s=[],n=5e3){this.ctx=e,this.iframes=t,this.exclude=s,this.iframesTimeout=n}static matches(e,t){const s=typeof t=="string"?[t]:t,n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(n){let r=!1;return s.every(i=>n.call(e,i)?(r=!0,!1):!0),r}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(s=>{const n=t.filter(r=>r.contains(s)).length>0;t.indexOf(s)===-1&&!n&&t.push(s)}),t}getIframeContents(e,t,s=()=>{}){let n;try{const r=e.contentWindow;if(n=r.document,!r||!n)throw new Error("iframe inaccessible")}catch{s()}n&&t(n)}isIframeBlank(e){const t="about:blank",s=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&s!==t&&s}observeIframeLoad(e,t,s){let n=!1,r=null;const i=()=>{if(!n){n=!0,clearTimeout(r);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,s))}catch{s()}}};e.addEventListener("load",i),r=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,s){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,s):this.getIframeContents(e,t,s):this.observeIframeLoad(e,t,s)}catch{s()}}waitForIframes(e,t){let s=0;this.forEachIframe(e,()=>!0,n=>{s++,this.waitForIframes(n.querySelector("html"),()=>{--s||t()})},n=>{n||t()})}forEachIframe(e,t,s,n=()=>{}){let r=e.querySelectorAll("iframe"),i=r.length,o=0;r=Array.prototype.slice.call(r);const l=()=>{--i<=0&&n(o)};i||l(),r.forEach(c=>{oe.matches(c,this.exclude)?l():this.onIframeReady(c,h=>{t(c)&&(o++,s(h)),l()},l)})}createIterator(e,t,s){return document.createNodeIterator(e,t,s,!1)}createInstanceOnIframe(e){return new oe(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,s){const n=e.compareDocumentPosition(s),r=Node.DOCUMENT_POSITION_PRECEDING;if(n&r)if(t!==null){const i=t.compareDocumentPosition(s),o=Node.DOCUMENT_POSITION_FOLLOWING;if(i&o)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let s;return t===null?s=e.nextNode():s=e.nextNode()&&e.nextNode(),{prevNode:t,node:s}}checkIframeFilter(e,t,s,n){let r=!1,i=!1;return n.forEach((o,l)=>{o.val===s&&(r=l,i=o.handled)}),this.compareNodeIframe(e,t,s)?(r===!1&&!i?n.push({val:s,handled:!0}):r!==!1&&!i&&(n[r].handled=!0),!0):(r===!1&&n.push({val:s,handled:!1}),!1)}handleOpenIframes(e,t,s,n){e.forEach(r=>{r.handled||this.getIframeContents(r.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,s,n)})})}iterateThroughNodes(e,t,s,n,r){const i=this.createIterator(t,e,n);let o=[],l=[],c,h,v=()=>({prevNode:h,node:c}=this.getIteratorNode(i),c);for(;v();)this.iframes&&this.forEachIframe(t,p=>this.checkIframeFilter(c,h,p,o),p=>{this.createInstanceOnIframe(p).forEachNode(e,b=>l.push(b),n)}),l.push(c);l.forEach(p=>{s(p)}),this.iframes&&this.handleOpenIframes(o,e,s,n),r()}forEachNode(e,t,s,n=()=>{}){const r=this.getContexts();let i=r.length;i||n(),r.forEach(o=>{const l=()=>{this.iterateThroughNodes(e,o,t,s,()=>{--i<=0&&n()})};this.iframes?this.waitForIframes(o,l):l()})}}let Rs=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new oe(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const s=this.opt.log;this.opt.debug&&typeof s=="object"&&typeof s[t]=="function"&&s[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,s=this.opt.caseSensitive?"":"i",n=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let r in t)if(t.hasOwnProperty(r)){const i=t[r],o=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(r):this.escapeStr(r),l=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);o!==""&&l!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(o)}|${this.escapeStr(l)})`,`gm${s}`),n+`(${this.processSynomyms(o)}|${this.processSynomyms(l)})`+n))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,s,n)=>{let r=n.charAt(s+1);return/[(|)\\]/.test(r)||r===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const s=this.opt.ignorePunctuation;return Array.isArray(s)&&s.length&&t.push(this.escapeStr(s.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",s=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let n=[];return e.split("").forEach(r=>{s.every(i=>{if(i.indexOf(r)!==-1){if(n.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),n.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let s=this.opt.accuracy,n=typeof s=="string"?s:s.value,r=typeof s=="string"?[]:s.limiters,i="";switch(r.forEach(o=>{i+=`|${this.escapeStr(o)}`}),n){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(s=>{this.opt.separateWordSearch?s.split(" ").forEach(n=>{n.trim()&&t.indexOf(n)===-1&&t.push(n)}):s.trim()&&t.indexOf(s)===-1&&t.push(s)}),{keywords:t.sort((s,n)=>n.length-s.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let s=0;return e.sort((n,r)=>n.start-r.start).forEach(n=>{let{start:r,end:i,valid:o}=this.callNoMatchOnInvalidRanges(n,s);o&&(n.start=r,n.length=i-r,t.push(n),s=i)}),t}callNoMatchOnInvalidRanges(e,t){let s,n,r=!1;return e&&typeof e.start<"u"?(s=parseInt(e.start,10),n=s+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&n-t>0&&n-s>0?r=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:s,end:n,valid:r}}checkWhitespaceRanges(e,t,s){let n,r=!0,i=s.length,o=t-i,l=parseInt(e.start,10)-o;return l=l>i?i:l,n=l+parseInt(e.length,10),n>i&&(n=i,this.log(`End range automatically set to the max value of ${i}`)),l<0||n-l<0||l>i||n>i?(r=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):s.substring(l,n).replace(/\s+/g,"")===""&&(r=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:l,end:n,valid:r}}getTextNodes(e){let t="",s=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,n=>{s.push({start:t.length,end:(t+=n.textContent).length,node:n})},n=>this.matchesExclude(n.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:s})})}matchesExclude(e){return oe.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,s){const n=this.opt.element?this.opt.element:"mark",r=e.splitText(t),i=r.splitText(s-t);let o=document.createElement(n);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=r.textContent,r.parentNode.replaceChild(o,r),i}wrapRangeInMappedTextNode(e,t,s,n,r){e.nodes.every((i,o)=>{const l=e.nodes[o+1];if(typeof l>"u"||l.start>t){if(!n(i.node))return!1;const c=t-i.start,h=(s>i.end?i.end:s)-i.start,v=e.value.substr(0,i.start),p=e.value.substr(h+i.start);if(i.node=this.wrapRangeInTextNode(i.node,c,h),e.value=v+p,e.nodes.forEach((b,y)=>{y>=o&&(e.nodes[y].start>0&&y!==o&&(e.nodes[y].start-=h),e.nodes[y].end-=h)}),s-=h,r(i.node.previousSibling,i.start),s>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,s,n,r){const i=t===0?0:t+1;this.getTextNodes(o=>{o.nodes.forEach(l=>{l=l.node;let c;for(;(c=e.exec(l.textContent))!==null&&c[i]!=="";){if(!s(c[i],l))continue;let h=c.index;if(i!==0)for(let v=1;v{let l;for(;(l=e.exec(o.value))!==null&&l[i]!=="";){let c=l.index;if(i!==0)for(let v=1;vs(l[i],v),(v,p)=>{e.lastIndex=p,n(v)})}r()})}wrapRangeFromIndex(e,t,s,n){this.getTextNodes(r=>{const i=r.value.length;e.forEach((o,l)=>{let{start:c,end:h,valid:v}=this.checkWhitespaceRanges(o,i,r.value);v&&this.wrapRangeInMappedTextNode(r,c,h,p=>t(p,o,r.value.substring(c,h),l),p=>{s(p,o)})}),n()})}unwrapMatches(e){const t=e.parentNode;let s=document.createDocumentFragment();for(;e.firstChild;)s.appendChild(e.removeChild(e.firstChild));t.replaceChild(s,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let s=0,n="wrapMatches";const r=i=>{s++,this.opt.each(i)};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),this[n](e,this.opt.ignoreGroups,(i,o)=>this.opt.filter(o,i,s),r,()=>{s===0&&this.opt.noMatch(e),this.opt.done(s)})}mark(e,t){this.opt=t;let s=0,n="wrapMatches";const{keywords:r,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),o=this.opt.caseSensitive?"":"i",l=c=>{let h=new RegExp(this.createRegExp(c),`gm${o}`),v=0;this.log(`Searching with expression "${h}"`),this[n](h,1,(p,b)=>this.opt.filter(b,c,s,v),p=>{v++,s++,this.opt.each(p)},()=>{v===0&&this.opt.noMatch(c),r[i-1]===c?this.opt.done(s):l(r[r.indexOf(c)+1])})};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),i===0?this.opt.done(s):l(r[0])}markRanges(e,t){this.opt=t;let s=0,n=this.checkRanges(e);n&&n.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(n)),this.wrapRangeFromIndex(n,(r,i,o,l)=>this.opt.filter(r,i,o,l),(r,i)=>{s++,this.opt.each(r,i)},()=>{this.opt.done(s)})):this.opt.done(s)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,s=>{this.unwrapMatches(s)},s=>{const n=oe.matches(s,t),r=this.matchesExclude(s);return!n||r?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function Cs(a){const e=new Rs(a);return this.mark=(t,s)=>(e.mark(t,s),this),this.markRegExp=(t,s)=>(e.markRegExp(t,s),this),this.markRanges=(t,s)=>(e.markRanges(t,s),this),this.unmark=t=>(e.unmark(t),this),this}function Te(a,e,t,s){function n(r){return r instanceof t?r:new t(function(i){i(r)})}return new(t||(t=Promise))(function(r,i){function o(h){try{c(s.next(h))}catch(v){i(v)}}function l(h){try{c(s.throw(h))}catch(v){i(v)}}function c(h){h.done?r(h.value):n(h.value).then(o,l)}c((s=s.apply(a,[])).next())})}const Ms="ENTRIES",xt="KEYS",St="VALUES",z="";class Ae{constructor(e,t){const s=e._tree,n=Array.from(s.keys());this.set=e,this._type=t,this._path=n.length>0?[{node:s,keys:n}]:[]}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return{done:!0,value:void 0};const{node:e,keys:t}=ae(this._path);if(ae(t)===z)return{done:!1,value:this.result()};const s=e.get(ae(t));return this._path.push({node:s,keys:Array.from(s.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=ae(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:e})=>ae(e)).filter(e=>e!==z).join("")}value(){return ae(this._path).node.get(z)}result(){switch(this._type){case St:return this.value();case xt:return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}const ae=a=>a[a.length-1],As=(a,e,t)=>{const s=new Map;if(e===void 0)return s;const n=e.length+1,r=n+t,i=new Uint8Array(r*n).fill(t+1);for(let o=0;o{const l=r*i;e:for(const c of a.keys())if(c===z){const h=n[l-1];h<=t&&s.set(o,[a.get(c),h])}else{let h=r;for(let v=0;vt)continue e}_t(a.get(c),e,t,s,n,h,i,o+c)}};class Z{constructor(e=new Map,t=""){this._size=void 0,this._tree=e,this._prefix=t}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[t,s]=Oe(this._tree,e.slice(this._prefix.length));if(t===void 0){const[n,r]=Ke(s);for(const i of n.keys())if(i!==z&&i.startsWith(r)){const o=new Map;return o.set(i.slice(r.length),n.get(i)),new Z(o,e)}}return new Z(t,e)}clear(){this._size=void 0,this._tree.clear()}delete(e){return this._size=void 0,Ls(this._tree,e)}entries(){return new Ae(this,Ms)}forEach(e){for(const[t,s]of this)e(t,s,this)}fuzzyGet(e,t){return As(this._tree,e,t)}get(e){const t=$e(this._tree,e);return t!==void 0?t.get(z):void 0}has(e){const t=$e(this._tree,e);return t!==void 0&&t.has(z)}keys(){return new Ae(this,xt)}set(e,t){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,Le(this._tree,e).set(z,t),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=Le(this._tree,e);return s.set(z,t(s.get(z))),this}fetch(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=Le(this._tree,e);let n=s.get(z);return n===void 0&&s.set(z,n=t()),n}values(){return new Ae(this,St)}[Symbol.iterator](){return this.entries()}static from(e){const t=new Z;for(const[s,n]of e)t.set(s,n);return t}static fromObject(e){return Z.from(Object.entries(e))}}const Oe=(a,e,t=[])=>{if(e.length===0||a==null)return[a,t];for(const s of a.keys())if(s!==z&&e.startsWith(s))return t.push([a,s]),Oe(a.get(s),e.slice(s.length),t);return t.push([a,e]),Oe(void 0,"",t)},$e=(a,e)=>{if(e.length===0||a==null)return a;for(const t of a.keys())if(t!==z&&e.startsWith(t))return $e(a.get(t),e.slice(t.length))},Le=(a,e)=>{const t=e.length;e:for(let s=0;a&&s{const[t,s]=Oe(a,e);if(t!==void 0){if(t.delete(z),t.size===0)Et(s);else if(t.size===1){const[n,r]=t.entries().next().value;Tt(s,n,r)}}},Et=a=>{if(a.length===0)return;const[e,t]=Ke(a);if(e.delete(t),e.size===0)Et(a.slice(0,-1));else if(e.size===1){const[s,n]=e.entries().next().value;s!==z&&Tt(a.slice(0,-1),s,n)}},Tt=(a,e,t)=>{if(a.length===0)return;const[s,n]=Ke(a);s.set(n+e,t),s.delete(n)},Ke=a=>a[a.length-1],Je="or",It="and",Ds="and_not";class le{constructor(e){if((e==null?void 0:e.fields)==null)throw new Error('MiniSearch: option "fields" must be provided');const t=e.autoVacuum==null||e.autoVacuum===!0?Pe:e.autoVacuum;this._options=Object.assign(Object.assign(Object.assign({},ze),e),{autoVacuum:t,searchOptions:Object.assign(Object.assign({},dt),e.searchOptions||{}),autoSuggestOptions:Object.assign(Object.assign({},$s),e.autoSuggestOptions||{})}),this._index=new Z,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=We,this.addFields(this._options.fields)}add(e){const{extractField:t,tokenize:s,processTerm:n,fields:r,idField:i}=this._options,o=t(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);if(this._idToShortId.has(o))throw new Error(`MiniSearch: duplicate ID ${o}`);const l=this.addDocumentId(o);this.saveStoredFields(l,e);for(const c of r){const h=t(e,c);if(h==null)continue;const v=s(h.toString(),c),p=this._fieldIds[c],b=new Set(v).size;this.addFieldLength(l,p,this._documentCount-1,b);for(const y of v){const x=n(y,c);if(Array.isArray(x))for(const w of x)this.addTerm(p,l,w);else x&&this.addTerm(p,l,x)}}}addAll(e){for(const t of e)this.add(t)}addAllAsync(e,t={}){const{chunkSize:s=10}=t,n={chunk:[],promise:Promise.resolve()},{chunk:r,promise:i}=e.reduce(({chunk:o,promise:l},c,h)=>(o.push(c),(h+1)%s===0?{chunk:[],promise:l.then(()=>new Promise(v=>setTimeout(v,0))).then(()=>this.addAll(o))}:{chunk:o,promise:l}),n);return i.then(()=>this.addAll(r))}remove(e){const{tokenize:t,processTerm:s,extractField:n,fields:r,idField:i}=this._options,o=n(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);const l=this._idToShortId.get(o);if(l==null)throw new Error(`MiniSearch: cannot remove document with ID ${o}: it is not in the index`);for(const c of r){const h=n(e,c);if(h==null)continue;const v=t(h.toString(),c),p=this._fieldIds[c],b=new Set(v).size;this.removeFieldLength(l,p,this._documentCount,b);for(const y of v){const x=s(y,c);if(Array.isArray(x))for(const w of x)this.removeTerm(p,l,w);else x&&this.removeTerm(p,l,x)}}this._storedFields.delete(l),this._documentIds.delete(l),this._idToShortId.delete(o),this._fieldLength.delete(l),this._documentCount-=1}removeAll(e){if(e)for(const t of e)this.remove(t);else{if(arguments.length>0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new Z,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}}discard(e){const t=this._idToShortId.get(e);if(t==null)throw new Error(`MiniSearch: cannot discard document with ID ${e}: it is not in the index`);this._idToShortId.delete(e),this._documentIds.delete(t),this._storedFields.delete(t),(this._fieldLength.get(t)||[]).forEach((s,n)=>{this.removeFieldLength(t,n,this._documentCount,s)}),this._fieldLength.delete(t),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()}maybeAutoVacuum(){if(this._options.autoVacuum===!1)return;const{minDirtFactor:e,minDirtCount:t,batchSize:s,batchWait:n}=this._options.autoVacuum;this.conditionalVacuum({batchSize:s,batchWait:n},{minDirtCount:t,minDirtFactor:e})}discardAll(e){const t=this._options.autoVacuum;try{this._options.autoVacuum=!1;for(const s of e)this.discard(s)}finally{this._options.autoVacuum=t}this.maybeAutoVacuum()}replace(e){const{idField:t,extractField:s}=this._options,n=s(e,t);this.discard(n),this.add(e)}vacuum(e={}){return this.conditionalVacuum(e)}conditionalVacuum(e,t){return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(()=>{const s=this._enqueuedVacuumConditions;return this._enqueuedVacuumConditions=We,this.performVacuuming(e,s)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)}performVacuuming(e,t){return Te(this,void 0,void 0,function*(){const s=this._dirtCount;if(this.vacuumConditionsMet(t)){const n=e.batchSize||Be.batchSize,r=e.batchWait||Be.batchWait;let i=1;for(const[o,l]of this._index){for(const[c,h]of l)for(const[v]of h)this._documentIds.has(v)||(h.size<=1?l.delete(c):h.delete(v));this._index.get(o).size===0&&this._index.delete(o),i%n===0&&(yield new Promise(c=>setTimeout(c,r))),i+=1}this._dirtCount-=s}yield null,this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null})}vacuumConditionsMet(e){if(e==null)return!0;let{minDirtCount:t,minDirtFactor:s}=e;return t=t||Pe.minDirtCount,s=s||Pe.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=s}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}has(e){return this._idToShortId.has(e)}getStoredFields(e){const t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)}search(e,t={}){const s=this.executeQuery(e,t),n=[];for(const[r,{score:i,terms:o,match:l}]of s){const c=o.length||1,h={id:this._documentIds.get(r),score:i*c,terms:Object.keys(l),queryTerms:o,match:l};Object.assign(h,this._storedFields.get(r)),(t.filter==null||t.filter(h))&&n.push(h)}return e===le.wildcard&&t.boostDocument==null&&this._options.searchOptions.boostDocument==null||n.sort(ft),n}autoSuggest(e,t={}){t=Object.assign(Object.assign({},this._options.autoSuggestOptions),t);const s=new Map;for(const{score:r,terms:i}of this.search(e,t)){const o=i.join(" "),l=s.get(o);l!=null?(l.score+=r,l.count+=1):s.set(o,{score:r,terms:i,count:1})}const n=[];for(const[r,{score:i,terms:o,count:l}]of s)n.push({suggestion:r,terms:o,score:i/l});return n.sort(ft),n}get documentCount(){return this._documentCount}get termCount(){return this._index.size}static loadJSON(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)}static loadJSONAsync(e,t){return Te(this,void 0,void 0,function*(){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJSAsync(JSON.parse(e),t)})}static getDefault(e){if(ze.hasOwnProperty(e))return De(ze,e);throw new Error(`MiniSearch: unknown option "${e}"`)}static loadJS(e,t){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=_e(n),l._fieldLength=_e(r),l._storedFields=_e(i);for(const[c,h]of l._documentIds)l._idToShortId.set(h,c);for(const[c,h]of s){const v=new Map;for(const p of Object.keys(h)){let b=h[p];o===1&&(b=b.ds),v.set(parseInt(p,10),_e(b))}l._index.set(c,v)}return l}static loadJSAsync(e,t){return Te(this,void 0,void 0,function*(){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=yield Ee(n),l._fieldLength=yield Ee(r),l._storedFields=yield Ee(i);for(const[h,v]of l._documentIds)l._idToShortId.set(v,h);let c=0;for(const[h,v]of s){const p=new Map;for(const b of Object.keys(v)){let y=v[b];o===1&&(y=y.ds),p.set(parseInt(b,10),yield Ee(y))}++c%1e3===0&&(yield kt(0)),l._index.set(h,p)}return l})}static instantiateMiniSearch(e,t){const{documentCount:s,nextId:n,fieldIds:r,averageFieldLength:i,dirtCount:o,serializationVersion:l}=e;if(l!==1&&l!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");const c=new le(t);return c._documentCount=s,c._nextId=n,c._idToShortId=new Map,c._fieldIds=r,c._avgFieldLength=i,c._dirtCount=o||0,c._index=new Z,c}executeQuery(e,t={}){if(e===le.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){const p=Object.assign(Object.assign(Object.assign({},t),e),{queries:void 0}),b=e.queries.map(y=>this.executeQuery(y,p));return this.combineResults(b,p.combineWith)}const{tokenize:s,processTerm:n,searchOptions:r}=this._options,i=Object.assign(Object.assign({tokenize:s,processTerm:n},r),t),{tokenize:o,processTerm:l}=i,v=o(e).flatMap(p=>l(p)).filter(p=>!!p).map(Vs(i)).map(p=>this.executeQuerySpec(p,i));return this.combineResults(v,i.combineWith)}executeQuerySpec(e,t){const s=Object.assign(Object.assign({},this._options.searchOptions),t),n=(s.fields||this._options.fields).reduce((x,w)=>Object.assign(Object.assign({},x),{[w]:De(s.boost,w)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:o,bm25:l}=s,{fuzzy:c,prefix:h}=Object.assign(Object.assign({},dt.weights),i),v=this._index.get(e.term),p=this.termResults(e.term,e.term,1,e.termBoost,v,n,r,l);let b,y;if(e.prefix&&(b=this._index.atPrefix(e.term)),e.fuzzy){const x=e.fuzzy===!0?.2:e.fuzzy,w=x<1?Math.min(o,Math.round(e.term.length*x)):x;w&&(y=this._index.fuzzyGet(e.term,w))}if(b)for(const[x,w]of b){const O=x.length-e.term.length;if(!O)continue;y==null||y.delete(x);const R=h*x.length/(x.length+.3*O);this.termResults(e.term,x,R,e.termBoost,w,n,r,l,p)}if(y)for(const x of y.keys()){const[w,O]=y.get(x);if(!O)continue;const R=c*x.length/(x.length+O);this.termResults(e.term,x,R,e.termBoost,w,n,r,l,p)}return p}executeWildcardQuery(e){const t=new Map,s=Object.assign(Object.assign({},this._options.searchOptions),e);for(const[n,r]of this._documentIds){const i=s.boostDocument?s.boostDocument(r,"",this._storedFields.get(n)):1;t.set(n,{score:i,terms:[],match:{}})}return t}combineResults(e,t=Je){if(e.length===0)return new Map;const s=t.toLowerCase(),n=zs[s];if(!n)throw new Error(`Invalid combination operator: ${t}`);return e.reduce(n)||new Map}toJSON(){const e=[];for(const[t,s]of this._index){const n={};for(const[r,i]of s)n[r]=Object.fromEntries(i);e.push([t,n])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,serializationVersion:2}}termResults(e,t,s,n,r,i,o,l,c=new Map){if(r==null)return c;for(const h of Object.keys(i)){const v=i[h],p=this._fieldIds[h],b=r.get(p);if(b==null)continue;let y=b.size;const x=this._avgFieldLength[p];for(const w of b.keys()){if(!this._documentIds.has(w)){this.removeTerm(p,w,t),y-=1;continue}const O=o?o(this._documentIds.get(w),t,this._storedFields.get(w)):1;if(!O)continue;const R=b.get(w),K=this._fieldLength.get(w)[p],G=js(R,y,this._documentCount,K,x,l),W=s*n*v*O*G,V=c.get(w);if(V){V.score+=W,Bs(V.terms,e);const $=De(V.match,t);$?$.push(h):V.match[t]=[h]}else c.set(w,{score:W,terms:[e],match:{[t]:[h]}})}}return c}addTerm(e,t,s){const n=this._index.fetch(s,pt);let r=n.get(e);if(r==null)r=new Map,r.set(t,1),n.set(e,r);else{const i=r.get(t);r.set(t,(i||0)+1)}}removeTerm(e,t,s){if(!this._index.has(s)){this.warnDocumentChanged(t,e,s);return}const n=this._index.fetch(s,pt),r=n.get(e);r==null||r.get(t)==null?this.warnDocumentChanged(t,e,s):r.get(t)<=1?r.size<=1?n.delete(e):r.delete(t):r.set(t,r.get(t)-1),this._index.get(s).size===0&&this._index.delete(s)}warnDocumentChanged(e,t,s){for(const n of Object.keys(this._fieldIds))if(this._fieldIds[n]===t){this._options.logger("warn",`MiniSearch: document with ID ${this._documentIds.get(e)} has changed before removal: term "${s}" was not present in field "${n}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}}addDocumentId(e){const t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t}addFields(e){for(let t=0;tObject.prototype.hasOwnProperty.call(a,e)?a[e]:void 0,zs={[Je]:(a,e)=>{for(const t of e.keys()){const s=a.get(t);if(s==null)a.set(t,e.get(t));else{const{score:n,terms:r,match:i}=e.get(t);s.score=s.score+n,s.match=Object.assign(s.match,i),ht(s.terms,r)}}return a},[It]:(a,e)=>{const t=new Map;for(const s of e.keys()){const n=a.get(s);if(n==null)continue;const{score:r,terms:i,match:o}=e.get(s);ht(n.terms,i),t.set(s,{score:n.score+r,terms:n.terms,match:Object.assign(n.match,o)})}return t},[Ds]:(a,e)=>{for(const t of e.keys())a.delete(t);return a}},Ps={k:1.2,b:.7,d:.5},js=(a,e,t,s,n,r)=>{const{k:i,b:o,d:l}=r;return Math.log(1+(t-e+.5)/(e+.5))*(l+a*(i+1)/(a+i*(1-o+o*s/n)))},Vs=a=>(e,t,s)=>{const n=typeof a.fuzzy=="function"?a.fuzzy(e,t,s):a.fuzzy||!1,r=typeof a.prefix=="function"?a.prefix(e,t,s):a.prefix===!0,i=typeof a.boostTerm=="function"?a.boostTerm(e,t,s):1;return{term:e,fuzzy:n,prefix:r,termBoost:i}},ze={idField:"id",extractField:(a,e)=>a[e],tokenize:a=>a.split(Ws),processTerm:a=>a.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(a,e)=>{typeof(console==null?void 0:console[a])=="function"&&console[a](e)},autoVacuum:!0},dt={combineWith:Je,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Ps},$s={combineWith:It,prefix:(a,e,t)=>e===t.length-1},Be={batchSize:1e3,batchWait:10},We={minDirtFactor:.1,minDirtCount:20},Pe=Object.assign(Object.assign({},Be),We),Bs=(a,e)=>{a.includes(e)||a.push(e)},ht=(a,e)=>{for(const t of e)a.includes(t)||a.push(t)},ft=({score:a},{score:e})=>e-a,pt=()=>new Map,_e=a=>{const e=new Map;for(const t of Object.keys(a))e.set(parseInt(t,10),a[t]);return e},Ee=a=>Te(void 0,void 0,void 0,function*(){const e=new Map;let t=0;for(const s of Object.keys(a))e.set(parseInt(s,10),a[s]),++t%1e3===0&&(yield kt(0));return e}),kt=a=>new Promise(e=>setTimeout(e,a)),Ws=/[\n\r\p{Z}\p{P}]+/u;class Ks{constructor(e=10){Re(this,"max");Re(this,"cache");this.max=e,this.cache=new Map}get(e){let t=this.cache.get(e);return t!==void 0&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){this.cache.has(e)?this.cache.delete(e):this.cache.size===this.max&&this.cache.delete(this.first()),this.cache.set(e,t)}first(){return this.cache.keys().next().value}clear(){this.cache.clear()}}const Js=["aria-owns"],Us={class:"shell"},qs=["title"],Gs={class:"search-actions before"},Hs=["title"],Qs=["placeholder"],Ys={class:"search-actions"},Zs=["title"],Xs=["disabled","title"],en=["id","role","aria-labelledby"],tn=["aria-selected"],sn=["href","aria-label","onMouseenter","onFocusin"],nn={class:"titles"},rn=["innerHTML"],an={class:"title main"},on=["innerHTML"],ln={key:0,class:"excerpt-wrapper"},cn={key:0,class:"excerpt",inert:""},un=["innerHTML"],dn={key:0,class:"no-results"},hn={class:"search-keyboard-shortcuts"},fn=["aria-label"],pn=["aria-label"],vn=["aria-label"],mn=["aria-label"],gn=At({__name:"VPLocalSearchBox",emits:["close"],setup(a,{emit:e}){var N,F;const t=e,s=ye(),n=ye(),r=ye(ns),i=ts(),{activate:o}=Os(s,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:l,theme:c}=i,h=et(async()=>{var m,f,T,A,C,M,I,L,j;return it(le.loadJSON((T=await((f=(m=r.value)[l.value])==null?void 0:f.call(m)))==null?void 0:T.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1},...((A=c.value.search)==null?void 0:A.provider)==="local"&&((M=(C=c.value.search.options)==null?void 0:C.miniSearch)==null?void 0:M.searchOptions)},...((I=c.value.search)==null?void 0:I.provider)==="local"&&((j=(L=c.value.search.options)==null?void 0:L.miniSearch)==null?void 0:j.options)}))}),p=pe(()=>{var m,f;return((m=c.value.search)==null?void 0:m.provider)==="local"&&((f=c.value.search.options)==null?void 0:f.disableQueryPersistence)===!0}).value?se(""):Lt("vitepress:local-search-filter",""),b=Dt("vitepress:local-search-detailed-list",((N=c.value.search)==null?void 0:N.provider)==="local"&&((F=c.value.search.options)==null?void 0:F.detailedView)===!0),y=pe(()=>{var m,f,T;return((m=c.value.search)==null?void 0:m.provider)==="local"&&(((f=c.value.search.options)==null?void 0:f.disableDetailedView)===!0||((T=c.value.search.options)==null?void 0:T.detailedView)===!1)}),x=pe(()=>{var f,T,A,C,M,I,L;const m=((f=c.value.search)==null?void 0:f.options)??c.value.algolia;return((M=(C=(A=(T=m==null?void 0:m.locales)==null?void 0:T[l.value])==null?void 0:A.translations)==null?void 0:C.button)==null?void 0:M.buttonText)||((L=(I=m==null?void 0:m.translations)==null?void 0:I.button)==null?void 0:L.buttonText)||"Search"});zt(()=>{y.value&&(b.value=!1)});const w=ye([]),O=se(!1);je(p,()=>{O.value=!1});const R=et(async()=>{if(n.value)return it(new Cs(n.value))},null),K=new Ks(16);Pt(()=>[h.value,p.value,b.value],async([m,f,T],A,C)=>{var ge,Ue,qe,Ge;(A==null?void 0:A[0])!==m&&K.clear();let M=!1;if(C(()=>{M=!0}),!m)return;w.value=m.search(f).slice(0,16),O.value=!0;const I=T?await Promise.all(w.value.map(B=>G(B.id))):[];if(M)return;for(const{id:B,mod:X}of I){const ee=B.slice(0,B.indexOf("#"));let Q=K.get(ee);if(Q)continue;Q=new Map,K.set(ee,Q);const U=X.default??X;if(U!=null&&U.render||U!=null&&U.setup){const te=Qt(U);te.config.warnHandler=()=>{},te.provide(Yt,i),Object.defineProperties(te.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const He=document.createElement("div");te.mount(He),He.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(ce=>{var Ze;const be=(Ze=ce.querySelector("a"))==null?void 0:Ze.getAttribute("href"),Qe=(be==null?void 0:be.startsWith("#"))&&be.slice(1);if(!Qe)return;let Ye="";for(;(ce=ce.nextElementSibling)&&!/^h[1-6]$/i.test(ce.tagName);)Ye+=ce.outerHTML;Q.set(Qe,Ye)}),te.unmount()}if(M)return}const L=new Set;if(w.value=w.value.map(B=>{const[X,ee]=B.id.split("#"),Q=K.get(X),U=(Q==null?void 0:Q.get(ee))??"";for(const te in B.match)L.add(te);return{...B,text:U}}),await ue(),M)return;await new Promise(B=>{var X;(X=R.value)==null||X.unmark({done:()=>{var ee;(ee=R.value)==null||ee.markRegExp(E(L),{done:B})}})});const j=((ge=s.value)==null?void 0:ge.querySelectorAll(".result .excerpt"))??[];for(const B of j)(Ue=B.querySelector('mark[data-markjs="true"]'))==null||Ue.scrollIntoView({block:"center"});(Ge=(qe=n.value)==null?void 0:qe.firstElementChild)==null||Ge.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function G(m){const f=Zt(m.slice(0,m.indexOf("#")));try{if(!f)throw new Error(`Cannot find file for id: ${m}`);return{id:m,mod:await import(f)}}catch(T){return console.error(T),{id:m,mod:{}}}}const W=se(),V=pe(()=>{var m;return((m=p.value)==null?void 0:m.length)<=0});function $(m=!0){var f,T;(f=W.value)==null||f.focus(),m&&((T=W.value)==null||T.select())}Ce(()=>{$()});function me(m){m.pointerType==="mouse"&&$()}const P=se(-1),H=se(!1);je(w,m=>{P.value=m.length?0:-1,J()});function J(){ue(()=>{const m=document.querySelector(".result.selected");m==null||m.scrollIntoView({block:"nearest"})})}we("ArrowUp",m=>{m.preventDefault(),P.value--,P.value<0&&(P.value=w.value.length-1),H.value=!0,J()}),we("ArrowDown",m=>{m.preventDefault(),P.value++,P.value>=w.value.length&&(P.value=0),H.value=!0,J()});const k=jt();we("Enter",m=>{if(m.isComposing||m.target instanceof HTMLButtonElement&&m.target.type!=="submit")return;const f=w.value[P.value];if(m.target instanceof HTMLInputElement&&!f){m.preventDefault();return}f&&(k.go(f.id),t("close"))}),we("Escape",()=>{t("close")});const u=ss({modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}});Ce(()=>{window.history.pushState(null,"",null)}),Vt("popstate",m=>{m.preventDefault(),t("close")});const g=$t(Bt?document.body:null);Ce(()=>{ue(()=>{g.value=!0,ue().then(()=>o())})}),Wt(()=>{g.value=!1});function _(){p.value="",ue().then(()=>$(!1))}function E(m){return new RegExp([...m].sort((f,T)=>T.length-f.length).map(f=>`(${Xt(f)})`).join("|"),"gi")}return(m,f)=>{var T,A,C,M;return q(),Kt(Ht,{to:"body"},[S("div",{ref_key:"el",ref:s,role:"button","aria-owns":(T=w.value)!=null&&T.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[S("div",{class:"backdrop",onClick:f[0]||(f[0]=I=>m.$emit("close"))}),S("div",Us,[S("form",{class:"search-bar",onPointerup:f[4]||(f[4]=I=>me(I)),onSubmit:f[5]||(f[5]=Jt(()=>{},["prevent"]))},[S("label",{title:x.value,id:"localsearch-label",for:"localsearch-input"},f[8]||(f[8]=[S("span",{"aria-hidden":"true",class:"vpi-search search-icon local-search-icon"},null,-1)]),8,qs),S("div",Gs,[S("button",{class:"back-button",title:D(u)("modal.backButtonTitle"),onClick:f[1]||(f[1]=I=>m.$emit("close"))},f[9]||(f[9]=[S("span",{class:"vpi-arrow-left local-search-icon"},null,-1)]),8,Hs)]),Ut(S("input",{ref_key:"searchInput",ref:W,"onUpdate:modelValue":f[2]||(f[2]=I=>Gt(p)?p.value=I:null),placeholder:x.value,id:"localsearch-input","aria-labelledby":"localsearch-label",class:"search-input"},null,8,Qs),[[qt,D(p)]]),S("div",Ys,[y.value?xe("",!0):(q(),Y("button",{key:0,class:tt(["toggle-layout-button",{"detailed-list":D(b)}]),type:"button",title:D(u)("modal.displayDetails"),onClick:f[3]||(f[3]=I=>P.value>-1&&(b.value=!D(b)))},f[10]||(f[10]=[S("span",{class:"vpi-layout-list local-search-icon"},null,-1)]),10,Zs)),S("button",{class:"clear-button",type:"reset",disabled:V.value,title:D(u)("modal.resetButtonTitle"),onClick:_},f[11]||(f[11]=[S("span",{class:"vpi-delete local-search-icon"},null,-1)]),8,Xs)])],32),S("ul",{ref_key:"resultsEl",ref:n,id:(A=w.value)!=null&&A.length?"localsearch-list":void 0,role:(C=w.value)!=null&&C.length?"listbox":void 0,"aria-labelledby":(M=w.value)!=null&&M.length?"localsearch-label":void 0,class:"results",onMousemove:f[7]||(f[7]=I=>H.value=!1)},[(q(!0),Y(nt,null,st(w.value,(I,L)=>(q(),Y("li",{key:I.id,role:"option","aria-selected":P.value===L?"true":"false"},[S("a",{href:I.id,class:tt(["result",{selected:P.value===L}]),"aria-label":[...I.titles,I.title].join(" > "),onMouseenter:j=>!H.value&&(P.value=L),onFocusin:j=>P.value=L,onClick:f[6]||(f[6]=j=>m.$emit("close"))},[S("div",null,[S("div",nn,[f[13]||(f[13]=S("span",{class:"title-icon"},"#",-1)),(q(!0),Y(nt,null,st(I.titles,(j,ge)=>(q(),Y("span",{key:ge,class:"title"},[S("span",{class:"text",innerHTML:j},null,8,rn),f[12]||(f[12]=S("span",{class:"vpi-chevron-right local-search-icon"},null,-1))]))),128)),S("span",an,[S("span",{class:"text",innerHTML:I.title},null,8,on)])]),D(b)?(q(),Y("div",ln,[I.text?(q(),Y("div",cn,[S("div",{class:"vp-doc",innerHTML:I.text},null,8,un)])):xe("",!0),f[14]||(f[14]=S("div",{class:"excerpt-gradient-bottom"},null,-1)),f[15]||(f[15]=S("div",{class:"excerpt-gradient-top"},null,-1))])):xe("",!0)])],42,sn)],8,tn))),128)),D(p)&&!w.value.length&&O.value?(q(),Y("li",dn,[de(he(D(u)("modal.noResultsText"))+' "',1),S("strong",null,he(D(p)),1),f[16]||(f[16]=de('" '))])):xe("",!0)],40,en),S("div",hn,[S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.navigateUpKeyAriaLabel")},f[17]||(f[17]=[S("span",{class:"vpi-arrow-up navigate-icon"},null,-1)]),8,fn),S("kbd",{"aria-label":D(u)("modal.footer.navigateDownKeyAriaLabel")},f[18]||(f[18]=[S("span",{class:"vpi-arrow-down navigate-icon"},null,-1)]),8,pn),de(" "+he(D(u)("modal.footer.navigateText")),1)]),S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.selectKeyAriaLabel")},f[19]||(f[19]=[S("span",{class:"vpi-corner-down-left navigate-icon"},null,-1)]),8,vn),de(" "+he(D(u)("modal.footer.selectText")),1)]),S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.closeKeyAriaLabel")},"esc",8,mn),de(" "+he(D(u)("modal.footer.closeText")),1)])])])],8,Js)])}}}),_n=es(gn,[["__scopeId","data-v-5b749456"]]);export{_n as default}; diff --git a/previews/PR437/assets/chunks/framework.BxolPc_T.js b/previews/PR437/assets/chunks/framework.BxolPc_T.js new file mode 100644 index 00000000..3cd50cf2 --- /dev/null +++ b/previews/PR437/assets/chunks/framework.BxolPc_T.js @@ -0,0 +1,17 @@ +/** +* @vue/shared v3.5.4 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function $r(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ee={},Ct=[],Ue=()=>{},Xo=()=>!1,Qt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Dr=e=>e.startsWith("onUpdate:"),fe=Object.assign,jr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},zo=Object.prototype.hasOwnProperty,J=(e,t)=>zo.call(e,t),K=Array.isArray,Tt=e=>Fn(e)==="[object Map]",ui=e=>Fn(e)==="[object Set]",q=e=>typeof e=="function",se=e=>typeof e=="string",rt=e=>typeof e=="symbol",ne=e=>e!==null&&typeof e=="object",di=e=>(ne(e)||q(e))&&q(e.then)&&q(e.catch),hi=Object.prototype.toString,Fn=e=>hi.call(e),Jo=e=>Fn(e).slice(8,-1),pi=e=>Fn(e)==="[object Object]",Vr=e=>se(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,At=$r(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Hn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Qo=/-(\w)/g,Ne=Hn(e=>e.replace(Qo,(t,n)=>n?n.toUpperCase():"")),Zo=/\B([A-Z])/g,st=Hn(e=>e.replace(Zo,"-$1").toLowerCase()),$n=Hn(e=>e.charAt(0).toUpperCase()+e.slice(1)),bn=Hn(e=>e?`on${$n(e)}`:""),tt=(e,t)=>!Object.is(e,t),wn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},Sr=e=>{const t=parseFloat(e);return isNaN(t)?e:t},el=e=>{const t=se(e)?Number(e):NaN;return isNaN(t)?e:t};let ps;const mi=()=>ps||(ps=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Ur(e){if(K(e)){const t={};for(let n=0;n{if(n){const r=n.split(nl);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function Br(e){let t="";if(se(e))t=e;else if(K(e))for(let n=0;n!!(e&&e.__v_isRef===!0),ll=e=>se(e)?e:e==null?"":K(e)||ne(e)&&(e.toString===hi||!q(e.toString))?vi(e)?ll(e.value):JSON.stringify(e,_i,2):String(e),_i=(e,t)=>vi(t)?_i(e,t.value):Tt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,s],i)=>(n[er(r,i)+" =>"]=s,n),{})}:ui(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>er(n))}:rt(t)?er(t):ne(t)&&!K(t)&&!pi(t)?String(t):t,er=(e,t="")=>{var n;return rt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.4 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let be;class cl{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=be,!t&&be&&(this.index=(be.scopes||(be.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0)return;let e;for(;Dt;){let t=Dt;for(Dt=void 0;t;){const n=t.nextEffect;if(t.nextEffect=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(r){e||(e=r)}t=n}}if(e)throw e}function Ei(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function xi(e){let t,n=e.depsTail;for(let r=n;r;r=r.prevDep)r.version===-1?(r===n&&(n=r.prevDep),Kr(r),fl(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0;e.deps=t,e.depsTail=n}function Er(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&Ci(t.dep.computed)||t.dep.version!==t.version)return!0;return!!e._dirty}function Ci(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Wt))return;e.globalVersion=Wt;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&!Er(e)){e.flags&=-3;return}const n=Z,r=Le;Z=e,Le=!0;try{Ei(e);const s=e.fn(e._value);(t.version===0||tt(s,e._value))&&(e._value=s,t.version++)}catch(s){throw t.version++,s}finally{Z=n,Le=r,xi(e),e.flags&=-3}}function Kr(e){const{dep:t,prevSub:n,nextSub:r}=e;if(n&&(n.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=n,e.nextSub=void 0),t.subs===e&&(t.subs=n),!t.subs&&t.computed){t.computed.flags&=-5;for(let s=t.computed.deps;s;s=s.nextDep)Kr(s)}}function fl(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let Le=!0;const Ti=[];function it(){Ti.push(Le),Le=!1}function ot(){const e=Ti.pop();Le=e===void 0?!0:e}function gs(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Z;Z=void 0;try{t()}finally{Z=n}}}let Wt=0;class Dn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0}track(t){if(!Z||!Le||Z===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Z)n=this.activeLink={dep:this,sub:Z,version:this.version,nextDep:void 0,prevDep:void 0,nextSub:void 0,prevSub:void 0,prevActiveLink:void 0},Z.deps?(n.prevDep=Z.depsTail,Z.depsTail.nextDep=n,Z.depsTail=n):Z.deps=Z.depsTail=n,Z.flags&4&&Ai(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const r=n.nextDep;r.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=r),n.prevDep=Z.depsTail,n.nextDep=void 0,Z.depsTail.nextDep=n,Z.depsTail=n,Z.deps===n&&(Z.deps=r)}return n}trigger(t){this.version++,Wt++,this.notify(t)}notify(t){kr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()}finally{Wr()}}}function Ai(e){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let r=t.deps;r;r=r.nextDep)Ai(r)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}const An=new WeakMap,ht=Symbol(""),xr=Symbol(""),Kt=Symbol("");function ve(e,t,n){if(Le&&Z){let r=An.get(e);r||An.set(e,r=new Map);let s=r.get(n);s||r.set(n,s=new Dn),s.track()}}function Ge(e,t,n,r,s,i){const o=An.get(e);if(!o){Wt++;return}const l=c=>{c&&c.trigger()};if(kr(),t==="clear")o.forEach(l);else{const c=K(e),f=c&&Vr(n);if(c&&n==="length"){const a=Number(r);o.forEach((h,g)=>{(g==="length"||g===Kt||!rt(g)&&g>=a)&&l(h)})}else switch(n!==void 0&&l(o.get(n)),f&&l(o.get(Kt)),t){case"add":c?f&&l(o.get("length")):(l(o.get(ht)),Tt(e)&&l(o.get(xr)));break;case"delete":c||(l(o.get(ht)),Tt(e)&&l(o.get(xr)));break;case"set":Tt(e)&&l(o.get(ht));break}}Wr()}function ul(e,t){var n;return(n=An.get(e))==null?void 0:n.get(t)}function bt(e){const t=z(e);return t===e?t:(ve(t,"iterate",Kt),Pe(e)?t:t.map(me))}function jn(e){return ve(e=z(e),"iterate",Kt),e}const dl={__proto__:null,[Symbol.iterator](){return nr(this,Symbol.iterator,me)},concat(...e){return bt(this).concat(...e.map(t=>K(t)?bt(t):t))},entries(){return nr(this,"entries",e=>(e[1]=me(e[1]),e))},every(e,t){return We(this,"every",e,t,void 0,arguments)},filter(e,t){return We(this,"filter",e,t,n=>n.map(me),arguments)},find(e,t){return We(this,"find",e,t,me,arguments)},findIndex(e,t){return We(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return We(this,"findLast",e,t,me,arguments)},findLastIndex(e,t){return We(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return We(this,"forEach",e,t,void 0,arguments)},includes(...e){return rr(this,"includes",e)},indexOf(...e){return rr(this,"indexOf",e)},join(e){return bt(this).join(e)},lastIndexOf(...e){return rr(this,"lastIndexOf",e)},map(e,t){return We(this,"map",e,t,void 0,arguments)},pop(){return Ft(this,"pop")},push(...e){return Ft(this,"push",e)},reduce(e,...t){return ms(this,"reduce",e,t)},reduceRight(e,...t){return ms(this,"reduceRight",e,t)},shift(){return Ft(this,"shift")},some(e,t){return We(this,"some",e,t,void 0,arguments)},splice(...e){return Ft(this,"splice",e)},toReversed(){return bt(this).toReversed()},toSorted(e){return bt(this).toSorted(e)},toSpliced(...e){return bt(this).toSpliced(...e)},unshift(...e){return Ft(this,"unshift",e)},values(){return nr(this,"values",me)}};function nr(e,t,n){const r=jn(e),s=r[t]();return r!==e&&!Pe(e)&&(s._next=s.next,s.next=()=>{const i=s._next();return i.value&&(i.value=n(i.value)),i}),s}const hl=Array.prototype;function We(e,t,n,r,s,i){const o=jn(e),l=o!==e&&!Pe(e),c=o[t];if(c!==hl[t]){const h=c.apply(e,i);return l?me(h):h}let f=n;o!==e&&(l?f=function(h,g){return n.call(this,me(h),g,e)}:n.length>2&&(f=function(h,g){return n.call(this,h,g,e)}));const a=c.call(o,f,r);return l&&s?s(a):a}function ms(e,t,n,r){const s=jn(e);let i=n;return s!==e&&(Pe(e)?n.length>3&&(i=function(o,l,c){return n.call(this,o,l,c,e)}):i=function(o,l,c){return n.call(this,o,me(l),c,e)}),s[t](i,...r)}function rr(e,t,n){const r=z(e);ve(r,"iterate",Kt);const s=r[t](...n);return(s===-1||s===!1)&&Xr(n[0])?(n[0]=z(n[0]),r[t](...n)):s}function Ft(e,t,n=[]){it(),kr();const r=z(e)[t].apply(e,n);return Wr(),ot(),r}const pl=$r("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(rt));function gl(e){rt(e)||(e=String(e));const t=z(this);return ve(t,"has",e),t.hasOwnProperty(e)}class Oi{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){const s=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return i;if(n==="__v_raw")return r===(s?i?Rl:Li:i?Ii:Pi).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const o=K(t);if(!s){let c;if(o&&(c=dl[n]))return c;if(n==="hasOwnProperty")return gl}const l=Reflect.get(t,n,ae(t)?t:r);return(rt(n)?Ri.has(n):pl(n))||(s||ve(t,"get",n),i)?l:ae(l)?o&&Vr(n)?l:l.value:ne(l)?s?Bn(l):Un(l):l}}class Mi extends Oi{constructor(t=!1){super(!1,t)}set(t,n,r,s){let i=t[n];if(!this._isShallow){const c=vt(i);if(!Pe(r)&&!vt(r)&&(i=z(i),r=z(r)),!K(t)&&ae(i)&&!ae(r))return c?!1:(i.value=r,!0)}const o=K(t)&&Vr(n)?Number(n)e,Vn=e=>Reflect.getPrototypeOf(e);function ln(e,t,n=!1,r=!1){e=e.__v_raw;const s=z(e),i=z(t);n||(tt(t,i)&&ve(s,"get",t),ve(s,"get",i));const{has:o}=Vn(s),l=r?qr:n?zr:me;if(o.call(s,t))return l(e.get(t));if(o.call(s,i))return l(e.get(i));e!==s&&e.get(t)}function cn(e,t=!1){const n=this.__v_raw,r=z(n),s=z(e);return t||(tt(e,s)&&ve(r,"has",e),ve(r,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function an(e,t=!1){return e=e.__v_raw,!t&&ve(z(e),"iterate",ht),Reflect.get(e,"size",e)}function ys(e,t=!1){!t&&!Pe(e)&&!vt(e)&&(e=z(e));const n=z(this);return Vn(n).has.call(n,e)||(n.add(e),Ge(n,"add",e,e)),this}function vs(e,t,n=!1){!n&&!Pe(t)&&!vt(t)&&(t=z(t));const r=z(this),{has:s,get:i}=Vn(r);let o=s.call(r,e);o||(e=z(e),o=s.call(r,e));const l=i.call(r,e);return r.set(e,t),o?tt(t,l)&&Ge(r,"set",e,t):Ge(r,"add",e,t),this}function _s(e){const t=z(this),{has:n,get:r}=Vn(t);let s=n.call(t,e);s||(e=z(e),s=n.call(t,e)),r&&r.call(t,e);const i=t.delete(e);return s&&Ge(t,"delete",e,void 0),i}function bs(){const e=z(this),t=e.size!==0,n=e.clear();return t&&Ge(e,"clear",void 0,void 0),n}function fn(e,t){return function(r,s){const i=this,o=i.__v_raw,l=z(o),c=t?qr:e?zr:me;return!e&&ve(l,"iterate",ht),o.forEach((f,a)=>r.call(s,c(f),c(a),i))}}function un(e,t,n){return function(...r){const s=this.__v_raw,i=z(s),o=Tt(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,f=s[e](...r),a=n?qr:t?zr:me;return!t&&ve(i,"iterate",c?xr:ht),{next(){const{value:h,done:g}=f.next();return g?{value:h,done:g}:{value:l?[a(h[0]),a(h[1])]:a(h),done:g}},[Symbol.iterator](){return this}}}}function Xe(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function bl(){const e={get(i){return ln(this,i)},get size(){return an(this)},has:cn,add:ys,set:vs,delete:_s,clear:bs,forEach:fn(!1,!1)},t={get(i){return ln(this,i,!1,!0)},get size(){return an(this)},has:cn,add(i){return ys.call(this,i,!0)},set(i,o){return vs.call(this,i,o,!0)},delete:_s,clear:bs,forEach:fn(!1,!0)},n={get(i){return ln(this,i,!0)},get size(){return an(this,!0)},has(i){return cn.call(this,i,!0)},add:Xe("add"),set:Xe("set"),delete:Xe("delete"),clear:Xe("clear"),forEach:fn(!0,!1)},r={get(i){return ln(this,i,!0,!0)},get size(){return an(this,!0)},has(i){return cn.call(this,i,!0)},add:Xe("add"),set:Xe("set"),delete:Xe("delete"),clear:Xe("clear"),forEach:fn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(i=>{e[i]=un(i,!1,!1),n[i]=un(i,!0,!1),t[i]=un(i,!1,!0),r[i]=un(i,!0,!0)}),[e,n,t,r]}const[wl,Sl,El,xl]=bl();function Gr(e,t){const n=t?e?xl:El:e?Sl:wl;return(r,s,i)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?r:Reflect.get(J(n,s)&&s in r?n:r,s,i)}const Cl={get:Gr(!1,!1)},Tl={get:Gr(!1,!0)},Al={get:Gr(!0,!1)};const Pi=new WeakMap,Ii=new WeakMap,Li=new WeakMap,Rl=new WeakMap;function Ol(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ml(e){return e.__v_skip||!Object.isExtensible(e)?0:Ol(Jo(e))}function Un(e){return vt(e)?e:Yr(e,!1,yl,Cl,Pi)}function Pl(e){return Yr(e,!1,_l,Tl,Ii)}function Bn(e){return Yr(e,!0,vl,Al,Li)}function Yr(e,t,n,r,s){if(!ne(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=s.get(e);if(i)return i;const o=Ml(e);if(o===0)return e;const l=new Proxy(e,o===2?r:n);return s.set(e,l),l}function pt(e){return vt(e)?pt(e.__v_raw):!!(e&&e.__v_isReactive)}function vt(e){return!!(e&&e.__v_isReadonly)}function Pe(e){return!!(e&&e.__v_isShallow)}function Xr(e){return e?!!e.__v_raw:!1}function z(e){const t=e&&e.__v_raw;return t?z(t):e}function Sn(e){return!J(e,"__v_skip")&&Object.isExtensible(e)&&gi(e,"__v_skip",!0),e}const me=e=>ne(e)?Un(e):e,zr=e=>ne(e)?Bn(e):e;function ae(e){return e?e.__v_isRef===!0:!1}function oe(e){return Ni(e,!1)}function Jr(e){return Ni(e,!0)}function Ni(e,t){return ae(e)?e:new Il(e,t)}class Il{constructor(t,n){this.dep=new Dn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:z(t),this._value=n?t:me(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,r=this.__v_isShallow||Pe(t)||vt(t);t=r?t:z(t),tt(t,n)&&(this._rawValue=t,this._value=r?t:me(t),this.dep.trigger())}}function Fi(e){return ae(e)?e.value:e}const Ll={get:(e,t,n)=>t==="__v_raw"?e:Fi(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const s=e[t];return ae(s)&&!ae(n)?(s.value=n,!0):Reflect.set(e,t,n,r)}};function Hi(e){return pt(e)?e:new Proxy(e,Ll)}class Nl{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Dn,{get:r,set:s}=t(n.track.bind(n),n.trigger.bind(n));this._get=r,this._set=s}get value(){return this._value=this._get()}set value(t){this._set(t)}}function Fl(e){return new Nl(e)}class Hl{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return ul(z(this._object),this._key)}}class $l{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function Dl(e,t,n){return ae(e)?e:q(e)?new $l(e):ne(e)&&arguments.length>1?jl(e,t,n):oe(e)}function jl(e,t,n){const r=e[t];return ae(r)?r:new Hl(e,t,n)}class Vl{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Dn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Wt-1,this.effect=this,this.__v_isReadonly=!n,this.isSSR=r}notify(){this.flags|=16,Z!==this&&this.dep.notify()}get value(){const t=this.dep.track();return Ci(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Ul(e,t,n=!1){let r,s;return q(e)?r=e:(r=e.get,s=e.set),new Vl(r,s,n)}const dn={},Rn=new WeakMap;let ut;function Bl(e,t=!1,n=ut){if(n){let r=Rn.get(n);r||Rn.set(n,r=[]),r.push(e)}}function kl(e,t,n=ee){const{immediate:r,deep:s,once:i,scheduler:o,augmentJob:l,call:c}=n,f=m=>s?m:Pe(m)||s===!1||s===0?qe(m,1):qe(m);let a,h,g,_,b=!1,S=!1;if(ae(e)?(h=()=>e.value,b=Pe(e)):pt(e)?(h=()=>f(e),b=!0):K(e)?(S=!0,b=e.some(m=>pt(m)||Pe(m)),h=()=>e.map(m=>{if(ae(m))return m.value;if(pt(m))return f(m);if(q(m))return c?c(m,2):m()})):q(e)?t?h=c?()=>c(e,2):e:h=()=>{if(g){it();try{g()}finally{ot()}}const m=ut;ut=a;try{return c?c(e,3,[_]):e(_)}finally{ut=m}}:h=Ue,t&&s){const m=h,M=s===!0?1/0:s;h=()=>qe(m(),M)}const V=bi(),N=()=>{a.stop(),V&&jr(V.effects,a)};if(i)if(t){const m=t;t=(...M)=>{m(...M),N()}}else{const m=h;h=()=>{m(),N()}}let U=S?new Array(e.length).fill(dn):dn;const p=m=>{if(!(!(a.flags&1)||!a.dirty&&!m))if(t){const M=a.run();if(s||b||(S?M.some((F,$)=>tt(F,U[$])):tt(M,U))){g&&g();const F=ut;ut=a;try{const $=[M,U===dn?void 0:S&&U[0]===dn?[]:U,_];c?c(t,3,$):t(...$),U=M}finally{ut=F}}}else a.run()};return l&&l(p),a=new wi(h),a.scheduler=o?()=>o(p,!1):p,_=m=>Bl(m,!1,a),g=a.onStop=()=>{const m=Rn.get(a);if(m){if(c)c(m,4);else for(const M of m)M();Rn.delete(a)}},t?r?p(!0):U=a.run():o?o(p.bind(null,!0),!0):a.run(),N.pause=a.pause.bind(a),N.resume=a.resume.bind(a),N.stop=N,N}function qe(e,t=1/0,n){if(t<=0||!ne(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,ae(e))qe(e.value,t,n);else if(K(e))for(let r=0;r{qe(r,t,n)});else if(pi(e)){for(const r in e)qe(e[r],t,n);for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&qe(e[r],t,n)}return e}/** +* @vue/runtime-core v3.5.4 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Zt(e,t,n,r){try{return r?e(...r):e()}catch(s){en(s,t,n)}}function Fe(e,t,n,r){if(q(e)){const s=Zt(e,t,n,r);return s&&di(s)&&s.catch(i=>{en(i,t,n)}),s}if(K(e)){const s=[];for(let i=0;i>>1,s=we[r],i=Gt(s);i=Gt(n)?we.push(e):we.splice(Kl(t),0,e),e.flags|=1,Di()}}function Di(){!qt&&!Cr&&(Cr=!0,Qr=$i.then(ji))}function ql(e){K(e)?Rt.push(...e):Qe&&e.id===-1?Qe.splice(St+1,0,e):e.flags&1||(Rt.push(e),e.flags|=1),Di()}function ws(e,t,n=qt?je+1:0){for(;nGt(n)-Gt(r));if(Rt.length=0,Qe){Qe.push(...t);return}for(Qe=t,St=0;Ste.id==null?e.flags&2?-1:1/0:e.id;function ji(e){Cr=!1,qt=!0;try{for(je=0;je{r._d&&Fs(-1);const i=Mn(t);let o;try{o=e(...s)}finally{Mn(i),r._d&&Fs(1)}return o};return r._n=!0,r._c=!0,r._d=!0,r}function Mf(e,t){if(de===null)return e;const n=zn(de),r=e.dirs||(e.dirs=[]);for(let s=0;se.__isTeleport,jt=e=>e&&(e.disabled||e.disabled===""),Yl=e=>e&&(e.defer||e.defer===""),Ss=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Es=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Tr=(e,t)=>{const n=e&&e.to;return se(n)?t?t(n):null:n},Xl={name:"Teleport",__isTeleport:!0,process(e,t,n,r,s,i,o,l,c,f){const{mc:a,pc:h,pbc:g,o:{insert:_,querySelector:b,createText:S,createComment:V}}=f,N=jt(t.props);let{shapeFlag:U,children:p,dynamicChildren:m}=t;if(e==null){const M=t.el=S(""),F=t.anchor=S("");_(M,n,r),_(F,n,r);const $=(R,v)=>{U&16&&a(p,R,v,s,i,o,l,c)},D=()=>{const R=t.target=Tr(t.props,b),v=ki(R,t,S,_);R&&(o!=="svg"&&Ss(R)?o="svg":o!=="mathml"&&Es(R)&&(o="mathml"),N||($(R,v),En(t)))};N&&($(n,F),En(t)),Yl(t.props)?Ee(D,i):D()}else{t.el=e.el,t.targetStart=e.targetStart;const M=t.anchor=e.anchor,F=t.target=e.target,$=t.targetAnchor=e.targetAnchor,D=jt(e.props),R=D?n:F,v=D?M:$;if(o==="svg"||Ss(F)?o="svg":(o==="mathml"||Es(F))&&(o="mathml"),m?(g(e.dynamicChildren,m,R,s,i,o,l),ss(e,t,!0)):c||h(e,t,R,v,s,i,o,l,!1),N)D?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):hn(t,n,M,f,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const L=t.target=Tr(t.props,b);L&&hn(t,L,null,f,0)}else D&&hn(t,F,$,f,1);En(t)}},remove(e,t,n,{um:r,o:{remove:s}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:f,targetAnchor:a,target:h,props:g}=e;if(h&&(s(f),s(a)),i&&s(c),o&16){const _=i||!jt(g);for(let b=0;b{e.isMounted=!0}),zi(()=>{e.isUnmounting=!0}),e}const Re=[Function,Array],Wi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Re,onEnter:Re,onAfterEnter:Re,onEnterCancelled:Re,onBeforeLeave:Re,onLeave:Re,onAfterLeave:Re,onLeaveCancelled:Re,onBeforeAppear:Re,onAppear:Re,onAfterAppear:Re,onAppearCancelled:Re},Ki=e=>{const t=e.subTree;return t.component?Ki(t.component):t},Ql={name:"BaseTransition",props:Wi,setup(e,{slots:t}){const n=Xn(),r=Jl();return()=>{const s=t.default&&Yi(t.default(),!0);if(!s||!s.length)return;const i=qi(s),o=z(e),{mode:l}=o;if(r.isLeaving)return sr(i);const c=xs(i);if(!c)return sr(i);let f=Ar(c,o,r,n,g=>f=g);c.type!==ye&&Yt(c,f);const a=n.subTree,h=a&&xs(a);if(h&&h.type!==ye&&!dt(c,h)&&Ki(n).type!==ye){const g=Ar(h,o,r,n);if(Yt(h,g),l==="out-in"&&c.type!==ye)return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.job.flags&8||n.update(),delete g.afterLeave},sr(i);l==="in-out"&&c.type!==ye&&(g.delayLeave=(_,b,S)=>{const V=Gi(r,h);V[String(h.key)]=h,_[Ze]=()=>{b(),_[Ze]=void 0,delete f.delayedLeave},f.delayedLeave=S})}return i}}};function qi(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ye){t=n;break}}return t}const Zl=Ql;function Gi(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function Ar(e,t,n,r,s){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:f,onAfterEnter:a,onEnterCancelled:h,onBeforeLeave:g,onLeave:_,onAfterLeave:b,onLeaveCancelled:S,onBeforeAppear:V,onAppear:N,onAfterAppear:U,onAppearCancelled:p}=t,m=String(e.key),M=Gi(n,e),F=(R,v)=>{R&&Fe(R,r,9,v)},$=(R,v)=>{const L=v[1];F(R,v),K(R)?R.every(x=>x.length<=1)&&L():R.length<=1&&L()},D={mode:o,persisted:l,beforeEnter(R){let v=c;if(!n.isMounted)if(i)v=V||c;else return;R[Ze]&&R[Ze](!0);const L=M[m];L&&dt(e,L)&&L.el[Ze]&&L.el[Ze](),F(v,[R])},enter(R){let v=f,L=a,x=h;if(!n.isMounted)if(i)v=N||f,L=U||a,x=p||h;else return;let W=!1;const re=R[pn]=ce=>{W||(W=!0,ce?F(x,[R]):F(L,[R]),D.delayedLeave&&D.delayedLeave(),R[pn]=void 0)};v?$(v,[R,re]):re()},leave(R,v){const L=String(e.key);if(R[pn]&&R[pn](!0),n.isUnmounting)return v();F(g,[R]);let x=!1;const W=R[Ze]=re=>{x||(x=!0,v(),re?F(S,[R]):F(b,[R]),R[Ze]=void 0,M[L]===e&&delete M[L])};M[L]=e,_?$(_,[R,W]):W()},clone(R){const v=Ar(R,t,n,r,s);return s&&s(v),v}};return D}function sr(e){if(tn(e))return e=nt(e),e.children=null,e}function xs(e){if(!tn(e))return Bi(e.type)&&e.children?qi(e.children):e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&q(n.default))return n.default()}}function Yt(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Yt(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Yi(e,t=!1,n){let r=[],s=0;for(let i=0;i1)for(let i=0;iPn(b,t&&(K(t)?t[S]:t),n,r,s));return}if(gt(r)&&!s)return;const i=r.shapeFlag&4?zn(r.component):r.el,o=s?null:i,{i:l,r:c}=e,f=t&&t.r,a=l.refs===ee?l.refs={}:l.refs,h=l.setupState,g=z(h),_=h===ee?()=>!1:b=>J(g,b);if(f!=null&&f!==c&&(se(f)?(a[f]=null,_(f)&&(h[f]=null)):ae(f)&&(f.value=null)),q(c))Zt(c,l,12,[o,a]);else{const b=se(c),S=ae(c);if(b||S){const V=()=>{if(e.f){const N=b?_(c)?h[c]:a[c]:c.value;s?K(N)&&jr(N,i):K(N)?N.includes(i)||N.push(i):b?(a[c]=[i],_(c)&&(h[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else b?(a[c]=o,_(c)&&(h[c]=o)):S&&(c.value=o,e.k&&(a[e.k]=o))};o?(V.id=-1,Ee(V,n)):V()}}}let Cs=!1;const wt=()=>{Cs||(console.error("Hydration completed but contains mismatches."),Cs=!0)},ec=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",tc=e=>e.namespaceURI.includes("MathML"),gn=e=>{if(e.nodeType===1){if(ec(e))return"svg";if(tc(e))return"mathml"}},xt=e=>e.nodeType===8;function nc(e){const{mt:t,p:n,o:{patchProp:r,createText:s,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:f}}=e,a=(p,m)=>{if(!m.hasChildNodes()){n(null,p,m),On(),m._vnode=p;return}h(m.firstChild,p,null,null,null),On(),m._vnode=p},h=(p,m,M,F,$,D=!1)=>{D=D||!!m.dynamicChildren;const R=xt(p)&&p.data==="[",v=()=>S(p,m,M,F,$,R),{type:L,ref:x,shapeFlag:W,patchFlag:re}=m;let ce=p.nodeType;m.el=p,re===-2&&(D=!1,m.dynamicChildren=null);let j=null;switch(L){case mt:ce!==3?m.children===""?(c(m.el=s(""),o(p),p),j=p):j=v():(p.data!==m.children&&(wt(),p.data=m.children),j=i(p));break;case ye:U(p)?(j=i(p),N(m.el=p.content.firstChild,p,M)):ce!==8||R?j=v():j=i(p);break;case Ut:if(R&&(p=i(p),ce=p.nodeType),ce===1||ce===3){j=p;const Y=!m.children.length;for(let B=0;B{D=D||!!m.dynamicChildren;const{type:R,props:v,patchFlag:L,shapeFlag:x,dirs:W,transition:re}=m,ce=R==="input"||R==="option";if(ce||L!==-1){W&&Ve(m,null,M,"created");let j=!1;if(U(p)){j=ho(F,re)&&M&&M.vnode.props&&M.vnode.props.appear;const B=p.content.firstChild;j&&re.beforeEnter(B),N(B,p,M),m.el=p=B}if(x&16&&!(v&&(v.innerHTML||v.textContent))){let B=_(p.firstChild,m,p,M,F,$,D);for(;B;){mn(p,1)||wt();const he=B;B=B.nextSibling,l(he)}}else x&8&&p.textContent!==m.children&&(mn(p,0)||wt(),p.textContent=m.children);if(v){if(ce||!D||L&48){const B=p.tagName.includes("-");for(const he in v)(ce&&(he.endsWith("value")||he==="indeterminate")||Qt(he)&&!At(he)||he[0]==="."||B)&&r(p,he,null,v[he],void 0,M)}else if(v.onClick)r(p,"onClick",null,v.onClick,void 0,M);else if(L&4&&pt(v.style))for(const B in v.style)v.style[B]}let Y;(Y=v&&v.onVnodeBeforeMount)&&Oe(Y,M,m),W&&Ve(m,null,M,"beforeMount"),((Y=v&&v.onVnodeMounted)||W||j)&&vo(()=>{Y&&Oe(Y,M,m),j&&re.enter(p),W&&Ve(m,null,M,"mounted")},F)}return p.nextSibling},_=(p,m,M,F,$,D,R)=>{R=R||!!m.dynamicChildren;const v=m.children,L=v.length;for(let x=0;x{const{slotScopeIds:R}=m;R&&($=$?$.concat(R):R);const v=o(p),L=_(i(p),m,v,M,F,$,D);return L&&xt(L)&&L.data==="]"?i(m.anchor=L):(wt(),c(m.anchor=f("]"),v,L),L)},S=(p,m,M,F,$,D)=>{if(mn(p.parentElement,1)||wt(),m.el=null,D){const L=V(p);for(;;){const x=i(p);if(x&&x!==L)l(x);else break}}const R=i(p),v=o(p);return l(p),n(null,m,v,R,M,F,gn(v),$),R},V=(p,m="[",M="]")=>{let F=0;for(;p;)if(p=i(p),p&&xt(p)&&(p.data===m&&F++,p.data===M)){if(F===0)return i(p);F--}return p},N=(p,m,M)=>{const F=m.parentNode;F&&F.replaceChild(p,m);let $=M;for(;$;)$.vnode.el===m&&($.vnode.el=$.subTree.el=p),$=$.parent},U=p=>p.nodeType===1&&p.tagName.toLowerCase()==="template";return[a,h]}const Ts="data-allow-mismatch",rc={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function mn(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(Ts);)e=e.parentElement;const n=e&&e.getAttribute(Ts);if(n==null)return!1;if(n==="")return!0;{const r=n.split(",");return t===0&&r.includes("children")?!0:n.split(",").includes(rc[t])}}function sc(e,t){if(xt(e)&&e.data==="["){let n=1,r=e.nextSibling;for(;r;){if(r.nodeType===1)t(r);else if(xt(r))if(r.data==="]"){if(--n===0)break}else r.data==="["&&n++;r=r.nextSibling}}else t(e)}const gt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function If(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:s=200,hydrate:i,timeout:o,suspensible:l=!0,onError:c}=e;let f=null,a,h=0;const g=()=>(h++,f=null,_()),_=()=>{let b;return f||(b=f=t().catch(S=>{if(S=S instanceof Error?S:new Error(String(S)),c)return new Promise((V,N)=>{c(S,()=>V(g()),()=>N(S),h+1)});throw S}).then(S=>b!==f&&f?f:(S&&(S.__esModule||S[Symbol.toStringTag]==="Module")&&(S=S.default),a=S,S)))};return Zr({name:"AsyncComponentWrapper",__asyncLoader:_,__asyncHydrate(b,S,V){const N=i?()=>{const U=i(V,p=>sc(b,p));U&&(S.bum||(S.bum=[])).push(U)}:V;a?N():_().then(()=>!S.isUnmounted&&N())},get __asyncResolved(){return a},setup(){const b=ue;if(es(b),a)return()=>ir(a,b);const S=p=>{f=null,en(p,b,13,!r)};if(l&&b.suspense||rn)return _().then(p=>()=>ir(p,b)).catch(p=>(S(p),()=>r?le(r,{error:p}):null));const V=oe(!1),N=oe(),U=oe(!!s);return s&&setTimeout(()=>{U.value=!1},s),o!=null&&setTimeout(()=>{if(!V.value&&!N.value){const p=new Error(`Async component timed out after ${o}ms.`);S(p),N.value=p}},o),_().then(()=>{V.value=!0,b.parent&&tn(b.parent.vnode)&&Wn(b.parent.update)}).catch(p=>{S(p),N.value=p}),()=>{if(V.value&&a)return ir(a,b);if(N.value&&r)return le(r,{error:N.value});if(n&&!U.value)return le(n)}}})}function ir(e,t){const{ref:n,props:r,children:s,ce:i}=t.vnode,o=le(e,r,s);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const tn=e=>e.type.__isKeepAlive;function ic(e,t){Xi(e,"a",t)}function oc(e,t){Xi(e,"da",t)}function Xi(e,t,n=ue){const r=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Kn(t,r,n),n){let s=n.parent;for(;s&&s.parent;)tn(s.parent.vnode)&&lc(r,t,n,s),s=s.parent}}function lc(e,t,n,r){const s=Kn(t,e,r,!0);qn(()=>{jr(r[t],s)},n)}function Kn(e,t,n=ue,r=!1){if(n){const s=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{it();const l=nn(n),c=Fe(t,n,e,o);return l(),ot(),c});return r?s.unshift(i):s.push(i),i}}const Ye=e=>(t,n=ue)=>{(!rn||e==="sp")&&Kn(e,(...r)=>t(...r),n)},cc=Ye("bm"),It=Ye("m"),ac=Ye("bu"),fc=Ye("u"),zi=Ye("bum"),qn=Ye("um"),uc=Ye("sp"),dc=Ye("rtg"),hc=Ye("rtc");function pc(e,t=ue){Kn("ec",e,t)}const ts="components";function Lf(e,t){return Qi(ts,e,!0,t)||e}const Ji=Symbol.for("v-ndc");function Nf(e){return se(e)?Qi(ts,e,!1)||e:e||Ji}function Qi(e,t,n=!0,r=!1){const s=de||ue;if(s){const i=s.type;if(e===ts){const l=Zc(i,!1);if(l&&(l===t||l===Ne(t)||l===$n(Ne(t))))return i}const o=As(s[e]||i[e],t)||As(s.appContext[e],t);return!o&&r?i:o}}function As(e,t){return e&&(e[t]||e[Ne(t)]||e[$n(Ne(t))])}function Ff(e,t,n,r){let s;const i=n,o=K(e);if(o||se(e)){const l=o&&pt(e);let c=!1;l&&(c=!Pe(e),e=jn(e)),s=new Array(e.length);for(let f=0,a=e.length;ft(l,c,void 0,i));else{const l=Object.keys(e);s=new Array(l.length);for(let c=0,f=l.length;cLn(t)?!(t.type===ye||t.type===Se&&!Zi(t.children)):!0)?e:null}function $f(e,t){const n={};for(const r in e)n[/[A-Z]/.test(r)?`on:${r}`:bn(r)]=e[r];return n}const Rr=e=>e?Eo(e)?zn(e):Rr(e.parent):null,Vt=fe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Rr(e.parent),$root:e=>Rr(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>ns(e),$forceUpdate:e=>e.f||(e.f=()=>{Wn(e.update)}),$nextTick:e=>e.n||(e.n=kn.bind(e.proxy)),$watch:e=>Hc.bind(e)}),or=(e,t)=>e!==ee&&!e.__isScriptSetup&&J(e,t),gc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:s,props:i,accessCache:o,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const _=o[t];if(_!==void 0)switch(_){case 1:return r[t];case 2:return s[t];case 4:return n[t];case 3:return i[t]}else{if(or(r,t))return o[t]=1,r[t];if(s!==ee&&J(s,t))return o[t]=2,s[t];if((f=e.propsOptions[0])&&J(f,t))return o[t]=3,i[t];if(n!==ee&&J(n,t))return o[t]=4,n[t];Or&&(o[t]=0)}}const a=Vt[t];let h,g;if(a)return t==="$attrs"&&ve(e.attrs,"get",""),a(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ee&&J(n,t))return o[t]=4,n[t];if(g=c.config.globalProperties,J(g,t))return g[t]},set({_:e},t,n){const{data:r,setupState:s,ctx:i}=e;return or(s,t)?(s[t]=n,!0):r!==ee&&J(r,t)?(r[t]=n,!0):J(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:s,propsOptions:i}},o){let l;return!!n[o]||e!==ee&&J(e,o)||or(t,o)||(l=i[0])&&J(l,o)||J(r,o)||J(Vt,o)||J(s.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:J(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Df(){return mc().slots}function mc(){const e=Xn();return e.setupContext||(e.setupContext=Co(e))}function Rs(e){return K(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Or=!0;function yc(e){const t=ns(e),n=e.proxy,r=e.ctx;Or=!1,t.beforeCreate&&Os(t.beforeCreate,e,"bc");const{data:s,computed:i,methods:o,watch:l,provide:c,inject:f,created:a,beforeMount:h,mounted:g,beforeUpdate:_,updated:b,activated:S,deactivated:V,beforeDestroy:N,beforeUnmount:U,destroyed:p,unmounted:m,render:M,renderTracked:F,renderTriggered:$,errorCaptured:D,serverPrefetch:R,expose:v,inheritAttrs:L,components:x,directives:W,filters:re}=t;if(f&&vc(f,r,null),o)for(const Y in o){const B=o[Y];q(B)&&(r[Y]=B.bind(n))}if(s){const Y=s.call(n,n);ne(Y)&&(e.data=Un(Y))}if(Or=!0,i)for(const Y in i){const B=i[Y],he=q(B)?B.bind(n,n):q(B.get)?B.get.bind(n,n):Ue,sn=!q(B)&&q(B.set)?B.set.bind(n):Ue,lt=ie({get:he,set:sn});Object.defineProperty(r,Y,{enumerable:!0,configurable:!0,get:()=>lt.value,set:$e=>lt.value=$e})}if(l)for(const Y in l)eo(l[Y],r,n,Y);if(c){const Y=q(c)?c.call(n):c;Reflect.ownKeys(Y).forEach(B=>{xc(B,Y[B])})}a&&Os(a,e,"c");function j(Y,B){K(B)?B.forEach(he=>Y(he.bind(n))):B&&Y(B.bind(n))}if(j(cc,h),j(It,g),j(ac,_),j(fc,b),j(ic,S),j(oc,V),j(pc,D),j(hc,F),j(dc,$),j(zi,U),j(qn,m),j(uc,R),K(v))if(v.length){const Y=e.exposed||(e.exposed={});v.forEach(B=>{Object.defineProperty(Y,B,{get:()=>n[B],set:he=>n[B]=he})})}else e.exposed||(e.exposed={});M&&e.render===Ue&&(e.render=M),L!=null&&(e.inheritAttrs=L),x&&(e.components=x),W&&(e.directives=W),R&&es(e)}function vc(e,t,n=Ue){K(e)&&(e=Mr(e));for(const r in e){const s=e[r];let i;ne(s)?"default"in s?i=Mt(s.from||r,s.default,!0):i=Mt(s.from||r):i=Mt(s),ae(i)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[r]=i}}function Os(e,t,n){Fe(K(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function eo(e,t,n,r){let s=r.includes(".")?go(n,r):()=>n[r];if(se(e)){const i=t[e];q(i)&&Be(s,i)}else if(q(e))Be(s,e.bind(n));else if(ne(e))if(K(e))e.forEach(i=>eo(i,t,n,r));else{const i=q(e.handler)?e.handler.bind(n):t[e.handler];q(i)&&Be(s,i,e)}}function ns(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:s,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!s.length&&!n&&!r?c=t:(c={},s.length&&s.forEach(f=>In(c,f,o,!0)),In(c,t,o)),ne(t)&&i.set(t,c),c}function In(e,t,n,r=!1){const{mixins:s,extends:i}=t;i&&In(e,i,n,!0),s&&s.forEach(o=>In(e,o,n,!0));for(const o in t)if(!(r&&o==="expose")){const l=_c[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const _c={data:Ms,props:Ps,emits:Ps,methods:$t,computed:$t,beforeCreate:_e,created:_e,beforeMount:_e,mounted:_e,beforeUpdate:_e,updated:_e,beforeDestroy:_e,beforeUnmount:_e,destroyed:_e,unmounted:_e,activated:_e,deactivated:_e,errorCaptured:_e,serverPrefetch:_e,components:$t,directives:$t,watch:wc,provide:Ms,inject:bc};function Ms(e,t){return t?e?function(){return fe(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function bc(e,t){return $t(Mr(e),Mr(t))}function Mr(e){if(K(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(r&&r.proxy):t}}const no={},ro=()=>Object.create(no),so=e=>Object.getPrototypeOf(e)===no;function Cc(e,t,n,r=!1){const s={},i=ro();e.propsDefaults=Object.create(null),io(e,t,s,i);for(const o in e.propsOptions[0])o in s||(s[o]=void 0);n?e.props=r?s:Pl(s):e.type.props?e.props=s:e.props=i,e.attrs=i}function Tc(e,t,n,r){const{props:s,attrs:i,vnode:{patchFlag:o}}=e,l=z(s),[c]=e.propsOptions;let f=!1;if((r||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[g,_]=oo(h,t,!0);fe(o,g),_&&l.push(..._)};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!i&&!c)return ne(e)&&r.set(e,Ct),Ct;if(K(i))for(let a=0;ae[0]==="_"||e==="$stable",rs=e=>K(e)?e.map(Me):[Me(e)],Rc=(e,t,n)=>{if(t._n)return t;const r=Gl((...s)=>rs(t(...s)),n);return r._c=!1,r},co=(e,t,n)=>{const r=e._ctx;for(const s in e){if(lo(s))continue;const i=e[s];if(q(i))t[s]=Rc(s,i,r);else if(i!=null){const o=rs(i);t[s]=()=>o}}},ao=(e,t)=>{const n=rs(t);e.slots.default=()=>n},fo=(e,t,n)=>{for(const r in t)(n||r!=="_")&&(e[r]=t[r])},Oc=(e,t,n)=>{const r=e.slots=ro();if(e.vnode.shapeFlag&32){const s=t._;s?(fo(r,t,n),n&&gi(r,"_",s,!0)):co(t,r)}else t&&ao(e,t)},Mc=(e,t,n)=>{const{vnode:r,slots:s}=e;let i=!0,o=ee;if(r.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:fo(s,t,n):(i=!t.$stable,co(t,s)),o=t}else t&&(ao(e,t),o={default:1});if(i)for(const l in s)!lo(l)&&o[l]==null&&delete s[l]},Ee=vo;function Pc(e){return uo(e)}function Ic(e){return uo(e,nc)}function uo(e,t){const n=mi();n.__VUE__=!0;const{insert:r,remove:s,patchProp:i,createElement:o,createText:l,createComment:c,setText:f,setElementText:a,parentNode:h,nextSibling:g,setScopeId:_=Ue,insertStaticContent:b}=e,S=(u,d,y,C=null,w=null,E=null,P=void 0,O=null,A=!!d.dynamicChildren)=>{if(u===d)return;u&&!dt(u,d)&&(C=on(u),$e(u,w,E,!0),u=null),d.patchFlag===-2&&(A=!1,d.dynamicChildren=null);const{type:T,ref:k,shapeFlag:I}=d;switch(T){case mt:V(u,d,y,C);break;case ye:N(u,d,y,C);break;case Ut:u==null&&U(d,y,C,P);break;case Se:x(u,d,y,C,w,E,P,O,A);break;default:I&1?M(u,d,y,C,w,E,P,O,A):I&6?W(u,d,y,C,w,E,P,O,A):(I&64||I&128)&&T.process(u,d,y,C,w,E,P,O,A,_t)}k!=null&&w&&Pn(k,u&&u.ref,E,d||u,!d)},V=(u,d,y,C)=>{if(u==null)r(d.el=l(d.children),y,C);else{const w=d.el=u.el;d.children!==u.children&&f(w,d.children)}},N=(u,d,y,C)=>{u==null?r(d.el=c(d.children||""),y,C):d.el=u.el},U=(u,d,y,C)=>{[u.el,u.anchor]=b(u.children,d,y,C,u.el,u.anchor)},p=({el:u,anchor:d},y,C)=>{let w;for(;u&&u!==d;)w=g(u),r(u,y,C),u=w;r(d,y,C)},m=({el:u,anchor:d})=>{let y;for(;u&&u!==d;)y=g(u),s(u),u=y;s(d)},M=(u,d,y,C,w,E,P,O,A)=>{d.type==="svg"?P="svg":d.type==="math"&&(P="mathml"),u==null?F(d,y,C,w,E,P,O,A):R(u,d,w,E,P,O,A)},F=(u,d,y,C,w,E,P,O)=>{let A,T;const{props:k,shapeFlag:I,transition:H,dirs:G}=u;if(A=u.el=o(u.type,E,k&&k.is,k),I&8?a(A,u.children):I&16&&D(u.children,A,null,C,w,lr(u,E),P,O),G&&Ve(u,null,C,"created"),$(A,u,u.scopeId,P,C),k){for(const te in k)te!=="value"&&!At(te)&&i(A,te,null,k[te],E,C);"value"in k&&i(A,"value",null,k.value,E),(T=k.onVnodeBeforeMount)&&Oe(T,C,u)}G&&Ve(u,null,C,"beforeMount");const X=ho(w,H);X&&H.beforeEnter(A),r(A,d,y),((T=k&&k.onVnodeMounted)||X||G)&&Ee(()=>{T&&Oe(T,C,u),X&&H.enter(A),G&&Ve(u,null,C,"mounted")},w)},$=(u,d,y,C,w)=>{if(y&&_(u,y),C)for(let E=0;E{for(let T=A;T{const O=d.el=u.el;let{patchFlag:A,dynamicChildren:T,dirs:k}=d;A|=u.patchFlag&16;const I=u.props||ee,H=d.props||ee;let G;if(y&&ct(y,!1),(G=H.onVnodeBeforeUpdate)&&Oe(G,y,d,u),k&&Ve(d,u,y,"beforeUpdate"),y&&ct(y,!0),(I.innerHTML&&H.innerHTML==null||I.textContent&&H.textContent==null)&&a(O,""),T?v(u.dynamicChildren,T,O,y,C,lr(d,w),E):P||B(u,d,O,null,y,C,lr(d,w),E,!1),A>0){if(A&16)L(O,I,H,y,w);else if(A&2&&I.class!==H.class&&i(O,"class",null,H.class,w),A&4&&i(O,"style",I.style,H.style,w),A&8){const X=d.dynamicProps;for(let te=0;te{G&&Oe(G,y,d,u),k&&Ve(d,u,y,"updated")},C)},v=(u,d,y,C,w,E,P)=>{for(let O=0;O{if(d!==y){if(d!==ee)for(const E in d)!At(E)&&!(E in y)&&i(u,E,d[E],null,w,C);for(const E in y){if(At(E))continue;const P=y[E],O=d[E];P!==O&&E!=="value"&&i(u,E,O,P,w,C)}"value"in y&&i(u,"value",d.value,y.value,w)}},x=(u,d,y,C,w,E,P,O,A)=>{const T=d.el=u?u.el:l(""),k=d.anchor=u?u.anchor:l("");let{patchFlag:I,dynamicChildren:H,slotScopeIds:G}=d;G&&(O=O?O.concat(G):G),u==null?(r(T,y,C),r(k,y,C),D(d.children||[],y,k,w,E,P,O,A)):I>0&&I&64&&H&&u.dynamicChildren?(v(u.dynamicChildren,H,y,w,E,P,O),(d.key!=null||w&&d===w.subTree)&&ss(u,d,!0)):B(u,d,y,k,w,E,P,O,A)},W=(u,d,y,C,w,E,P,O,A)=>{d.slotScopeIds=O,u==null?d.shapeFlag&512?w.ctx.activate(d,y,C,P,A):re(d,y,C,w,E,P,A):ce(u,d,A)},re=(u,d,y,C,w,E,P)=>{const O=u.component=Xc(u,C,w);if(tn(u)&&(O.ctx.renderer=_t),zc(O,!1,P),O.asyncDep){if(w&&w.registerDep(O,j,P),!u.el){const A=O.subTree=le(ye);N(null,A,d,y)}}else j(O,u,d,y,w,E,P)},ce=(u,d,y)=>{const C=d.component=u.component;if(Uc(u,d,y))if(C.asyncDep&&!C.asyncResolved){Y(C,d,y);return}else C.next=d,C.update();else d.el=u.el,C.vnode=d},j=(u,d,y,C,w,E,P)=>{const O=()=>{if(u.isMounted){let{next:I,bu:H,u:G,parent:X,vnode:te}=u;{const Ce=po(u);if(Ce){I&&(I.el=te.el,Y(u,I,P)),Ce.asyncDep.then(()=>{u.isUnmounted||O()});return}}let Q=I,xe;ct(u,!1),I?(I.el=te.el,Y(u,I,P)):I=te,H&&wn(H),(xe=I.props&&I.props.onVnodeBeforeUpdate)&&Oe(xe,X,I,te),ct(u,!0);const pe=cr(u),Ie=u.subTree;u.subTree=pe,S(Ie,pe,h(Ie.el),on(Ie),u,w,E),I.el=pe.el,Q===null&&Bc(u,pe.el),G&&Ee(G,w),(xe=I.props&&I.props.onVnodeUpdated)&&Ee(()=>Oe(xe,X,I,te),w)}else{let I;const{el:H,props:G}=d,{bm:X,m:te,parent:Q,root:xe,type:pe}=u,Ie=gt(d);if(ct(u,!1),X&&wn(X),!Ie&&(I=G&&G.onVnodeBeforeMount)&&Oe(I,Q,d),ct(u,!0),H&&Zn){const Ce=()=>{u.subTree=cr(u),Zn(H,u.subTree,u,w,null)};Ie&&pe.__asyncHydrate?pe.__asyncHydrate(H,u,Ce):Ce()}else{xe.ce&&xe.ce._injectChildStyle(pe);const Ce=u.subTree=cr(u);S(null,Ce,y,C,u,w,E),d.el=Ce.el}if(te&&Ee(te,w),!Ie&&(I=G&&G.onVnodeMounted)){const Ce=d;Ee(()=>Oe(I,Q,Ce),w)}(d.shapeFlag&256||Q&>(Q.vnode)&&Q.vnode.shapeFlag&256)&&u.a&&Ee(u.a,w),u.isMounted=!0,d=y=C=null}};u.scope.on();const A=u.effect=new wi(O);u.scope.off();const T=u.update=A.run.bind(A),k=u.job=A.runIfDirty.bind(A);k.i=u,k.id=u.uid,A.scheduler=()=>Wn(k),ct(u,!0),T()},Y=(u,d,y)=>{d.component=u;const C=u.vnode.props;u.vnode=d,u.next=null,Tc(u,d.props,C,y),Mc(u,d.children,y),it(),ws(u),ot()},B=(u,d,y,C,w,E,P,O,A=!1)=>{const T=u&&u.children,k=u?u.shapeFlag:0,I=d.children,{patchFlag:H,shapeFlag:G}=d;if(H>0){if(H&128){sn(T,I,y,C,w,E,P,O,A);return}else if(H&256){he(T,I,y,C,w,E,P,O,A);return}}G&8?(k&16&&Lt(T,w,E),I!==T&&a(y,I)):k&16?G&16?sn(T,I,y,C,w,E,P,O,A):Lt(T,w,E,!0):(k&8&&a(y,""),G&16&&D(I,y,C,w,E,P,O,A))},he=(u,d,y,C,w,E,P,O,A)=>{u=u||Ct,d=d||Ct;const T=u.length,k=d.length,I=Math.min(T,k);let H;for(H=0;Hk?Lt(u,w,E,!0,!1,I):D(d,y,C,w,E,P,O,A,I)},sn=(u,d,y,C,w,E,P,O,A)=>{let T=0;const k=d.length;let I=u.length-1,H=k-1;for(;T<=I&&T<=H;){const G=u[T],X=d[T]=A?et(d[T]):Me(d[T]);if(dt(G,X))S(G,X,y,null,w,E,P,O,A);else break;T++}for(;T<=I&&T<=H;){const G=u[I],X=d[H]=A?et(d[H]):Me(d[H]);if(dt(G,X))S(G,X,y,null,w,E,P,O,A);else break;I--,H--}if(T>I){if(T<=H){const G=H+1,X=GH)for(;T<=I;)$e(u[T],w,E,!0),T++;else{const G=T,X=T,te=new Map;for(T=X;T<=H;T++){const Te=d[T]=A?et(d[T]):Me(d[T]);Te.key!=null&&te.set(Te.key,T)}let Q,xe=0;const pe=H-X+1;let Ie=!1,Ce=0;const Nt=new Array(pe);for(T=0;T=pe){$e(Te,w,E,!0);continue}let De;if(Te.key!=null)De=te.get(Te.key);else for(Q=X;Q<=H;Q++)if(Nt[Q-X]===0&&dt(Te,d[Q])){De=Q;break}De===void 0?$e(Te,w,E,!0):(Nt[De-X]=T+1,De>=Ce?Ce=De:Ie=!0,S(Te,d[De],y,null,w,E,P,O,A),xe++)}const ds=Ie?Lc(Nt):Ct;for(Q=ds.length-1,T=pe-1;T>=0;T--){const Te=X+T,De=d[Te],hs=Te+1{const{el:E,type:P,transition:O,children:A,shapeFlag:T}=u;if(T&6){lt(u.component.subTree,d,y,C);return}if(T&128){u.suspense.move(d,y,C);return}if(T&64){P.move(u,d,y,_t);return}if(P===Se){r(E,d,y);for(let I=0;IO.enter(E),w);else{const{leave:I,delayLeave:H,afterLeave:G}=O,X=()=>r(E,d,y),te=()=>{I(E,()=>{X(),G&&G()})};H?H(E,X,te):te()}else r(E,d,y)},$e=(u,d,y,C=!1,w=!1)=>{const{type:E,props:P,ref:O,children:A,dynamicChildren:T,shapeFlag:k,patchFlag:I,dirs:H,cacheIndex:G}=u;if(I===-2&&(w=!1),O!=null&&Pn(O,null,y,u,!0),G!=null&&(d.renderCache[G]=void 0),k&256){d.ctx.deactivate(u);return}const X=k&1&&H,te=!gt(u);let Q;if(te&&(Q=P&&P.onVnodeBeforeUnmount)&&Oe(Q,d,u),k&6)Yo(u.component,y,C);else{if(k&128){u.suspense.unmount(y,C);return}X&&Ve(u,null,d,"beforeUnmount"),k&64?u.type.remove(u,d,y,_t,C):T&&!T.hasOnce&&(E!==Se||I>0&&I&64)?Lt(T,d,y,!1,!0):(E===Se&&I&384||!w&&k&16)&&Lt(A,d,y),C&&fs(u)}(te&&(Q=P&&P.onVnodeUnmounted)||X)&&Ee(()=>{Q&&Oe(Q,d,u),X&&Ve(u,null,d,"unmounted")},y)},fs=u=>{const{type:d,el:y,anchor:C,transition:w}=u;if(d===Se){Go(y,C);return}if(d===Ut){m(u);return}const E=()=>{s(y),w&&!w.persisted&&w.afterLeave&&w.afterLeave()};if(u.shapeFlag&1&&w&&!w.persisted){const{leave:P,delayLeave:O}=w,A=()=>P(y,E);O?O(u.el,E,A):A()}else E()},Go=(u,d)=>{let y;for(;u!==d;)y=g(u),s(u),u=y;s(d)},Yo=(u,d,y)=>{const{bum:C,scope:w,job:E,subTree:P,um:O,m:A,a:T}=u;Ls(A),Ls(T),C&&wn(C),w.stop(),E&&(E.flags|=8,$e(P,u,d,y)),O&&Ee(O,d),Ee(()=>{u.isUnmounted=!0},d),d&&d.pendingBranch&&!d.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===d.pendingId&&(d.deps--,d.deps===0&&d.resolve())},Lt=(u,d,y,C=!1,w=!1,E=0)=>{for(let P=E;P{if(u.shapeFlag&6)return on(u.component.subTree);if(u.shapeFlag&128)return u.suspense.next();const d=g(u.anchor||u.el),y=d&&d[Ui];return y?g(y):d};let Jn=!1;const us=(u,d,y)=>{u==null?d._vnode&&$e(d._vnode,null,null,!0):S(d._vnode||null,u,d,null,null,null,y),d._vnode=u,Jn||(Jn=!0,ws(),On(),Jn=!1)},_t={p:S,um:$e,m:lt,r:fs,mt:re,mc:D,pc:B,pbc:v,n:on,o:e};let Qn,Zn;return t&&([Qn,Zn]=t(_t)),{render:us,hydrate:Qn,createApp:Ec(us,Qn)}}function lr({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function ct({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ho(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ss(e,t,n=!1){const r=e.children,s=t.children;if(K(r)&&K(s))for(let i=0;i>1,e[n[l]]0&&(t[r]=n[i-1]),n[i]=r)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function po(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:po(t)}function Ls(e){if(e)for(let t=0;tMt(Nc);function is(e,t){return Gn(e,null,t)}function jf(e,t){return Gn(e,null,{flush:"post"})}function Be(e,t,n){return Gn(e,t,n)}function Gn(e,t,n=ee){const{immediate:r,deep:s,flush:i,once:o}=n,l=fe({},n);let c;if(rn)if(i==="sync"){const g=Fc();c=g.__watcherHandles||(g.__watcherHandles=[])}else if(!t||r)l.once=!0;else return{stop:Ue,resume:Ue,pause:Ue};const f=ue;l.call=(g,_,b)=>Fe(g,f,_,b);let a=!1;i==="post"?l.scheduler=g=>{Ee(g,f&&f.suspense)}:i!=="sync"&&(a=!0,l.scheduler=(g,_)=>{_?g():Wn(g)}),l.augmentJob=g=>{t&&(g.flags|=4),a&&(g.flags|=2,f&&(g.id=f.uid,g.i=f))};const h=kl(e,t,l);return c&&c.push(h),h}function Hc(e,t,n){const r=this.proxy,s=se(e)?e.includes(".")?go(r,e):()=>r[e]:e.bind(r,r);let i;q(t)?i=t:(i=t.handler,n=t);const o=nn(this),l=Gn(s,i.bind(r),n);return o(),l}function go(e,t){const n=t.split(".");return()=>{let r=e;for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ne(t)}Modifiers`]||e[`${st(t)}Modifiers`];function Dc(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||ee;let s=n;const i=t.startsWith("update:"),o=i&&$c(r,t.slice(7));o&&(o.trim&&(s=n.map(a=>se(a)?a.trim():a)),o.number&&(s=n.map(Sr)));let l,c=r[l=bn(t)]||r[l=bn(Ne(t))];!c&&i&&(c=r[l=bn(st(t))]),c&&Fe(c,e,6,s);const f=r[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Fe(f,e,6,s)}}function mo(e,t,n=!1){const r=t.emitsCache,s=r.get(e);if(s!==void 0)return s;const i=e.emits;let o={},l=!1;if(!q(e)){const c=f=>{const a=mo(f,t,!0);a&&(l=!0,fe(o,a))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(ne(e)&&r.set(e,null),null):(K(i)?i.forEach(c=>o[c]=null):fe(o,i),ne(e)&&r.set(e,o),o)}function Yn(e,t){return!e||!Qt(t)?!1:(t=t.slice(2).replace(/Once$/,""),J(e,t[0].toLowerCase()+t.slice(1))||J(e,st(t))||J(e,t))}function cr(e){const{type:t,vnode:n,proxy:r,withProxy:s,propsOptions:[i],slots:o,attrs:l,emit:c,render:f,renderCache:a,props:h,data:g,setupState:_,ctx:b,inheritAttrs:S}=e,V=Mn(e);let N,U;try{if(n.shapeFlag&4){const m=s||r,M=m;N=Me(f.call(M,m,a,h,_,g,b)),U=l}else{const m=t;N=Me(m.length>1?m(h,{attrs:l,slots:o,emit:c}):m(h,null)),U=t.props?l:jc(l)}}catch(m){Bt.length=0,en(m,e,1),N=le(ye)}let p=N;if(U&&S!==!1){const m=Object.keys(U),{shapeFlag:M}=p;m.length&&M&7&&(i&&m.some(Dr)&&(U=Vc(U,i)),p=nt(p,U,!1,!0))}return n.dirs&&(p=nt(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(n.dirs):n.dirs),n.transition&&Yt(p,n.transition),N=p,Mn(V),N}const jc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Qt(n))&&((t||(t={}))[n]=e[n]);return t},Vc=(e,t)=>{const n={};for(const r in e)(!Dr(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Uc(e,t,n){const{props:r,children:s,component:i}=e,{props:o,children:l,patchFlag:c}=t,f=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?Ns(r,o,f):!!o;if(c&8){const a=t.dynamicProps;for(let h=0;he.__isSuspense;function vo(e,t){t&&t.pendingBranch?K(e)?t.effects.push(...e):t.effects.push(e):ql(e)}const Se=Symbol.for("v-fgt"),mt=Symbol.for("v-txt"),ye=Symbol.for("v-cmt"),Ut=Symbol.for("v-stc"),Bt=[];let Ae=null;function Ir(e=!1){Bt.push(Ae=e?null:[])}function kc(){Bt.pop(),Ae=Bt[Bt.length-1]||null}let Xt=1;function Fs(e){Xt+=e,e<0&&Ae&&(Ae.hasOnce=!0)}function _o(e){return e.dynamicChildren=Xt>0?Ae||Ct:null,kc(),Xt>0&&Ae&&Ae.push(e),e}function Vf(e,t,n,r,s,i){return _o(wo(e,t,n,r,s,i,!0))}function Lr(e,t,n,r,s){return _o(le(e,t,n,r,s,!0))}function Ln(e){return e?e.__v_isVNode===!0:!1}function dt(e,t){return e.type===t.type&&e.key===t.key}const bo=({key:e})=>e??null,xn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?se(e)||ae(e)||q(e)?{i:de,r:e,k:t,f:!!n}:e:null);function wo(e,t=null,n=null,r=0,s=null,i=e===Se?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&bo(t),ref:t&&xn(t),scopeId:Vi,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:r,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:de};return l?(os(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=se(n)?8:16),Xt>0&&!o&&Ae&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Ae.push(c),c}const le=Wc;function Wc(e,t=null,n=null,r=0,s=null,i=!1){if((!e||e===Ji)&&(e=ye),Ln(e)){const l=nt(e,t,!0);return n&&os(l,n),Xt>0&&!i&&Ae&&(l.shapeFlag&6?Ae[Ae.indexOf(e)]=l:Ae.push(l)),l.patchFlag=-2,l}if(ea(e)&&(e=e.__vccOpts),t){t=Kc(t);let{class:l,style:c}=t;l&&!se(l)&&(t.class=Br(l)),ne(c)&&(Xr(c)&&!K(c)&&(c=fe({},c)),t.style=Ur(c))}const o=se(e)?1:yo(e)?128:Bi(e)?64:ne(e)?4:q(e)?2:0;return wo(e,t,n,r,s,o,i,!0)}function Kc(e){return e?Xr(e)||so(e)?fe({},e):e:null}function nt(e,t,n=!1,r=!1){const{props:s,ref:i,patchFlag:o,children:l,transition:c}=e,f=t?qc(s||{},t):s,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&bo(f),ref:t&&t.ref?n&&i?K(i)?i.concat(xn(t)):[i,xn(t)]:xn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Se?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&nt(e.ssContent),ssFallback:e.ssFallback&&nt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&r&&Yt(a,c.clone(a)),a}function So(e=" ",t=0){return le(mt,null,e,t)}function Uf(e,t){const n=le(Ut,null,e);return n.staticCount=t,n}function Bf(e="",t=!1){return t?(Ir(),Lr(ye,null,e)):le(ye,null,e)}function Me(e){return e==null||typeof e=="boolean"?le(ye):K(e)?le(Se,null,e.slice()):typeof e=="object"?et(e):le(mt,null,String(e))}function et(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:nt(e)}function os(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(K(t))n=16;else if(typeof t=="object")if(r&65){const s=t.default;s&&(s._c&&(s._d=!1),os(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!so(t)?t._ctx=de:s===3&&de&&(de.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else q(t)?(t={default:t,_ctx:de},n=32):(t=String(t),r&64?(n=16,t=[So(t)]):n=8);e.children=t,e.shapeFlag|=n}function qc(...e){const t={};for(let n=0;nue||de;let Nn,Nr;{const e=mi(),t=(n,r)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(r),i=>{s.length>1?s.forEach(o=>o(i)):s[0](i)}};Nn=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Nr=t("__VUE_SSR_SETTERS__",n=>rn=n)}const nn=e=>{const t=ue;return Nn(e),e.scope.on(),()=>{e.scope.off(),Nn(t)}},Hs=()=>{ue&&ue.scope.off(),Nn(null)};function Eo(e){return e.vnode.shapeFlag&4}let rn=!1;function zc(e,t=!1,n=!1){t&&Nr(t);const{props:r,children:s}=e.vnode,i=Eo(e);Cc(e,r,i,t),Oc(e,s,n);const o=i?Jc(e,t):void 0;return t&&Nr(!1),o}function Jc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,gc);const{setup:r}=n;if(r){const s=e.setupContext=r.length>1?Co(e):null,i=nn(e);it();const o=Zt(r,e,0,[e.props,s]);if(ot(),i(),di(o)){if(gt(e)||es(e),o.then(Hs,Hs),t)return o.then(l=>{$s(e,l,t)}).catch(l=>{en(l,e,0)});e.asyncDep=o}else $s(e,o,t)}else xo(e,t)}function $s(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ne(t)&&(e.setupState=Hi(t)),xo(e,n)}let Ds;function xo(e,t,n){const r=e.type;if(!e.render){if(!t&&Ds&&!r.render){const s=r.template||ns(e).template;if(s){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:c}=r,f=fe(fe({isCustomElement:i,delimiters:l},o),c);r.render=Ds(s,f)}}e.render=r.render||Ue}{const s=nn(e);it();try{yc(e)}finally{ot(),s()}}}const Qc={get(e,t){return ve(e,"get",""),e[t]}};function Co(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Qc),slots:e.slots,emit:e.emit,expose:t}}function zn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Hi(Sn(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Vt)return Vt[n](e)},has(t,n){return n in t||n in Vt}})):e.proxy}function Zc(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function ea(e){return q(e)&&"__vccOpts"in e}const ie=(e,t)=>Ul(e,t,rn);function Fr(e,t,n){const r=arguments.length;return r===2?ne(t)&&!K(t)?Ln(t)?le(e,null,[t]):le(e,t):le(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ln(n)&&(n=[n]),le(e,t,n))}const ta="3.5.4";/** +* @vue/runtime-dom v3.5.4 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Hr;const js=typeof window<"u"&&window.trustedTypes;if(js)try{Hr=js.createPolicy("vue",{createHTML:e=>e})}catch{}const To=Hr?e=>Hr.createHTML(e):e=>e,na="http://www.w3.org/2000/svg",ra="http://www.w3.org/1998/Math/MathML",Ke=typeof document<"u"?document:null,Vs=Ke&&Ke.createElement("template"),sa={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t==="svg"?Ke.createElementNS(na,e):t==="mathml"?Ke.createElementNS(ra,e):n?Ke.createElement(e,{is:n}):Ke.createElement(e);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>Ke.createTextNode(e),createComment:e=>Ke.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ke.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,i){const o=n?n.previousSibling:t.lastChild;if(s&&(s===i||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===i||!(s=s.nextSibling)););else{Vs.innerHTML=To(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const l=Vs.content;if(r==="svg"||r==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ze="transition",Ht="animation",zt=Symbol("_vtc"),Ao={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},ia=fe({},Wi,Ao),oa=e=>(e.displayName="Transition",e.props=ia,e),kf=oa((e,{slots:t})=>Fr(Zl,la(e),t)),at=(e,t=[])=>{K(e)?e.forEach(n=>n(...t)):e&&e(...t)},Us=e=>e?K(e)?e.some(t=>t.length>1):e.length>1:!1;function la(e){const t={};for(const x in e)x in Ao||(t[x]=e[x]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:f=o,appearToClass:a=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:_=`${n}-leave-to`}=e,b=ca(s),S=b&&b[0],V=b&&b[1],{onBeforeEnter:N,onEnter:U,onEnterCancelled:p,onLeave:m,onLeaveCancelled:M,onBeforeAppear:F=N,onAppear:$=U,onAppearCancelled:D=p}=t,R=(x,W,re)=>{ft(x,W?a:l),ft(x,W?f:o),re&&re()},v=(x,W)=>{x._isLeaving=!1,ft(x,h),ft(x,_),ft(x,g),W&&W()},L=x=>(W,re)=>{const ce=x?$:U,j=()=>R(W,x,re);at(ce,[W,j]),Bs(()=>{ft(W,x?c:i),Je(W,x?a:l),Us(ce)||ks(W,r,S,j)})};return fe(t,{onBeforeEnter(x){at(N,[x]),Je(x,i),Je(x,o)},onBeforeAppear(x){at(F,[x]),Je(x,c),Je(x,f)},onEnter:L(!1),onAppear:L(!0),onLeave(x,W){x._isLeaving=!0;const re=()=>v(x,W);Je(x,h),Je(x,g),ua(),Bs(()=>{x._isLeaving&&(ft(x,h),Je(x,_),Us(m)||ks(x,r,V,re))}),at(m,[x,re])},onEnterCancelled(x){R(x,!1),at(p,[x])},onAppearCancelled(x){R(x,!0),at(D,[x])},onLeaveCancelled(x){v(x),at(M,[x])}})}function ca(e){if(e==null)return null;if(ne(e))return[ar(e.enter),ar(e.leave)];{const t=ar(e);return[t,t]}}function ar(e){return el(e)}function Je(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[zt]||(e[zt]=new Set)).add(t)}function ft(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[zt];n&&(n.delete(t),n.size||(e[zt]=void 0))}function Bs(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let aa=0;function ks(e,t,n,r){const s=e._endId=++aa,i=()=>{s===e._endId&&r()};if(n)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=fa(e,t);if(!o)return r();const f=o+"end";let a=0;const h=()=>{e.removeEventListener(f,g),i()},g=_=>{_.target===e&&++a>=c&&h()};setTimeout(()=>{a(n[b]||"").split(", "),s=r(`${ze}Delay`),i=r(`${ze}Duration`),o=Ws(s,i),l=r(`${Ht}Delay`),c=r(`${Ht}Duration`),f=Ws(l,c);let a=null,h=0,g=0;t===ze?o>0&&(a=ze,h=o,g=i.length):t===Ht?f>0&&(a=Ht,h=f,g=c.length):(h=Math.max(o,f),a=h>0?o>f?ze:Ht:null,g=a?a===ze?i.length:c.length:0);const _=a===ze&&/\b(transform|all)(,|$)/.test(r(`${ze}Property`).toString());return{type:a,timeout:h,propCount:g,hasTransform:_}}function Ws(e,t){for(;e.lengthKs(n)+Ks(e[r])))}function Ks(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ua(){return document.body.offsetHeight}function da(e,t,n){const r=e[zt];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const qs=Symbol("_vod"),ha=Symbol("_vsh"),pa=Symbol(""),ga=/(^|;)\s*display\s*:/;function ma(e,t,n){const r=e.style,s=se(n);let i=!1;if(n&&!s){if(t)if(se(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&Cn(r,l,"")}else for(const o in t)n[o]==null&&Cn(r,o,"");for(const o in n)o==="display"&&(i=!0),Cn(r,o,n[o])}else if(s){if(t!==n){const o=r[pa];o&&(n+=";"+o),r.cssText=n,i=ga.test(n)}}else t&&e.removeAttribute("style");qs in e&&(e[qs]=i?r.display:"",e[ha]&&(r.display="none"))}const Gs=/\s*!important$/;function Cn(e,t,n){if(K(n))n.forEach(r=>Cn(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=ya(e,t);Gs.test(n)?e.setProperty(st(r),n.replace(Gs,""),"important"):e[r]=n}}const Ys=["Webkit","Moz","ms"],fr={};function ya(e,t){const n=fr[t];if(n)return n;let r=Ne(t);if(r!=="filter"&&r in e)return fr[t]=r;r=$n(r);for(let s=0;sur||(Sa.then(()=>ur=0),ur=Date.now());function xa(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;Fe(Ca(r,n.value),t,5,[r])};return n.value=e,n.attached=Ea(),n}function Ca(e,t){if(K(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const Zs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ta=(e,t,n,r,s,i)=>{const o=s==="svg";t==="class"?da(e,r,o):t==="style"?ma(e,n,r):Qt(t)?Dr(t)||ba(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Aa(e,t,r,o))?(va(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&zs(e,t,r,o,i,t!=="value")):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),zs(e,t,r,o))};function Aa(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Zs(t)&&q(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return Zs(t)&&se(n)?!1:!!(t in e||e._isVueCE&&(/[A-Z]/.test(t)||!se(n)))}const ei=e=>{const t=e.props["onUpdate:modelValue"]||!1;return K(t)?n=>wn(t,n):t};function Ra(e){e.target.composing=!0}function ti(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const dr=Symbol("_assign"),Wf={created(e,{modifiers:{lazy:t,trim:n,number:r}},s){e[dr]=ei(s);const i=r||s.props&&s.props.type==="number";Et(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=Sr(l)),e[dr](l)}),n&&Et(e,"change",()=>{e.value=e.value.trim()}),t||(Et(e,"compositionstart",Ra),Et(e,"compositionend",ti),Et(e,"change",ti))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:s,number:i}},o){if(e[dr]=ei(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?Sr(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(r&&t===n||s&&e.value.trim()===c)||(e.value=c))}},Oa=["ctrl","shift","alt","meta"],Ma={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Oa.some(n=>e[`${n}Key`]&&!t.includes(n))},Kf=(e,t)=>{const n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=(s,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=s=>{if(!("key"in s))return;const i=st(s.key);if(t.some(o=>o===i||Pa[o]===i))return e(s)})},Ro=fe({patchProp:Ta},sa);let kt,ni=!1;function Ia(){return kt||(kt=Pc(Ro))}function La(){return kt=ni?kt:Ic(Ro),ni=!0,kt}const Gf=(...e)=>{const t=Ia().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Mo(r);if(!s)return;const i=t._component;!q(i)&&!i.render&&!i.template&&(i.template=s.innerHTML),s.nodeType===1&&(s.textContent="");const o=n(s,!1,Oo(s));return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),o},t},Yf=(...e)=>{const t=La().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Mo(r);if(s)return n(s,!0,Oo(s))},t};function Oo(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Mo(e){return se(e)?document.querySelector(e):e}const Xf=(e,t)=>{const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n},Na=window.__VP_SITE_DATA__;function ls(e){return bi()?(al(e),!0):!1}function ke(e){return typeof e=="function"?e():Fi(e)}const Po=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const zf=e=>e!=null,Fa=Object.prototype.toString,Ha=e=>Fa.call(e)==="[object Object]",Jt=()=>{},ri=$a();function $a(){var e,t;return Po&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Da(e,t){function n(...r){return new Promise((s,i)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(s).catch(i)})}return n}const Io=e=>e();function ja(e,t={}){let n,r,s=Jt;const i=l=>{clearTimeout(l),s(),s=Jt};return l=>{const c=ke(e),f=ke(t.maxWait);return n&&i(n),c<=0||f!==void 0&&f<=0?(r&&(i(r),r=null),Promise.resolve(l())):new Promise((a,h)=>{s=t.rejectOnCancel?h:a,f&&!r&&(r=setTimeout(()=>{n&&i(n),r=null,a(l())},f)),n=setTimeout(()=>{r&&i(r),r=null,a(l())},c)})}}function Va(e=Io){const t=oe(!0);function n(){t.value=!1}function r(){t.value=!0}const s=(...i)=>{t.value&&e(...i)};return{isActive:Bn(t),pause:n,resume:r,eventFilter:s}}function Ua(e){return Xn()}function Lo(...e){if(e.length!==1)return Dl(...e);const t=e[0];return typeof t=="function"?Bn(Fl(()=>({get:t,set:Jt}))):oe(t)}function No(e,t,n={}){const{eventFilter:r=Io,...s}=n;return Be(e,Da(r,t),s)}function Ba(e,t,n={}){const{eventFilter:r,...s}=n,{eventFilter:i,pause:o,resume:l,isActive:c}=Va(r);return{stop:No(e,t,{...s,eventFilter:i}),pause:o,resume:l,isActive:c}}function cs(e,t=!0,n){Ua()?It(e,n):t?e():kn(e)}function Jf(e,t,n={}){const{debounce:r=0,maxWait:s=void 0,...i}=n;return No(e,t,{...i,eventFilter:ja(r,{maxWait:s})})}function Qf(e,t,n){let r;ae(n)?r={evaluating:n}:r={};const{lazy:s=!1,evaluating:i=void 0,shallow:o=!0,onError:l=Jt}=r,c=oe(!s),f=o?Jr(t):oe(t);let a=0;return is(async h=>{if(!c.value)return;a++;const g=a;let _=!1;i&&Promise.resolve().then(()=>{i.value=!0});try{const b=await e(S=>{h(()=>{i&&(i.value=!1),_||S()})});g===a&&(f.value=b)}catch(b){l(b)}finally{i&&g===a&&(i.value=!1),_=!0}}),s?ie(()=>(c.value=!0,f.value)):f}function Fo(e){var t;const n=ke(e);return(t=n==null?void 0:n.$el)!=null?t:n}const He=Po?window:void 0;function Pt(...e){let t,n,r,s;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,s]=e,t=He):[t,n,r,s]=e,!t)return Jt;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const i=[],o=()=>{i.forEach(a=>a()),i.length=0},l=(a,h,g,_)=>(a.addEventListener(h,g,_),()=>a.removeEventListener(h,g,_)),c=Be(()=>[Fo(t),ke(s)],([a,h])=>{if(o(),!a)return;const g=Ha(h)?{...h}:h;i.push(...n.flatMap(_=>r.map(b=>l(a,_,b,g))))},{immediate:!0,flush:"post"}),f=()=>{c(),o()};return ls(f),f}function ka(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function Zf(...e){let t,n,r={};e.length===3?(t=e[0],n=e[1],r=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],r=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:s=He,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=r,c=ka(t);return Pt(s,i,a=>{a.repeat&&ke(l)||c(a)&&n(a)},o)}function Wa(){const e=oe(!1),t=Xn();return t&&It(()=>{e.value=!0},t),e}function Ka(e){const t=Wa();return ie(()=>(t.value,!!e()))}function Ho(e,t={}){const{window:n=He}=t,r=Ka(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const i=oe(!1),o=f=>{i.value=f.matches},l=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",o):s.removeListener(o))},c=is(()=>{r.value&&(l(),s=n.matchMedia(ke(e)),"addEventListener"in s?s.addEventListener("change",o):s.addListener(o),i.value=s.matches)});return ls(()=>{c(),l(),s=void 0}),i}const yn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},vn="__vueuse_ssr_handlers__",qa=Ga();function Ga(){return vn in yn||(yn[vn]=yn[vn]||{}),yn[vn]}function $o(e,t){return qa[e]||t}function Ya(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Xa={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},si="vueuse-storage";function as(e,t,n,r={}){var s;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:f=!1,shallow:a,window:h=He,eventFilter:g,onError:_=v=>{console.error(v)},initOnMounted:b}=r,S=(a?Jr:oe)(typeof t=="function"?t():t);if(!n)try{n=$o("getDefaultStorage",()=>{var v;return(v=He)==null?void 0:v.localStorage})()}catch(v){_(v)}if(!n)return S;const V=ke(t),N=Ya(V),U=(s=r.serializer)!=null?s:Xa[N],{pause:p,resume:m}=Ba(S,()=>F(S.value),{flush:i,deep:o,eventFilter:g});h&&l&&cs(()=>{n instanceof Storage?Pt(h,"storage",D):Pt(h,si,R),b&&D()}),b||D();function M(v,L){if(h){const x={key:e,oldValue:v,newValue:L,storageArea:n};h.dispatchEvent(n instanceof Storage?new StorageEvent("storage",x):new CustomEvent(si,{detail:x}))}}function F(v){try{const L=n.getItem(e);if(v==null)M(L,null),n.removeItem(e);else{const x=U.write(v);L!==x&&(n.setItem(e,x),M(L,x))}}catch(L){_(L)}}function $(v){const L=v?v.newValue:n.getItem(e);if(L==null)return c&&V!=null&&n.setItem(e,U.write(V)),V;if(!v&&f){const x=U.read(L);return typeof f=="function"?f(x,V):N==="object"&&!Array.isArray(x)?{...V,...x}:x}else return typeof L!="string"?L:U.read(L)}function D(v){if(!(v&&v.storageArea!==n)){if(v&&v.key==null){S.value=V;return}if(!(v&&v.key!==e)){p();try{(v==null?void 0:v.newValue)!==U.write(S.value)&&(S.value=$(v))}catch(L){_(L)}finally{v?kn(m):m()}}}}function R(v){D(v.detail)}return S}function Do(e){return Ho("(prefers-color-scheme: dark)",e)}const za="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Ja(e={}){const{selector:t="html",attribute:n="class",initialValue:r="auto",window:s=He,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:f,disableTransition:a=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},g=Do({window:s}),_=ie(()=>g.value?"dark":"light"),b=c||(o==null?Lo(r):as(o,r,i,{window:s,listenToStorageChanges:l})),S=ie(()=>b.value==="auto"?_.value:b.value),V=$o("updateHTMLAttrs",(m,M,F)=>{const $=typeof m=="string"?s==null?void 0:s.document.querySelector(m):Fo(m);if(!$)return;const D=new Set,R=new Set;let v=null;if(M==="class"){const x=F.split(/\s/g);Object.values(h).flatMap(W=>(W||"").split(/\s/g)).filter(Boolean).forEach(W=>{x.includes(W)?D.add(W):R.add(W)})}else v={key:M,value:F};if(D.size===0&&R.size===0&&v===null)return;let L;a&&(L=s.document.createElement("style"),L.appendChild(document.createTextNode(za)),s.document.head.appendChild(L));for(const x of D)$.classList.add(x);for(const x of R)$.classList.remove(x);v&&$.setAttribute(v.key,v.value),a&&(s.getComputedStyle(L).opacity,document.head.removeChild(L))});function N(m){var M;V(t,n,(M=h[m])!=null?M:m)}function U(m){e.onChanged?e.onChanged(m,N):N(m)}Be(S,U,{flush:"post",immediate:!0}),cs(()=>U(S.value));const p=ie({get(){return f?b.value:S.value},set(m){b.value=m}});try{return Object.assign(p,{store:b,system:_,state:S})}catch{return p}}function Qa(e={}){const{valueDark:t="dark",valueLight:n="",window:r=He}=e,s=Ja({...e,onChanged:(l,c)=>{var f;e.onChanged?(f=e.onChanged)==null||f.call(e,l==="dark",c,l):c(l)},modes:{dark:t,light:n}}),i=ie(()=>s.system?s.system.value:Do({window:r}).value?"dark":"light");return ie({get(){return s.value==="dark"},set(l){const c=l?"dark":"light";i.value===c?s.value="auto":s.value=c}})}function hr(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function eu(e,t,n={}){const{window:r=He}=n;return as(e,t,r==null?void 0:r.localStorage,n)}function jo(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const pr=new WeakMap;function tu(e,t=!1){const n=oe(t);let r=null,s="";Be(Lo(e),l=>{const c=hr(ke(l));if(c){const f=c;if(pr.get(f)||pr.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(s=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const i=()=>{const l=hr(ke(e));!l||n.value||(ri&&(r=Pt(l,"touchmove",c=>{Za(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=hr(ke(e));!l||!n.value||(ri&&(r==null||r()),l.style.overflow=s,pr.delete(l),n.value=!1)};return ls(o),ie({get(){return n.value},set(l){l?i():o()}})}function nu(e,t,n={}){const{window:r=He}=n;return as(e,t,r==null?void 0:r.sessionStorage,n)}function ru(e={}){const{window:t=He,behavior:n="auto"}=e;if(!t)return{x:oe(0),y:oe(0)};const r=oe(t.scrollX),s=oe(t.scrollY),i=ie({get(){return r.value},set(l){scrollTo({left:l,behavior:n})}}),o=ie({get(){return s.value},set(l){scrollTo({top:l,behavior:n})}});return Pt(t,"scroll",()=>{r.value=t.scrollX,s.value=t.scrollY},{capture:!1,passive:!0}),{x:i,y:o}}function su(e={}){const{window:t=He,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:s=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=oe(n),c=oe(r),f=()=>{t&&(o==="outer"?(l.value=t.outerWidth,c.value=t.outerHeight):i?(l.value=t.innerWidth,c.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,c.value=t.document.documentElement.clientHeight))};if(f(),cs(f),Pt("resize",f,{passive:!0}),s){const a=Ho("(orientation: portrait)");Be(a,()=>f())}return{width:l,height:c}}const gr={BASE_URL:"/YAXArrays.jl/previews/PR437/",DEV:!1,MODE:"production",PROD:!0,SSR:!1};var mr={};const Vo=/^(?:[a-z]+:|\/\/)/i,ef="vitepress-theme-appearance",tf=/#.*$/,nf=/[?#].*$/,rf=/(?:(^|\/)index)?\.(?:md|html)$/,ge=typeof document<"u",Uo={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function sf(e,t,n=!1){if(t===void 0)return!1;if(e=ii(`/${e}`),n)return new RegExp(t).test(e);if(ii(t)!==e)return!1;const r=t.match(tf);return r?(ge?location.hash:"")===r[0]:!0}function ii(e){return decodeURI(e).replace(nf,"").replace(rf,"$1")}function of(e){return Vo.test(e)}function lf(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!of(n)&&sf(t,`/${n}/`,!0))||"root"}function cf(e,t){var r,s,i,o,l,c,f;const n=lf(e,t);return Object.assign({},e,{localeIndex:n,lang:((r=e.locales[n])==null?void 0:r.lang)??e.lang,dir:((s=e.locales[n])==null?void 0:s.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:ko(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function Bo(e,t){const n=t.title||e.title,r=t.titleTemplate??e.titleTemplate;if(typeof r=="string"&&r.includes(":title"))return r.replace(/:title/g,n);const s=af(e.title,r);return n===s.slice(3)?n:`${n}${s}`}function af(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function ff(e,t){const[n,r]=t;if(n!=="meta")return!1;const s=Object.entries(r)[0];return s==null?!1:e.some(([i,o])=>i===n&&o[s[0]]===s[1])}function ko(e,t){return[...e.filter(n=>!ff(t,n)),...t]}const uf=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,df=/^[a-z]:/i;function oi(e){const t=df.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(uf,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const yr=new Set;function hf(e){if(yr.size===0){const n=typeof process=="object"&&(mr==null?void 0:mr.VITE_EXTRA_EXTENSIONS)||(gr==null?void 0:gr.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(r=>yr.add(r))}const t=e.split(".").pop();return t==null||!yr.has(t.toLowerCase())}function iu(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const pf=Symbol(),yt=Jr(Na);function ou(e){const t=ie(()=>cf(yt.value,e.data.relativePath)),n=t.value.appearance,r=n==="force-dark"?oe(!0):n?Qa({storageKey:ef,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):oe(!1),s=oe(ge?location.hash:"");return ge&&window.addEventListener("hashchange",()=>{s.value=location.hash}),Be(()=>e.data,()=>{s.value=ge?location.hash:""}),{site:t,theme:ie(()=>t.value.themeConfig),page:ie(()=>e.data),frontmatter:ie(()=>e.data.frontmatter),params:ie(()=>e.data.params),lang:ie(()=>t.value.lang),dir:ie(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:ie(()=>t.value.localeIndex||"root"),title:ie(()=>Bo(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:r,hash:ie(()=>s.value)}}function gf(){const e=Mt(pf);if(!e)throw new Error("vitepress data not properly injected in app");return e}function mf(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function li(e){return Vo.test(e)||!e.startsWith("/")?e:mf(yt.value.base,e)}function yf(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ge){const n="/YAXArrays.jl/previews/PR437/";t=oi(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let r=__VP_HASH_MAP__[t.toLowerCase()];if(r||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",r=__VP_HASH_MAP__[t.toLowerCase()]),!r)return null;t=`${n}assets/${t}.${r}.js`}else t=`./${oi(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let Tn=[];function lu(e){Tn.push(e),qn(()=>{Tn=Tn.filter(t=>t!==e)})}function vf(){let e=yt.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=ci(e,n);else if(Array.isArray(e))for(const r of e){const s=ci(r,n);if(s){t=s;break}}return t}function ci(e,t){const n=document.querySelector(e);if(!n)return 0;const r=n.getBoundingClientRect().bottom;return r<0?0:r+t}const _f=Symbol(),Wo="http://a.com",bf=()=>({path:"/",component:null,data:Uo});function cu(e,t){const n=Un(bf()),r={route:n,go:s};async function s(l=ge?location.href:"/"){var c,f;l=vr(l),await((c=r.onBeforeRouteChange)==null?void 0:c.call(r,l))!==!1&&(ge&&l!==vr(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((f=r.onAfterRouteChanged)==null?void 0:f.call(r,l)))}let i=null;async function o(l,c=0,f=!1){var g;if(await((g=r.onBeforePageLoad)==null?void 0:g.call(r,l))===!1)return;const a=new URL(l,Wo),h=i=a.pathname;try{let _=await e(h);if(!_)throw new Error(`Page not found: ${h}`);if(i===h){i=null;const{default:b,__pageData:S}=_;if(!b)throw new Error(`Invalid route component: ${b}`);n.path=ge?h:li(h),n.component=Sn(b),n.data=Sn(S),ge&&kn(()=>{let V=yt.value.base+S.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!yt.value.cleanUrls&&!V.endsWith("/")&&(V+=".html"),V!==a.pathname&&(a.pathname=V,l=V+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let N=null;try{N=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(U){console.warn(U)}if(N){ai(N,a.hash);return}}window.scrollTo(0,c)})}}catch(_){if(!/fetch|Page not found/.test(_.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(_),!f)try{const b=await fetch(yt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await b.json(),await o(l,c,!0);return}catch{}if(i===h){i=null,n.path=ge?h:li(h),n.component=t?Sn(t):null;const b=ge?h.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={...Uo,relativePath:b}}}}return ge&&(history.state===null&&history.replaceState({},""),window.addEventListener("click",l=>{if(l.defaultPrevented||!(l.target instanceof Element)||l.target.closest("button")||l.button!==0||l.ctrlKey||l.shiftKey||l.altKey||l.metaKey)return;const c=l.target.closest("a");if(!c||c.closest(".vp-raw")||c.hasAttribute("download")||c.hasAttribute("target"))return;const f=c.getAttribute("href")??(c instanceof SVGAElement?c.getAttribute("xlink:href"):null);if(f==null)return;const{href:a,origin:h,pathname:g,hash:_,search:b}=new URL(f,c.baseURI),S=new URL(location.href);h===S.origin&&hf(g)&&(l.preventDefault(),g===S.pathname&&b===S.search?(_!==S.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:S.href,newURL:a}))),_?ai(c,_,c.classList.contains("header-anchor")):window.scrollTo(0,0)):s(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var c;l.state!==null&&(await o(vr(location.href),l.state&&l.state.scrollPosition||0),(c=r.onAfterRouteChanged)==null||c.call(r,location.href))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),r}function wf(){const e=Mt(_f);if(!e)throw new Error("useRouter() is called without provider.");return e}function Ko(){return wf().route}function ai(e,t,n=!1){let r=null;try{r=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(s){console.warn(s)}if(r){let s=function(){!n||Math.abs(o-window.scrollY)>window.innerHeight?window.scrollTo(0,o):window.scrollTo({left:0,top:o,behavior:"smooth"})};const i=parseInt(window.getComputedStyle(r).paddingTop,10),o=window.scrollY+r.getBoundingClientRect().top-vf()+i;requestAnimationFrame(s)}}function vr(e){const t=new URL(e,Wo);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),yt.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const _r=()=>Tn.forEach(e=>e()),au=Zr({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Ko(),{site:n}=gf();return()=>Fr(e.as,n.value.contentProps??{style:{position:"relative"}},[t.component?Fr(t.component,{onVnodeMounted:_r,onVnodeUpdated:_r,onVnodeUnmounted:_r}):"404 Page Not Found"])}}),Sf="modulepreload",Ef=function(e){return"/YAXArrays.jl/previews/PR437/"+e},fi={},fu=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),o=(i==null?void 0:i.nonce)||(i==null?void 0:i.getAttribute("nonce"));s=Promise.allSettled(n.map(l=>{if(l=Ef(l),l in fi)return;fi[l]=!0;const c=l.endsWith(".css"),f=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${l}"]${f}`))return;const a=document.createElement("link");if(a.rel=c?"stylesheet":Sf,c||(a.as="script"),a.crossOrigin="",a.href=l,o&&a.setAttribute("nonce",o),document.head.appendChild(a),c)return new Promise((h,g)=>{a.addEventListener("load",h),a.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${l}`)))})}))}return s.then(i=>{for(const o of i||[]){if(o.status!=="rejected")continue;const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o.reason,window.dispatchEvent(l),!l.defaultPrevented)throw o.reason}return t()})},uu=Zr({setup(e,{slots:t}){const n=oe(!1);return It(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function du(){ge&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const r=(n=t.parentElement)==null?void 0:n.parentElement;if(!r)return;const s=Array.from(r.querySelectorAll("input")).indexOf(t);if(s<0)return;const i=r.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(f=>f.classList.contains("active"));if(!o)return;const l=i.children[s];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=r==null?void 0:r.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function hu(){if(ge){const e=new WeakMap;window.addEventListener("click",t=>{var r;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const s=n.parentElement,i=(r=n.nextElementSibling)==null?void 0:r.nextElementSibling;if(!s||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(s.className),l=[".vp-copy-ignore",".diff.remove"],c=i.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(a=>a.remove());let f=c.textContent||"";o&&(f=f.replace(/^ *(\$|>) /gm,"").trim()),xf(f).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const a=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,a)})}})}}async function xf(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const r=document.getSelection(),s=r?r.rangeCount>0&&r.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),s&&(r.removeAllRanges(),r.addRange(s)),n&&n.focus()}}function pu(e,t){let n=!0,r=[];const s=i=>{if(n){n=!1,i.forEach(l=>{const c=br(l);for(const f of document.head.children)if(f.isEqualNode(c)){r.push(f);return}});return}const o=i.map(br);r.forEach((l,c)=>{const f=o.findIndex(a=>a==null?void 0:a.isEqualNode(l??null));f!==-1?delete o[f]:(l==null||l.remove(),delete r[c])}),o.forEach(l=>l&&document.head.appendChild(l)),r=[...r,...o].filter(Boolean)};is(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],f=Bo(o,i);f!==document.title&&(document.title=f);const a=l||o.description;let h=document.querySelector("meta[name=description]");h?h.getAttribute("content")!==a&&h.setAttribute("content",a):br(["meta",{name:"description",content:a}]),s(ko(o.head,Tf(c)))})}function br([e,t,n]){const r=document.createElement(e);for(const s in t)r.setAttribute(s,t[s]);return n&&(r.innerHTML=n),e==="script"&&!t.async&&(r.async=!1),r}function Cf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function Tf(e){return e.filter(t=>!Cf(t))}const wr=new Set,qo=()=>document.createElement("link"),Af=e=>{const t=qo();t.rel="prefetch",t.href=e,document.head.appendChild(t)},Rf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let _n;const Of=ge&&(_n=qo())&&_n.relList&&_n.relList.supports&&_n.relList.supports("prefetch")?Af:Rf;function gu(){if(!ge||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const r=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!wr.has(c)){wr.add(c);const f=yf(c);f&&Of(f)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{hostname:o,pathname:l}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||i.target!=="_blank"&&o===location.hostname&&(l!==location.pathname?n.observe(i):wr.add(l))})})};It(r);const s=Ko();Be(()=>s.path,r),qn(()=>{n&&n.disconnect()})}export{zi as $,vf as A,Lf as B,Ff as C,Jr as D,lu as E,Se as F,le as G,Nf as H,Vo as I,Ko as J,qc as K,Mt as L,su as M,Ur as N,Zf as O,kn as P,ru as Q,ge as R,Bn as S,kf as T,If as U,fu as V,tu as W,xc as X,$f as Y,qf as Z,Xf as _,So as a,Kf as a0,Df as a1,Uf as a2,Un as a3,Dl as a4,Fr as a5,pu as a6,_f as a7,ou as a8,pf as a9,au as aa,uu as ab,yt as ac,Yf as ad,cu as ae,yf as af,gu as ag,hu as ah,du as ai,ke as aj,Fo as ak,zf as al,ls as am,Qf as an,nu as ao,eu as ap,Jf as aq,wf as ar,Pt as as,Mf as at,Wf as au,ae as av,Pf as aw,Sn as ax,Gf as ay,iu as az,Lr as b,Vf as c,Zr as d,Bf as e,hf as f,li as g,ie as h,of as i,wo as j,Fi as k,sf as l,Ho as m,Br as n,Ir as o,oe as p,Be as q,Hf as r,is as s,ll as t,gf as u,It as v,Gl as w,qn as x,jf as y,fc as z}; diff --git a/previews/PR437/assets/chunks/theme.C_rChtpL.js b/previews/PR437/assets/chunks/theme.C_rChtpL.js new file mode 100644 index 00000000..0ec94f70 --- /dev/null +++ b/previews/PR437/assets/chunks/theme.C_rChtpL.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/VPLocalSearchBox.DHQW8c6e.js","assets/chunks/framework.BxolPc_T.js"])))=>i.map(i=>d[i]); +import{d as h,o,c as l,r as u,n as T,a as F,t as V,b as $,w as f,e as m,T as pe,_ as k,u as Ue,i as Ge,f as Je,g as ve,h as y,j as d,k as i,l as K,m as ie,p as I,q as W,s as q,v as G,x as fe,y as me,z as Ke,A as je,B as J,F as C,C as w,D as Se,E as x,G as b,H,I as Ve,J as ee,K as U,L as z,M as ze,N as Ie,O as le,P as Ne,Q as Te,R as te,S as Re,U as Ze,V as Ye,W as Ce,X as he,Y as Xe,Z as qe,$ as xe,a0 as et,a1 as Me,a2 as tt,a3 as st,a4 as nt,a5 as ye}from"./framework.BxolPc_T.js";const at=h({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(a){return(e,t)=>(o(),l("span",{class:T(["VPBadge",e.type])},[u(e.$slots,"default",{},()=>[F(V(e.text),1)])],2))}}),ot={key:0,class:"VPBackdrop"},rt=h({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(a){return(e,t)=>(o(),$(pe,{name:"fade"},{default:f(()=>[e.show?(o(),l("div",ot)):m("",!0)]),_:1}))}}),it=k(rt,[["__scopeId","data-v-b06cdb19"]]),S=Ue;function lt(a,e){let t,n=!1;return()=>{t&&clearTimeout(t),n?t=setTimeout(a,e):(a(),(n=!0)&&setTimeout(()=>n=!1,e))}}function ce(a){return/^\//.test(a)?a:`/${a}`}function _e(a){const{pathname:e,search:t,hash:n,protocol:s}=new URL(a,"http://a.com");if(Ge(a)||a.startsWith("#")||!s.startsWith("http")||!Je(e))return a;const{site:r}=S(),c=e.endsWith("/")||e.endsWith(".html")?a:a.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${n}`);return ve(c)}function Z({correspondingLink:a=!1}={}){const{site:e,localeIndex:t,page:n,theme:s,hash:r}=S(),c=y(()=>{var p,_;return{label:(p=e.value.locales[t.value])==null?void 0:p.label,link:((_=e.value.locales[t.value])==null?void 0:_.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:y(()=>Object.entries(e.value.locales).flatMap(([p,_])=>c.value.label===_.label?[]:{text:_.label,link:ct(_.link||(p==="root"?"/":`/${p}/`),s.value.i18nRouting!==!1&&a,n.value.relativePath.slice(c.value.link.length-1),!e.value.cleanUrls)+r.value})),currentLang:c}}function ct(a,e,t,n){return e?a.replace(/\/$/,"")+ce(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,n?".html":"")):a}const ut={class:"NotFound"},dt={class:"code"},pt={class:"title"},vt={class:"quote"},ft={class:"action"},mt=["href","aria-label"],ht=h({__name:"NotFound",setup(a){const{theme:e}=S(),{currentLang:t}=Z();return(n,s)=>{var r,c,v,p,_;return o(),l("div",ut,[d("p",dt,V(((r=i(e).notFound)==null?void 0:r.code)??"404"),1),d("h1",pt,V(((c=i(e).notFound)==null?void 0:c.title)??"PAGE NOT FOUND"),1),s[0]||(s[0]=d("div",{class:"divider"},null,-1)),d("blockquote",vt,V(((v=i(e).notFound)==null?void 0:v.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),d("div",ft,[d("a",{class:"link",href:i(ve)(i(t).link),"aria-label":((p=i(e).notFound)==null?void 0:p.linkLabel)??"go to home"},V(((_=i(e).notFound)==null?void 0:_.linkText)??"Take me home"),9,mt)])])}}}),_t=k(ht,[["__scopeId","data-v-951cab6c"]]);function Be(a,e){if(Array.isArray(a))return Y(a);if(a==null)return[];e=ce(e);const t=Object.keys(a).sort((s,r)=>r.split("/").length-s.split("/").length).find(s=>e.startsWith(ce(s))),n=t?a[t]:[];return Array.isArray(n)?Y(n):Y(n.items,n.base)}function bt(a){const e=[];let t=0;for(const n in a){const s=a[n];if(s.items){t=e.push(s);continue}e[t]||e.push({items:[]}),e[t].items.push(s)}return e}function gt(a){const e=[];function t(n){for(const s of n)s.text&&s.link&&e.push({text:s.text,link:s.link,docFooterText:s.docFooterText}),s.items&&t(s.items)}return t(a),e}function ue(a,e){return Array.isArray(e)?e.some(t=>ue(a,t)):K(a,e.link)?!0:e.items?ue(a,e.items):!1}function Y(a,e){return[...a].map(t=>{const n={...t},s=n.base||e;return s&&n.link&&(n.link=s+n.link),n.items&&(n.items=Y(n.items,s)),n})}function D(){const{frontmatter:a,page:e,theme:t}=S(),n=ie("(min-width: 960px)"),s=I(!1),r=y(()=>{const B=t.value.sidebar,N=e.value.relativePath;return B?Be(B,N):[]}),c=I(r.value);W(r,(B,N)=>{JSON.stringify(B)!==JSON.stringify(N)&&(c.value=r.value)});const v=y(()=>a.value.sidebar!==!1&&c.value.length>0&&a.value.layout!=="home"),p=y(()=>_?a.value.aside==null?t.value.aside==="left":a.value.aside==="left":!1),_=y(()=>a.value.layout==="home"?!1:a.value.aside!=null?!!a.value.aside:t.value.aside!==!1),L=y(()=>v.value&&n.value),g=y(()=>v.value?bt(c.value):[]);function A(){s.value=!0}function P(){s.value=!1}function M(){s.value?P():A()}return{isOpen:s,sidebar:c,sidebarGroups:g,hasSidebar:v,hasAside:_,leftAside:p,isSidebarEnabled:L,open:A,close:P,toggle:M}}function kt(a,e){let t;q(()=>{t=a.value?document.activeElement:void 0}),G(()=>{window.addEventListener("keyup",n)}),fe(()=>{window.removeEventListener("keyup",n)});function n(s){s.key==="Escape"&&a.value&&(e(),t==null||t.focus())}}function $t(a){const{page:e,hash:t}=S(),n=I(!1),s=y(()=>a.value.collapsed!=null),r=y(()=>!!a.value.link),c=I(!1),v=()=>{c.value=K(e.value.relativePath,a.value.link)};W([e,a,t],v),G(v);const p=y(()=>c.value?!0:a.value.items?ue(e.value.relativePath,a.value.items):!1),_=y(()=>!!(a.value.items&&a.value.items.length));q(()=>{n.value=!!(s.value&&a.value.collapsed)}),me(()=>{(c.value||p.value)&&(n.value=!1)});function L(){s.value&&(n.value=!n.value)}return{collapsed:n,collapsible:s,isLink:r,isActiveLink:c,hasActiveLink:p,hasChildren:_,toggle:L}}function yt(){const{hasSidebar:a}=D(),e=ie("(min-width: 960px)"),t=ie("(min-width: 1280px)");return{isAsideEnabled:y(()=>!t.value&&!e.value?!1:a.value?t.value:e.value)}}const de=[];function we(a){return typeof a.outline=="object"&&!Array.isArray(a.outline)&&a.outline.label||a.outlineTitle||"On this page"}function be(a){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const n=Number(t.tagName[1]);return{element:t,title:At(t),link:"#"+t.id,level:n}});return Pt(e,a)}function At(a){let e="";for(const t of a.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function Pt(a,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[n,s]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;a=a.filter(c=>c.level>=n&&c.level<=s),de.length=0;for(const{element:c,link:v}of a)de.push({element:c,link:v});const r=[];e:for(let c=0;c=0;p--){const _=a[p];if(_.level{requestAnimationFrame(r),window.addEventListener("scroll",n)}),Ke(()=>{c(location.hash)}),fe(()=>{window.removeEventListener("scroll",n)});function r(){if(!t.value)return;const v=window.scrollY,p=window.innerHeight,_=document.body.offsetHeight,L=Math.abs(v+p-_)<1,g=de.map(({element:P,link:M})=>({link:M,top:St(P)})).filter(({top:P})=>!Number.isNaN(P)).sort((P,M)=>P.top-M.top);if(!g.length){c(null);return}if(v<1){c(null);return}if(L){c(g[g.length-1].link);return}let A=null;for(const{link:P,top:M}of g){if(M>v+je()+4)break;A=P}c(A)}function c(v){s&&s.classList.remove("active"),v==null?s=null:s=a.value.querySelector(`a[href="${decodeURIComponent(v)}"]`);const p=s;p?(p.classList.add("active"),e.value.style.top=p.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function St(a){let e=0;for(;a!==document.body;){if(a===null)return NaN;e+=a.offsetTop,a=a.offsetParent}return e}const Vt=["href","title"],It=h({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(a){function e({target:t}){const n=t.href.split("#")[1],s=document.getElementById(decodeURIComponent(n));s==null||s.focus({preventScroll:!0})}return(t,n)=>{const s=J("VPDocOutlineItem",!0);return o(),l("ul",{class:T(["VPDocOutlineItem",t.root?"root":"nested"])},[(o(!0),l(C,null,w(t.headers,({children:r,link:c,title:v})=>(o(),l("li",null,[d("a",{class:"outline-link",href:c,onClick:e,title:v},V(v),9,Vt),r!=null&&r.length?(o(),$(s,{key:0,headers:r},null,8,["headers"])):m("",!0)]))),256))],2)}}}),Ee=k(It,[["__scopeId","data-v-3f927ebe"]]),Nt={class:"content"},Tt={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},Ct=h({__name:"VPDocAsideOutline",setup(a){const{frontmatter:e,theme:t}=S(),n=Se([]);x(()=>{n.value=be(e.value.outline??t.value.outline)});const s=I(),r=I();return Lt(s,r),(c,v)=>(o(),l("nav",{"aria-labelledby":"doc-outline-aria-label",class:T(["VPDocAsideOutline",{"has-outline":n.value.length>0}]),ref_key:"container",ref:s},[d("div",Nt,[d("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),d("div",Tt,V(i(we)(i(t))),1),b(Ee,{headers:n.value,root:!0},null,8,["headers"])])],2))}}),Mt=k(Ct,[["__scopeId","data-v-b38bf2ff"]]),Bt={class:"VPDocAsideCarbonAds"},wt=h({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(a){const e=()=>null;return(t,n)=>(o(),l("div",Bt,[b(i(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Et={class:"VPDocAside"},Qt=h({__name:"VPDocAside",setup(a){const{theme:e}=S();return(t,n)=>(o(),l("div",Et,[u(t.$slots,"aside-top",{},void 0,!0),u(t.$slots,"aside-outline-before",{},void 0,!0),b(Mt),u(t.$slots,"aside-outline-after",{},void 0,!0),n[0]||(n[0]=d("div",{class:"spacer"},null,-1)),u(t.$slots,"aside-ads-before",{},void 0,!0),i(e).carbonAds?(o(),$(wt,{key:0,"carbon-ads":i(e).carbonAds},null,8,["carbon-ads"])):m("",!0),u(t.$slots,"aside-ads-after",{},void 0,!0),u(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Ft=k(Qt,[["__scopeId","data-v-6d7b3c46"]]);function Ht(){const{theme:a,page:e}=S();return y(()=>{const{text:t="Edit this page",pattern:n=""}=a.value.editLink||{};let s;return typeof n=="function"?s=n(e.value):s=n.replace(/:path/g,e.value.filePath),{url:s,text:t}})}function Wt(){const{page:a,theme:e,frontmatter:t}=S();return y(()=>{var _,L,g,A,P,M,B,N;const n=Be(e.value.sidebar,a.value.relativePath),s=gt(n),r=Dt(s,E=>E.link.replace(/[?#].*$/,"")),c=r.findIndex(E=>K(a.value.relativePath,E.link)),v=((_=e.value.docFooter)==null?void 0:_.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((L=e.value.docFooter)==null?void 0:L.next)===!1&&!t.value.next||t.value.next===!1;return{prev:v?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((g=r[c-1])==null?void 0:g.docFooterText)??((A=r[c-1])==null?void 0:A.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((P=r[c-1])==null?void 0:P.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((M=r[c+1])==null?void 0:M.docFooterText)??((B=r[c+1])==null?void 0:B.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((N=r[c+1])==null?void 0:N.link)}}})}function Dt(a,e){const t=new Set;return a.filter(n=>{const s=e(n);return t.has(s)?!1:t.add(s)})}const Q=h({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(a){const e=a,t=y(()=>e.tag??(e.href?"a":"span")),n=y(()=>e.href&&Ve.test(e.href)||e.target==="_blank");return(s,r)=>(o(),$(H(t.value),{class:T(["VPLink",{link:s.href,"vp-external-link-icon":n.value,"no-icon":s.noIcon}]),href:s.href?i(_e)(s.href):void 0,target:s.target??(n.value?"_blank":void 0),rel:s.rel??(n.value?"noreferrer":void 0)},{default:f(()=>[u(s.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Ot={class:"VPLastUpdated"},Ut=["datetime"],Gt=h({__name:"VPDocFooterLastUpdated",setup(a){const{theme:e,page:t,lang:n}=S(),s=y(()=>new Date(t.value.lastUpdated)),r=y(()=>s.value.toISOString()),c=I("");return G(()=>{q(()=>{var v,p,_;c.value=new Intl.DateTimeFormat((p=(v=e.value.lastUpdated)==null?void 0:v.formatOptions)!=null&&p.forceLocale?n.value:void 0,((_=e.value.lastUpdated)==null?void 0:_.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(s.value)})}),(v,p)=>{var _;return o(),l("p",Ot,[F(V(((_=i(e).lastUpdated)==null?void 0:_.text)||i(e).lastUpdatedText||"Last updated")+": ",1),d("time",{datetime:r.value},V(c.value),9,Ut)])}}}),Jt=k(Gt,[["__scopeId","data-v-475f71b8"]]),Kt={key:0,class:"VPDocFooter"},jt={key:0,class:"edit-info"},zt={key:0,class:"edit-link"},Rt={key:1,class:"last-updated"},Zt={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},Yt={class:"pager"},Xt=["innerHTML"],qt=["innerHTML"],xt={class:"pager"},es=["innerHTML"],ts=["innerHTML"],ss=h({__name:"VPDocFooter",setup(a){const{theme:e,page:t,frontmatter:n}=S(),s=Ht(),r=Wt(),c=y(()=>e.value.editLink&&n.value.editLink!==!1),v=y(()=>t.value.lastUpdated),p=y(()=>c.value||v.value||r.value.prev||r.value.next);return(_,L)=>{var g,A,P,M;return p.value?(o(),l("footer",Kt,[u(_.$slots,"doc-footer-before",{},void 0,!0),c.value||v.value?(o(),l("div",jt,[c.value?(o(),l("div",zt,[b(Q,{class:"edit-link-button",href:i(s).url,"no-icon":!0},{default:f(()=>[L[0]||(L[0]=d("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),F(" "+V(i(s).text),1)]),_:1},8,["href"])])):m("",!0),v.value?(o(),l("div",Rt,[b(Jt)])):m("",!0)])):m("",!0),(g=i(r).prev)!=null&&g.link||(A=i(r).next)!=null&&A.link?(o(),l("nav",Zt,[L[1]||(L[1]=d("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),d("div",Yt,[(P=i(r).prev)!=null&&P.link?(o(),$(Q,{key:0,class:"pager-link prev",href:i(r).prev.link},{default:f(()=>{var B;return[d("span",{class:"desc",innerHTML:((B=i(e).docFooter)==null?void 0:B.prev)||"Previous page"},null,8,Xt),d("span",{class:"title",innerHTML:i(r).prev.text},null,8,qt)]}),_:1},8,["href"])):m("",!0)]),d("div",xt,[(M=i(r).next)!=null&&M.link?(o(),$(Q,{key:0,class:"pager-link next",href:i(r).next.link},{default:f(()=>{var B;return[d("span",{class:"desc",innerHTML:((B=i(e).docFooter)==null?void 0:B.next)||"Next page"},null,8,es),d("span",{class:"title",innerHTML:i(r).next.text},null,8,ts)]}),_:1},8,["href"])):m("",!0)])])):m("",!0)])):m("",!0)}}}),ns=k(ss,[["__scopeId","data-v-4f9813fa"]]),as={class:"container"},os={class:"aside-container"},rs={class:"aside-content"},is={class:"content"},ls={class:"content-container"},cs={class:"main"},us=h({__name:"VPDoc",setup(a){const{theme:e}=S(),t=ee(),{hasSidebar:n,hasAside:s,leftAside:r}=D(),c=y(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(v,p)=>{const _=J("Content");return o(),l("div",{class:T(["VPDoc",{"has-sidebar":i(n),"has-aside":i(s)}])},[u(v.$slots,"doc-top",{},void 0,!0),d("div",as,[i(s)?(o(),l("div",{key:0,class:T(["aside",{"left-aside":i(r)}])},[p[0]||(p[0]=d("div",{class:"aside-curtain"},null,-1)),d("div",os,[d("div",rs,[b(Ft,null,{"aside-top":f(()=>[u(v.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[u(v.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[u(v.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[u(v.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[u(v.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[u(v.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):m("",!0),d("div",is,[d("div",ls,[u(v.$slots,"doc-before",{},void 0,!0),d("main",cs,[b(_,{class:T(["vp-doc",[c.value,i(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),b(ns,null,{"doc-footer-before":f(()=>[u(v.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),u(v.$slots,"doc-after",{},void 0,!0)])])]),u(v.$slots,"doc-bottom",{},void 0,!0)],2)}}}),ds=k(us,[["__scopeId","data-v-83890dd9"]]),ps=h({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(a){const e=a,t=y(()=>e.href&&Ve.test(e.href)),n=y(()=>e.tag||e.href?"a":"button");return(s,r)=>(o(),$(H(n.value),{class:T(["VPButton",[s.size,s.theme]]),href:s.href?i(_e)(s.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:f(()=>[F(V(s.text),1)]),_:1},8,["class","href","target","rel"]))}}),vs=k(ps,[["__scopeId","data-v-14206e74"]]),fs=["src","alt"],ms=h({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(a){return(e,t)=>{const n=J("VPImage",!0);return e.image?(o(),l(C,{key:0},[typeof e.image=="string"||"src"in e.image?(o(),l("img",U({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:i(ve)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,fs)):(o(),l(C,{key:1},[b(n,U({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),b(n,U({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):m("",!0)}}}),X=k(ms,[["__scopeId","data-v-35a7d0b8"]]),hs={class:"container"},_s={class:"main"},bs={key:0,class:"name"},gs=["innerHTML"],ks=["innerHTML"],$s=["innerHTML"],ys={key:0,class:"actions"},As={key:0,class:"image"},Ps={class:"image-container"},Ls=h({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(a){const e=z("hero-image-slot-exists");return(t,n)=>(o(),l("div",{class:T(["VPHero",{"has-image":t.image||i(e)}])},[d("div",hs,[d("div",_s,[u(t.$slots,"home-hero-info-before",{},void 0,!0),u(t.$slots,"home-hero-info",{},()=>[t.name?(o(),l("h1",bs,[d("span",{innerHTML:t.name,class:"clip"},null,8,gs)])):m("",!0),t.text?(o(),l("p",{key:1,innerHTML:t.text,class:"text"},null,8,ks)):m("",!0),t.tagline?(o(),l("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,$s)):m("",!0)],!0),u(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(o(),l("div",ys,[(o(!0),l(C,null,w(t.actions,s=>(o(),l("div",{key:s.link,class:"action"},[b(vs,{tag:"a",size:"medium",theme:s.theme,text:s.text,href:s.link,target:s.target,rel:s.rel},null,8,["theme","text","href","target","rel"])]))),128))])):m("",!0),u(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||i(e)?(o(),l("div",As,[d("div",Ps,[n[0]||(n[0]=d("div",{class:"image-bg"},null,-1)),u(t.$slots,"home-hero-image",{},()=>[t.image?(o(),$(X,{key:0,class:"image-src",image:t.image},null,8,["image"])):m("",!0)],!0)])])):m("",!0)])],2))}}),Ss=k(Ls,[["__scopeId","data-v-955009fc"]]),Vs=h({__name:"VPHomeHero",setup(a){const{frontmatter:e}=S();return(t,n)=>i(e).hero?(o(),$(Ss,{key:0,class:"VPHomeHero",name:i(e).hero.name,text:i(e).hero.text,tagline:i(e).hero.tagline,image:i(e).hero.image,actions:i(e).hero.actions},{"home-hero-info-before":f(()=>[u(t.$slots,"home-hero-info-before")]),"home-hero-info":f(()=>[u(t.$slots,"home-hero-info")]),"home-hero-info-after":f(()=>[u(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":f(()=>[u(t.$slots,"home-hero-actions-after")]),"home-hero-image":f(()=>[u(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):m("",!0)}}),Is={class:"box"},Ns={key:0,class:"icon"},Ts=["innerHTML"],Cs=["innerHTML"],Ms=["innerHTML"],Bs={key:4,class:"link-text"},ws={class:"link-text-value"},Es=h({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(a){return(e,t)=>(o(),$(Q,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:f(()=>[d("article",Is,[typeof e.icon=="object"&&e.icon.wrap?(o(),l("div",Ns,[b(X,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(o(),$(X,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(o(),l("div",{key:2,class:"icon",innerHTML:e.icon},null,8,Ts)):m("",!0),d("h2",{class:"title",innerHTML:e.title},null,8,Cs),e.details?(o(),l("p",{key:3,class:"details",innerHTML:e.details},null,8,Ms)):m("",!0),e.linkText?(o(),l("div",Bs,[d("p",ws,[F(V(e.linkText)+" ",1),t[0]||(t[0]=d("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):m("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Qs=k(Es,[["__scopeId","data-v-f5e9645b"]]),Fs={key:0,class:"VPFeatures"},Hs={class:"container"},Ws={class:"items"},Ds=h({__name:"VPFeatures",props:{features:{}},setup(a){const e=a,t=y(()=>{const n=e.features.length;if(n){if(n===2)return"grid-2";if(n===3)return"grid-3";if(n%3===0)return"grid-6";if(n>3)return"grid-4"}else return});return(n,s)=>n.features?(o(),l("div",Fs,[d("div",Hs,[d("div",Ws,[(o(!0),l(C,null,w(n.features,r=>(o(),l("div",{key:r.title,class:T(["item",[t.value]])},[b(Qs,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):m("",!0)}}),Os=k(Ds,[["__scopeId","data-v-d0a190d7"]]),Us=h({__name:"VPHomeFeatures",setup(a){const{frontmatter:e}=S();return(t,n)=>i(e).features?(o(),$(Os,{key:0,class:"VPHomeFeatures",features:i(e).features},null,8,["features"])):m("",!0)}}),Gs=h({__name:"VPHomeContent",setup(a){const{width:e}=ze({initialWidth:0,includeScrollbar:!1});return(t,n)=>(o(),l("div",{class:"vp-doc container",style:Ie(i(e)?{"--vp-offset":`calc(50% - ${i(e)/2}px)`}:{})},[u(t.$slots,"default",{},void 0,!0)],4))}}),Js=k(Gs,[["__scopeId","data-v-7a48a447"]]),Ks={class:"VPHome"},js=h({__name:"VPHome",setup(a){const{frontmatter:e}=S();return(t,n)=>{const s=J("Content");return o(),l("div",Ks,[u(t.$slots,"home-hero-before",{},void 0,!0),b(Vs,null,{"home-hero-info-before":f(()=>[u(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[u(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[u(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[u(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[u(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),u(t.$slots,"home-hero-after",{},void 0,!0),u(t.$slots,"home-features-before",{},void 0,!0),b(Us),u(t.$slots,"home-features-after",{},void 0,!0),i(e).markdownStyles!==!1?(o(),$(Js,{key:0},{default:f(()=>[b(s)]),_:1})):(o(),$(s,{key:1}))])}}}),zs=k(js,[["__scopeId","data-v-cbb6ec48"]]),Rs={},Zs={class:"VPPage"};function Ys(a,e){const t=J("Content");return o(),l("div",Zs,[u(a.$slots,"page-top"),b(t),u(a.$slots,"page-bottom")])}const Xs=k(Rs,[["render",Ys]]),qs=h({__name:"VPContent",setup(a){const{page:e,frontmatter:t}=S(),{hasSidebar:n}=D();return(s,r)=>(o(),l("div",{class:T(["VPContent",{"has-sidebar":i(n),"is-home":i(t).layout==="home"}]),id:"VPContent"},[i(e).isNotFound?u(s.$slots,"not-found",{key:0},()=>[b(_t)],!0):i(t).layout==="page"?(o(),$(Xs,{key:1},{"page-top":f(()=>[u(s.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[u(s.$slots,"page-bottom",{},void 0,!0)]),_:3})):i(t).layout==="home"?(o(),$(zs,{key:2},{"home-hero-before":f(()=>[u(s.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[u(s.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[u(s.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[u(s.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[u(s.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[u(s.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[u(s.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[u(s.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[u(s.$slots,"home-features-after",{},void 0,!0)]),_:3})):i(t).layout&&i(t).layout!=="doc"?(o(),$(H(i(t).layout),{key:3})):(o(),$(ds,{key:4},{"doc-top":f(()=>[u(s.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[u(s.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":f(()=>[u(s.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[u(s.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[u(s.$slots,"doc-after",{},void 0,!0)]),"aside-top":f(()=>[u(s.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":f(()=>[u(s.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[u(s.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[u(s.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[u(s.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":f(()=>[u(s.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),xs=k(qs,[["__scopeId","data-v-91765379"]]),en={class:"container"},tn=["innerHTML"],sn=["innerHTML"],nn=h({__name:"VPFooter",setup(a){const{theme:e,frontmatter:t}=S(),{hasSidebar:n}=D();return(s,r)=>i(e).footer&&i(t).footer!==!1?(o(),l("footer",{key:0,class:T(["VPFooter",{"has-sidebar":i(n)}])},[d("div",en,[i(e).footer.message?(o(),l("p",{key:0,class:"message",innerHTML:i(e).footer.message},null,8,tn)):m("",!0),i(e).footer.copyright?(o(),l("p",{key:1,class:"copyright",innerHTML:i(e).footer.copyright},null,8,sn)):m("",!0)])],2)):m("",!0)}}),an=k(nn,[["__scopeId","data-v-c970a860"]]);function on(){const{theme:a,frontmatter:e}=S(),t=Se([]),n=y(()=>t.value.length>0);return x(()=>{t.value=be(e.value.outline??a.value.outline)}),{headers:t,hasLocalNav:n}}const rn={class:"menu-text"},ln={class:"header"},cn={class:"outline"},un=h({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(a){const e=a,{theme:t}=S(),n=I(!1),s=I(0),r=I(),c=I();function v(g){var A;(A=r.value)!=null&&A.contains(g.target)||(n.value=!1)}W(n,g=>{if(g){document.addEventListener("click",v);return}document.removeEventListener("click",v)}),le("Escape",()=>{n.value=!1}),x(()=>{n.value=!1});function p(){n.value=!n.value,s.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function _(g){g.target.classList.contains("outline-link")&&(c.value&&(c.value.style.transition="none"),Ne(()=>{n.value=!1}))}function L(){n.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(g,A)=>(o(),l("div",{class:"VPLocalNavOutlineDropdown",style:Ie({"--vp-vh":s.value+"px"}),ref_key:"main",ref:r},[g.headers.length>0?(o(),l("button",{key:0,onClick:p,class:T({open:n.value})},[d("span",rn,V(i(we)(i(t))),1),A[0]||(A[0]=d("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(o(),l("button",{key:1,onClick:L},V(i(t).returnToTopLabel||"Return to top"),1)),b(pe,{name:"flyout"},{default:f(()=>[n.value?(o(),l("div",{key:0,ref_key:"items",ref:c,class:"items",onClick:_},[d("div",ln,[d("a",{class:"top-link",href:"#",onClick:L},V(i(t).returnToTopLabel||"Return to top"),1)]),d("div",cn,[b(Ee,{headers:g.headers},null,8,["headers"])])],512)):m("",!0)]),_:1})],4))}}),dn=k(un,[["__scopeId","data-v-bc9dc845"]]),pn={class:"container"},vn=["aria-expanded"],fn={class:"menu-text"},mn=h({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(a){const{theme:e,frontmatter:t}=S(),{hasSidebar:n}=D(),{headers:s}=on(),{y:r}=Te(),c=I(0);G(()=>{c.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),x(()=>{s.value=be(t.value.outline??e.value.outline)});const v=y(()=>s.value.length===0),p=y(()=>v.value&&!n.value),_=y(()=>({VPLocalNav:!0,"has-sidebar":n.value,empty:v.value,fixed:p.value}));return(L,g)=>i(t).layout!=="home"&&(!p.value||i(r)>=c.value)?(o(),l("div",{key:0,class:T(_.value)},[d("div",pn,[i(n)?(o(),l("button",{key:0,class:"menu","aria-expanded":L.open,"aria-controls":"VPSidebarNav",onClick:g[0]||(g[0]=A=>L.$emit("open-menu"))},[g[1]||(g[1]=d("span",{class:"vpi-align-left menu-icon"},null,-1)),d("span",fn,V(i(e).sidebarMenuLabel||"Menu"),1)],8,vn)):m("",!0),b(dn,{headers:i(s),navHeight:c.value},null,8,["headers","navHeight"])])],2)):m("",!0)}}),hn=k(mn,[["__scopeId","data-v-070ab83d"]]);function _n(){const a=I(!1);function e(){a.value=!0,window.addEventListener("resize",s)}function t(){a.value=!1,window.removeEventListener("resize",s)}function n(){a.value?t():e()}function s(){window.outerWidth>=768&&t()}const r=ee();return W(()=>r.path,t),{isScreenOpen:a,openScreen:e,closeScreen:t,toggleScreen:n}}const bn={},gn={class:"VPSwitch",type:"button",role:"switch"},kn={class:"check"},$n={key:0,class:"icon"};function yn(a,e){return o(),l("button",gn,[d("span",kn,[a.$slots.default?(o(),l("span",$n,[u(a.$slots,"default",{},void 0,!0)])):m("",!0)])])}const An=k(bn,[["render",yn],["__scopeId","data-v-4a1c76db"]]),Pn=h({__name:"VPSwitchAppearance",setup(a){const{isDark:e,theme:t}=S(),n=z("toggle-appearance",()=>{e.value=!e.value}),s=I("");return me(()=>{s.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(r,c)=>(o(),$(An,{title:s.value,class:"VPSwitchAppearance","aria-checked":i(e),onClick:i(n)},{default:f(()=>c[0]||(c[0]=[d("span",{class:"vpi-sun sun"},null,-1),d("span",{class:"vpi-moon moon"},null,-1)])),_:1},8,["title","aria-checked","onClick"]))}}),ge=k(Pn,[["__scopeId","data-v-e40a8bb6"]]),Ln={key:0,class:"VPNavBarAppearance"},Sn=h({__name:"VPNavBarAppearance",setup(a){const{site:e}=S();return(t,n)=>i(e).appearance&&i(e).appearance!=="force-dark"&&i(e).appearance!=="force-auto"?(o(),l("div",Ln,[b(ge)])):m("",!0)}}),Vn=k(Sn,[["__scopeId","data-v-af096f4a"]]),ke=I();let Qe=!1,re=0;function In(a){const e=I(!1);if(te){!Qe&&Nn(),re++;const t=W(ke,n=>{var s,r,c;n===a.el.value||(s=a.el.value)!=null&&s.contains(n)?(e.value=!0,(r=a.onFocus)==null||r.call(a)):(e.value=!1,(c=a.onBlur)==null||c.call(a))});fe(()=>{t(),re--,re||Tn()})}return Re(e)}function Nn(){document.addEventListener("focusin",Fe),Qe=!0,ke.value=document.activeElement}function Tn(){document.removeEventListener("focusin",Fe)}function Fe(){ke.value=document.activeElement}const Cn={class:"VPMenuLink"},Mn=h({__name:"VPMenuLink",props:{item:{}},setup(a){const{page:e}=S();return(t,n)=>(o(),l("div",Cn,[b(Q,{class:T({active:i(K)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:f(()=>[F(V(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),se=k(Mn,[["__scopeId","data-v-8b74d055"]]),Bn={class:"VPMenuGroup"},wn={key:0,class:"title"},En=h({__name:"VPMenuGroup",props:{text:{},items:{}},setup(a){return(e,t)=>(o(),l("div",Bn,[e.text?(o(),l("p",wn,V(e.text),1)):m("",!0),(o(!0),l(C,null,w(e.items,n=>(o(),l(C,null,["link"in n?(o(),$(se,{key:0,item:n},null,8,["item"])):m("",!0)],64))),256))]))}}),Qn=k(En,[["__scopeId","data-v-48c802d0"]]),Fn={class:"VPMenu"},Hn={key:0,class:"items"},Wn=h({__name:"VPMenu",props:{items:{}},setup(a){return(e,t)=>(o(),l("div",Fn,[e.items?(o(),l("div",Hn,[(o(!0),l(C,null,w(e.items,n=>(o(),l(C,{key:JSON.stringify(n)},["link"in n?(o(),$(se,{key:0,item:n},null,8,["item"])):"component"in n?(o(),$(H(n.component),U({key:1,ref_for:!0},n.props),null,16)):(o(),$(Qn,{key:2,text:n.text,items:n.items},null,8,["text","items"]))],64))),128))])):m("",!0),u(e.$slots,"default",{},void 0,!0)]))}}),Dn=k(Wn,[["__scopeId","data-v-7dd3104a"]]),On=["aria-expanded","aria-label"],Un={key:0,class:"text"},Gn=["innerHTML"],Jn={key:1,class:"vpi-more-horizontal icon"},Kn={class:"menu"},jn=h({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(a){const e=I(!1),t=I();In({el:t,onBlur:n});function n(){e.value=!1}return(s,r)=>(o(),l("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=c=>e.value=!0),onMouseleave:r[2]||(r[2]=c=>e.value=!1)},[d("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":s.label,onClick:r[0]||(r[0]=c=>e.value=!e.value)},[s.button||s.icon?(o(),l("span",Un,[s.icon?(o(),l("span",{key:0,class:T([s.icon,"option-icon"])},null,2)):m("",!0),s.button?(o(),l("span",{key:1,innerHTML:s.button},null,8,Gn)):m("",!0),r[3]||(r[3]=d("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(o(),l("span",Jn))],8,On),d("div",Kn,[b(Dn,{items:s.items},{default:f(()=>[u(s.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),$e=k(jn,[["__scopeId","data-v-e5380155"]]),zn=["href","aria-label","innerHTML"],Rn=h({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(a){const e=a,t=y(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,s)=>(o(),l("a",{class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,zn))}}),Zn=k(Rn,[["__scopeId","data-v-717b8b75"]]),Yn={class:"VPSocialLinks"},Xn=h({__name:"VPSocialLinks",props:{links:{}},setup(a){return(e,t)=>(o(),l("div",Yn,[(o(!0),l(C,null,w(e.links,({link:n,icon:s,ariaLabel:r})=>(o(),$(Zn,{key:n,icon:s,link:n,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),ne=k(Xn,[["__scopeId","data-v-ee7a9424"]]),qn={key:0,class:"group translations"},xn={class:"trans-title"},ea={key:1,class:"group"},ta={class:"item appearance"},sa={class:"label"},na={class:"appearance-action"},aa={key:2,class:"group"},oa={class:"item social-links"},ra=h({__name:"VPNavBarExtra",setup(a){const{site:e,theme:t}=S(),{localeLinks:n,currentLang:s}=Z({correspondingLink:!0}),r=y(()=>n.value.length&&s.value.label||e.value.appearance||t.value.socialLinks);return(c,v)=>r.value?(o(),$($e,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:f(()=>[i(n).length&&i(s).label?(o(),l("div",qn,[d("p",xn,V(i(s).label),1),(o(!0),l(C,null,w(i(n),p=>(o(),$(se,{key:p.link,item:p},null,8,["item"]))),128))])):m("",!0),i(e).appearance&&i(e).appearance!=="force-dark"&&i(e).appearance!=="force-auto"?(o(),l("div",ea,[d("div",ta,[d("p",sa,V(i(t).darkModeSwitchLabel||"Appearance"),1),d("div",na,[b(ge)])])])):m("",!0),i(t).socialLinks?(o(),l("div",aa,[d("div",oa,[b(ne,{class:"social-links-list",links:i(t).socialLinks},null,8,["links"])])])):m("",!0)]),_:1})):m("",!0)}}),ia=k(ra,[["__scopeId","data-v-925effce"]]),la=["aria-expanded"],ca=h({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(a){return(e,t)=>(o(),l("button",{type:"button",class:T(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=n=>e.$emit("click"))},t[1]||(t[1]=[d("span",{class:"container"},[d("span",{class:"top"}),d("span",{class:"middle"}),d("span",{class:"bottom"})],-1)]),10,la))}}),ua=k(ca,[["__scopeId","data-v-5dea55bf"]]),da=["innerHTML"],pa=h({__name:"VPNavBarMenuLink",props:{item:{}},setup(a){const{page:e}=S();return(t,n)=>(o(),$(Q,{class:T({VPNavBarMenuLink:!0,active:i(K)(i(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:f(()=>[d("span",{innerHTML:t.item.text},null,8,da)]),_:1},8,["class","href","noIcon","target","rel"]))}}),va=k(pa,[["__scopeId","data-v-ed5ac1f6"]]),fa=h({__name:"VPNavBarMenuGroup",props:{item:{}},setup(a){const e=a,{page:t}=S(),n=r=>"component"in r?!1:"link"in r?K(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(n),s=y(()=>n(e.item));return(r,c)=>(o(),$($e,{class:T({VPNavBarMenuGroup:!0,active:i(K)(i(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||s.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),ma={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},ha=h({__name:"VPNavBarMenu",setup(a){const{theme:e}=S();return(t,n)=>i(e).nav?(o(),l("nav",ma,[n[0]||(n[0]=d("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(o(!0),l(C,null,w(i(e).nav,s=>(o(),l(C,{key:JSON.stringify(s)},["link"in s?(o(),$(va,{key:0,item:s},null,8,["item"])):"component"in s?(o(),$(H(s.component),U({key:1,ref_for:!0},s.props),null,16)):(o(),$(fa,{key:2,item:s},null,8,["item"]))],64))),128))])):m("",!0)}}),_a=k(ha,[["__scopeId","data-v-e6d46098"]]);function ba(a){const{localeIndex:e,theme:t}=S();function n(s){var M,B,N;const r=s.split("."),c=(M=t.value.search)==null?void 0:M.options,v=c&&typeof c=="object",p=v&&((N=(B=c.locales)==null?void 0:B[e.value])==null?void 0:N.translations)||null,_=v&&c.translations||null;let L=p,g=_,A=a;const P=r.pop();for(const E of r){let O=null;const j=A==null?void 0:A[E];j&&(O=A=j);const ae=g==null?void 0:g[E];ae&&(O=g=ae);const oe=L==null?void 0:L[E];oe&&(O=L=oe),j||(A=O),ae||(g=O),oe||(L=O)}return(L==null?void 0:L[P])??(g==null?void 0:g[P])??(A==null?void 0:A[P])??""}return n}const ga=["aria-label"],ka={class:"DocSearch-Button-Container"},$a={class:"DocSearch-Button-Placeholder"},Ae=h({__name:"VPNavBarSearchButton",setup(a){const t=ba({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(n,s)=>(o(),l("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":i(t)("button.buttonAriaLabel")},[d("span",ka,[s[0]||(s[0]=d("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),d("span",$a,V(i(t)("button.buttonText")),1)]),s[1]||(s[1]=d("span",{class:"DocSearch-Button-Keys"},[d("kbd",{class:"DocSearch-Button-Key"}),d("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,ga))}}),ya={class:"VPNavBarSearch"},Aa={id:"local-search"},Pa={key:1,id:"docsearch"},La=h({__name:"VPNavBarSearch",setup(a){const e=Ze(()=>Ye(()=>import("./VPLocalSearchBox.DHQW8c6e.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:n}=S(),s=I(!1),r=I(!1);G(()=>{});function c(){s.value||(s.value=!0,setTimeout(v,16))}function v(){const g=new Event("keydown");g.key="k",g.metaKey=!0,window.dispatchEvent(g),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||v()},16)}function p(g){const A=g.target,P=A.tagName;return A.isContentEditable||P==="INPUT"||P==="SELECT"||P==="TEXTAREA"}const _=I(!1);le("k",g=>{(g.ctrlKey||g.metaKey)&&(g.preventDefault(),_.value=!0)}),le("/",g=>{p(g)||(g.preventDefault(),_.value=!0)});const L="local";return(g,A)=>{var P;return o(),l("div",ya,[i(L)==="local"?(o(),l(C,{key:0},[_.value?(o(),$(i(e),{key:0,onClose:A[0]||(A[0]=M=>_.value=!1)})):m("",!0),d("div",Aa,[b(Ae,{onClick:A[1]||(A[1]=M=>_.value=!0)})])],64)):i(L)==="algolia"?(o(),l(C,{key:1},[s.value?(o(),$(i(t),{key:0,algolia:((P=i(n).search)==null?void 0:P.options)??i(n).algolia,onVnodeBeforeMount:A[2]||(A[2]=M=>r.value=!0)},null,8,["algolia"])):m("",!0),r.value?m("",!0):(o(),l("div",Pa,[b(Ae,{onClick:c})]))],64)):m("",!0)])}}}),Sa=h({__name:"VPNavBarSocialLinks",setup(a){const{theme:e}=S();return(t,n)=>i(e).socialLinks?(o(),$(ne,{key:0,class:"VPNavBarSocialLinks",links:i(e).socialLinks},null,8,["links"])):m("",!0)}}),Va=k(Sa,[["__scopeId","data-v-164c457f"]]),Ia=["href","rel","target"],Na={key:1},Ta={key:2},Ca=h({__name:"VPNavBarTitle",setup(a){const{site:e,theme:t}=S(),{hasSidebar:n}=D(),{currentLang:s}=Z(),r=y(()=>{var p;return typeof t.value.logoLink=="string"?t.value.logoLink:(p=t.value.logoLink)==null?void 0:p.link}),c=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.rel}),v=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.target});return(p,_)=>(o(),l("div",{class:T(["VPNavBarTitle",{"has-sidebar":i(n)}])},[d("a",{class:"title",href:r.value??i(_e)(i(s).link),rel:c.value,target:v.value},[u(p.$slots,"nav-bar-title-before",{},void 0,!0),i(t).logo?(o(),$(X,{key:0,class:"logo",image:i(t).logo},null,8,["image"])):m("",!0),i(t).siteTitle?(o(),l("span",Na,V(i(t).siteTitle),1)):i(t).siteTitle===void 0?(o(),l("span",Ta,V(i(e).title),1)):m("",!0),u(p.$slots,"nav-bar-title-after",{},void 0,!0)],8,Ia)],2))}}),Ma=k(Ca,[["__scopeId","data-v-28a961f9"]]),Ba={class:"items"},wa={class:"title"},Ea=h({__name:"VPNavBarTranslations",setup(a){const{theme:e}=S(),{localeLinks:t,currentLang:n}=Z({correspondingLink:!0});return(s,r)=>i(t).length&&i(n).label?(o(),$($e,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:i(e).langMenuLabel||"Change language"},{default:f(()=>[d("div",Ba,[d("p",wa,V(i(n).label),1),(o(!0),l(C,null,w(i(t),c=>(o(),$(se,{key:c.link,item:c},null,8,["item"]))),128))])]),_:1},8,["label"])):m("",!0)}}),Qa=k(Ea,[["__scopeId","data-v-c80d9ad0"]]),Fa={class:"wrapper"},Ha={class:"container"},Wa={class:"title"},Da={class:"content"},Oa={class:"content-body"},Ua=h({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(a){const e=a,{y:t}=Te(),{hasSidebar:n}=D(),{frontmatter:s}=S(),r=I({});return me(()=>{r.value={"has-sidebar":n.value,home:s.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(c,v)=>(o(),l("div",{class:T(["VPNavBar",r.value])},[d("div",Fa,[d("div",Ha,[d("div",Wa,[b(Ma,null,{"nav-bar-title-before":f(()=>[u(c.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[u(c.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),d("div",Da,[d("div",Oa,[u(c.$slots,"nav-bar-content-before",{},void 0,!0),b(La,{class:"search"}),b(_a,{class:"menu"}),b(Qa,{class:"translations"}),b(Vn,{class:"appearance"}),b(Va,{class:"social-links"}),b(ia,{class:"extra"}),u(c.$slots,"nav-bar-content-after",{},void 0,!0),b(ua,{class:"hamburger",active:c.isScreenOpen,onClick:v[0]||(v[0]=p=>c.$emit("toggle-screen"))},null,8,["active"])])])])]),v[1]||(v[1]=d("div",{class:"divider"},[d("div",{class:"divider-line"})],-1))],2))}}),Ga=k(Ua,[["__scopeId","data-v-822684d1"]]),Ja={key:0,class:"VPNavScreenAppearance"},Ka={class:"text"},ja=h({__name:"VPNavScreenAppearance",setup(a){const{site:e,theme:t}=S();return(n,s)=>i(e).appearance&&i(e).appearance!=="force-dark"&&i(e).appearance!=="force-auto"?(o(),l("div",Ja,[d("p",Ka,V(i(t).darkModeSwitchLabel||"Appearance"),1),b(ge)])):m("",!0)}}),za=k(ja,[["__scopeId","data-v-ffb44008"]]),Ra=h({__name:"VPNavScreenMenuLink",props:{item:{}},setup(a){const e=z("close-screen");return(t,n)=>(o(),$(Q,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e),innerHTML:t.item.text},null,8,["href","target","rel","onClick","innerHTML"]))}}),Za=k(Ra,[["__scopeId","data-v-27d04aeb"]]),Ya=h({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(a){const e=z("close-screen");return(t,n)=>(o(),$(Q,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:i(e)},{default:f(()=>[F(V(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),He=k(Ya,[["__scopeId","data-v-7179dbb7"]]),Xa={class:"VPNavScreenMenuGroupSection"},qa={key:0,class:"title"},xa=h({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(a){return(e,t)=>(o(),l("div",Xa,[e.text?(o(),l("p",qa,V(e.text),1)):m("",!0),(o(!0),l(C,null,w(e.items,n=>(o(),$(He,{key:n.text,item:n},null,8,["item"]))),128))]))}}),eo=k(xa,[["__scopeId","data-v-4b8941ac"]]),to=["aria-controls","aria-expanded"],so=["innerHTML"],no=["id"],ao={key:0,class:"item"},oo={key:1,class:"item"},ro={key:2,class:"group"},io=h({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(a){const e=a,t=I(!1),n=y(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function s(){t.value=!t.value}return(r,c)=>(o(),l("div",{class:T(["VPNavScreenMenuGroup",{open:t.value}])},[d("button",{class:"button","aria-controls":n.value,"aria-expanded":t.value,onClick:s},[d("span",{class:"button-text",innerHTML:r.text},null,8,so),c[0]||(c[0]=d("span",{class:"vpi-plus button-icon"},null,-1))],8,to),d("div",{id:n.value,class:"items"},[(o(!0),l(C,null,w(r.items,v=>(o(),l(C,{key:JSON.stringify(v)},["link"in v?(o(),l("div",ao,[b(He,{item:v},null,8,["item"])])):"component"in v?(o(),l("div",oo,[(o(),$(H(v.component),U({ref_for:!0},v.props,{"screen-menu":""}),null,16))])):(o(),l("div",ro,[b(eo,{text:v.text,items:v.items},null,8,["text","items"])]))],64))),128))],8,no)],2))}}),lo=k(io,[["__scopeId","data-v-875057a5"]]),co={key:0,class:"VPNavScreenMenu"},uo=h({__name:"VPNavScreenMenu",setup(a){const{theme:e}=S();return(t,n)=>i(e).nav?(o(),l("nav",co,[(o(!0),l(C,null,w(i(e).nav,s=>(o(),l(C,{key:JSON.stringify(s)},["link"in s?(o(),$(Za,{key:0,item:s},null,8,["item"])):"component"in s?(o(),$(H(s.component),U({key:1,ref_for:!0},s.props,{"screen-menu":""}),null,16)):(o(),$(lo,{key:2,text:s.text||"",items:s.items},null,8,["text","items"]))],64))),128))])):m("",!0)}}),po=h({__name:"VPNavScreenSocialLinks",setup(a){const{theme:e}=S();return(t,n)=>i(e).socialLinks?(o(),$(ne,{key:0,class:"VPNavScreenSocialLinks",links:i(e).socialLinks},null,8,["links"])):m("",!0)}}),vo={class:"list"},fo=h({__name:"VPNavScreenTranslations",setup(a){const{localeLinks:e,currentLang:t}=Z({correspondingLink:!0}),n=I(!1);function s(){n.value=!n.value}return(r,c)=>i(e).length&&i(t).label?(o(),l("div",{key:0,class:T(["VPNavScreenTranslations",{open:n.value}])},[d("button",{class:"title",onClick:s},[c[0]||(c[0]=d("span",{class:"vpi-languages icon lang"},null,-1)),F(" "+V(i(t).label)+" ",1),c[1]||(c[1]=d("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),d("ul",vo,[(o(!0),l(C,null,w(i(e),v=>(o(),l("li",{key:v.link,class:"item"},[b(Q,{class:"link",href:v.link},{default:f(()=>[F(V(v.text),1)]),_:2},1032,["href"])]))),128))])],2)):m("",!0)}}),mo=k(fo,[["__scopeId","data-v-362991c2"]]),ho={class:"container"},_o=h({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(a){const e=I(null),t=Ce(te?document.body:null);return(n,s)=>(o(),$(pe,{name:"fade",onEnter:s[0]||(s[0]=r=>t.value=!0),onAfterLeave:s[1]||(s[1]=r=>t.value=!1)},{default:f(()=>[n.open?(o(),l("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[d("div",ho,[u(n.$slots,"nav-screen-content-before",{},void 0,!0),b(uo,{class:"menu"}),b(mo,{class:"translations"}),b(za,{class:"appearance"}),b(po,{class:"social-links"}),u(n.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):m("",!0)]),_:3}))}}),bo=k(_o,[["__scopeId","data-v-833aabba"]]),go={key:0,class:"VPNav"},ko=h({__name:"VPNav",setup(a){const{isScreenOpen:e,closeScreen:t,toggleScreen:n}=_n(),{frontmatter:s}=S(),r=y(()=>s.value.navbar!==!1);return he("close-screen",t),q(()=>{te&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(c,v)=>r.value?(o(),l("header",go,[b(Ga,{"is-screen-open":i(e),onToggleScreen:i(n)},{"nav-bar-title-before":f(()=>[u(c.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[u(c.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[u(c.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[u(c.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),b(bo,{open:i(e)},{"nav-screen-content-before":f(()=>[u(c.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[u(c.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):m("",!0)}}),$o=k(ko,[["__scopeId","data-v-f1e365da"]]),yo=["role","tabindex"],Ao={key:1,class:"items"},Po=h({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(a){const e=a,{collapsed:t,collapsible:n,isLink:s,isActiveLink:r,hasActiveLink:c,hasChildren:v,toggle:p}=$t(y(()=>e.item)),_=y(()=>v.value?"section":"div"),L=y(()=>s.value?"a":"div"),g=y(()=>v.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),A=y(()=>s.value?void 0:"button"),P=y(()=>[[`level-${e.depth}`],{collapsible:n.value},{collapsed:t.value},{"is-link":s.value},{"is-active":r.value},{"has-active":c.value}]);function M(N){"key"in N&&N.key!=="Enter"||!e.item.link&&p()}function B(){e.item.link&&p()}return(N,E)=>{const O=J("VPSidebarItem",!0);return o(),$(H(_.value),{class:T(["VPSidebarItem",P.value])},{default:f(()=>[N.item.text?(o(),l("div",U({key:0,class:"item",role:A.value},Xe(N.item.items?{click:M,keydown:M}:{},!0),{tabindex:N.item.items&&0}),[E[1]||(E[1]=d("div",{class:"indicator"},null,-1)),N.item.link?(o(),$(Q,{key:0,tag:L.value,class:"link",href:N.item.link,rel:N.item.rel,target:N.item.target},{default:f(()=>[(o(),$(H(g.value),{class:"text",innerHTML:N.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(o(),$(H(g.value),{key:1,class:"text",innerHTML:N.item.text},null,8,["innerHTML"])),N.item.collapsed!=null&&N.item.items&&N.item.items.length?(o(),l("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:B,onKeydown:qe(B,["enter"]),tabindex:"0"},E[0]||(E[0]=[d("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):m("",!0)],16,yo)):m("",!0),N.item.items&&N.item.items.length?(o(),l("div",Ao,[N.depth<5?(o(!0),l(C,{key:0},w(N.item.items,j=>(o(),$(O,{key:j.text,item:j,depth:N.depth+1},null,8,["item","depth"]))),128)):m("",!0)])):m("",!0)]),_:1},8,["class"])}}}),Lo=k(Po,[["__scopeId","data-v-196b2e5f"]]),So=h({__name:"VPSidebarGroup",props:{items:{}},setup(a){const e=I(!0);let t=null;return G(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),xe(()=>{t!=null&&(clearTimeout(t),t=null)}),(n,s)=>(o(!0),l(C,null,w(n.items,r=>(o(),l("div",{key:r.text,class:T(["group",{"no-transition":e.value}])},[b(Lo,{item:r,depth:0},null,8,["item"])],2))),128))}}),Vo=k(So,[["__scopeId","data-v-9e426adc"]]),Io={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},No=h({__name:"VPSidebar",props:{open:{type:Boolean}},setup(a){const{sidebarGroups:e,hasSidebar:t}=D(),n=a,s=I(null),r=Ce(te?document.body:null);W([n,s],()=>{var v;n.open?(r.value=!0,(v=s.value)==null||v.focus()):r.value=!1},{immediate:!0,flush:"post"});const c=I(0);return W(e,()=>{c.value+=1},{deep:!0}),(v,p)=>i(t)?(o(),l("aside",{key:0,class:T(["VPSidebar",{open:v.open}]),ref_key:"navEl",ref:s,onClick:p[0]||(p[0]=et(()=>{},["stop"]))},[p[2]||(p[2]=d("div",{class:"curtain"},null,-1)),d("nav",Io,[p[1]||(p[1]=d("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),u(v.$slots,"sidebar-nav-before",{},void 0,!0),(o(),$(Vo,{items:i(e),key:c.value},null,8,["items"])),u(v.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):m("",!0)}}),To=k(No,[["__scopeId","data-v-18756405"]]),Co=h({__name:"VPSkipLink",setup(a){const e=ee(),t=I();W(()=>e.path,()=>t.value.focus());function n({target:s}){const r=document.getElementById(decodeURIComponent(s.hash).slice(1));if(r){const c=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",c)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",c),r.focus(),window.scrollTo(0,0)}}return(s,r)=>(o(),l(C,null,[d("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),d("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n}," Skip to content ")],64))}}),Mo=k(Co,[["__scopeId","data-v-c3508ec8"]]),Bo=h({__name:"Layout",setup(a){const{isOpen:e,open:t,close:n}=D(),s=ee();W(()=>s.path,n),kt(e,n);const{frontmatter:r}=S(),c=Me(),v=y(()=>!!c["home-hero-image"]);return he("hero-image-slot-exists",v),(p,_)=>{const L=J("Content");return i(r).layout!==!1?(o(),l("div",{key:0,class:T(["Layout",i(r).pageClass])},[u(p.$slots,"layout-top",{},void 0,!0),b(Mo),b(it,{class:"backdrop",show:i(e),onClick:i(n)},null,8,["show","onClick"]),b($o,null,{"nav-bar-title-before":f(()=>[u(p.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[u(p.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[u(p.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[u(p.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":f(()=>[u(p.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[u(p.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),b(hn,{open:i(e),onOpenMenu:i(t)},null,8,["open","onOpenMenu"]),b(To,{open:i(e)},{"sidebar-nav-before":f(()=>[u(p.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":f(()=>[u(p.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),b(xs,null,{"page-top":f(()=>[u(p.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[u(p.$slots,"page-bottom",{},void 0,!0)]),"not-found":f(()=>[u(p.$slots,"not-found",{},void 0,!0)]),"home-hero-before":f(()=>[u(p.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[u(p.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[u(p.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[u(p.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[u(p.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[u(p.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[u(p.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[u(p.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[u(p.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":f(()=>[u(p.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[u(p.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[u(p.$slots,"doc-after",{},void 0,!0)]),"doc-top":f(()=>[u(p.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[u(p.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":f(()=>[u(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[u(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[u(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[u(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[u(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[u(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),b(an),u(p.$slots,"layout-bottom",{},void 0,!0)],2)):(o(),$(L,{key:1}))}}}),wo=k(Bo,[["__scopeId","data-v-a9a9e638"]]),Eo={},Qo={class:"VPTeamPage"};function Fo(a,e){return o(),l("div",Qo,[u(a.$slots,"default")])}const Mr=k(Eo,[["render",Fo],["__scopeId","data-v-c2f8e101"]]),Ho={},Wo={class:"VPTeamPageTitle"},Do={key:0,class:"title"},Oo={key:1,class:"lead"};function Uo(a,e){return o(),l("div",Wo,[a.$slots.title?(o(),l("h1",Do,[u(a.$slots,"title",{},void 0,!0)])):m("",!0),a.$slots.lead?(o(),l("p",Oo,[u(a.$slots,"lead",{},void 0,!0)])):m("",!0)])}const Br=k(Ho,[["render",Uo],["__scopeId","data-v-e277e15c"]]),Go={},Jo={class:"VPTeamPageSection"},Ko={class:"title"},jo={key:0,class:"title-text"},zo={key:0,class:"lead"},Ro={key:1,class:"members"};function Zo(a,e){return o(),l("section",Jo,[d("div",Ko,[e[0]||(e[0]=d("div",{class:"title-line"},null,-1)),a.$slots.title?(o(),l("h2",jo,[u(a.$slots,"title",{},void 0,!0)])):m("",!0)]),a.$slots.lead?(o(),l("p",zo,[u(a.$slots,"lead",{},void 0,!0)])):m("",!0),a.$slots.members?(o(),l("div",Ro,[u(a.$slots,"members",{},void 0,!0)])):m("",!0)])}const wr=k(Go,[["render",Zo],["__scopeId","data-v-d43bc49d"]]),Yo={class:"profile"},Xo={class:"avatar"},qo=["src","alt"],xo={class:"data"},er={class:"name"},tr={key:0,class:"affiliation"},sr={key:0,class:"title"},nr={key:1,class:"at"},ar=["innerHTML"],or={key:2,class:"links"},rr={key:0,class:"sp"},ir=h({__name:"VPTeamMembersItem",props:{size:{default:"medium"},member:{}},setup(a){return(e,t)=>(o(),l("article",{class:T(["VPTeamMembersItem",[e.size]])},[d("div",Yo,[d("figure",Xo,[d("img",{class:"avatar-img",src:e.member.avatar,alt:e.member.name},null,8,qo)]),d("div",xo,[d("h1",er,V(e.member.name),1),e.member.title||e.member.org?(o(),l("p",tr,[e.member.title?(o(),l("span",sr,V(e.member.title),1)):m("",!0),e.member.title&&e.member.org?(o(),l("span",nr," @ ")):m("",!0),e.member.org?(o(),$(Q,{key:2,class:T(["org",{link:e.member.orgLink}]),href:e.member.orgLink,"no-icon":""},{default:f(()=>[F(V(e.member.org),1)]),_:1},8,["class","href"])):m("",!0)])):m("",!0),e.member.desc?(o(),l("p",{key:1,class:"desc",innerHTML:e.member.desc},null,8,ar)):m("",!0),e.member.links?(o(),l("div",or,[b(ne,{links:e.member.links},null,8,["links"])])):m("",!0)])]),e.member.sponsor?(o(),l("div",rr,[b(Q,{class:"sp-link",href:e.member.sponsor,"no-icon":""},{default:f(()=>[t[0]||(t[0]=d("span",{class:"vpi-heart sp-icon"},null,-1)),F(" "+V(e.member.actionText||"Sponsor"),1)]),_:1},8,["href"])])):m("",!0)],2))}}),lr=k(ir,[["__scopeId","data-v-f9987cb6"]]),cr={class:"container"},ur=h({__name:"VPTeamMembers",props:{size:{default:"medium"},members:{}},setup(a){const e=a,t=y(()=>[e.size,`count-${e.members.length}`]);return(n,s)=>(o(),l("div",{class:T(["VPTeamMembers",t.value])},[d("div",cr,[(o(!0),l(C,null,w(n.members,r=>(o(),l("div",{key:r.name,class:"item"},[b(lr,{size:n.size,member:r},null,8,["size","member"])]))),128))])],2))}}),Er=k(ur,[["__scopeId","data-v-fba19bad"]]),Pe={Layout:wo,enhanceApp:({app:a})=>{a.component("Badge",at)}},dr={},pr={style:{"text-align":"center"}};function vr(a,e){const t=J("font");return o(),l(C,null,[e[1]||(e[1]=d("br",null,null,-1)),d("h1",pr,[d("strong",null,[b(t,{color:"orange"},{default:f(()=>e[0]||(e[0]=[F(" Package Ecosystem")])),_:1})])]),e[2]||(e[2]=tt('

Read n-d array like-data

DiskArrays.jl

Get your chunks!

Named Dimensions

DimensionalData.jl

Select & Index!

Out of memory data

Zarr.jl

Chunkerd, compressed !

Rasterized spatial data

Rasters.jl

Read and manipulate !

Array-oriented data

NetCDF.jl

Scientific binary data.

Raster and vector data

ArchGDAL.jl

GDAL in Julia.

An interface for

GeoInterface.jl

geospatial data in Julia.

A higher level interface

GRIBDatasets.jl

for reading GRIB files.

Array-oriented data

NCDatasets.jl

Scientific binary data.

',9))],64)}const fr=k(dr,[["render",vr]]),mr=a=>{if(typeof document>"u")return{stabilizeScrollPosition:s=>async(...r)=>s(...r)};const e=document.documentElement;return{stabilizeScrollPosition:n=>async(...s)=>{const r=n(...s),c=a.value;if(!c)return r;const v=c.offsetTop-e.scrollTop;return await Ne(),e.scrollTop=c.offsetTop-v,r}}},We="vitepress:tabSharedState",R=typeof localStorage<"u"?localStorage:null,De="vitepress:tabsSharedState",hr=()=>{const a=R==null?void 0:R.getItem(De);if(a)try{return JSON.parse(a)}catch{}return{}},_r=a=>{R&&R.setItem(De,JSON.stringify(a))},br=a=>{const e=st({});W(()=>e.content,(t,n)=>{t&&n&&_r(t)},{deep:!0}),a.provide(We,e)},gr=(a,e)=>{const t=z(We);if(!t)throw new Error("[vitepress-plugin-tabs] TabsSharedState should be injected");G(()=>{t.content||(t.content=hr())});const n=I(),s=y({get(){var p;const c=e.value,v=a.value;if(c){const _=(p=t.content)==null?void 0:p[c];if(_&&v.includes(_))return _}else{const _=n.value;if(_)return _}return v[0]},set(c){const v=e.value;v?t.content&&(t.content[v]=c):n.value=c}});return{selected:s,select:c=>{s.value=c}}};let Le=0;const kr=()=>(Le++,""+Le);function $r(){const a=Me();return y(()=>{var n;const t=(n=a.default)==null?void 0:n.call(a);return t?t.filter(s=>typeof s.type=="object"&&"__name"in s.type&&s.type.__name==="PluginTabsTab"&&s.props).map(s=>{var r;return(r=s.props)==null?void 0:r.label}):[]})}const Oe="vitepress:tabSingleState",yr=a=>{he(Oe,a)},Ar=()=>{const a=z(Oe);if(!a)throw new Error("[vitepress-plugin-tabs] TabsSingleState should be injected");return a},Pr={class:"plugin-tabs"},Lr=["id","aria-selected","aria-controls","tabindex","onClick"],Sr=h({__name:"PluginTabs",props:{sharedStateKey:{}},setup(a){const e=a,t=$r(),{selected:n,select:s}=gr(t,nt(e,"sharedStateKey")),r=I(),{stabilizeScrollPosition:c}=mr(r),v=c(s),p=I([]),_=g=>{var M;const A=t.value.indexOf(n.value);let P;g.key==="ArrowLeft"?P=A>=1?A-1:t.value.length-1:g.key==="ArrowRight"&&(P=A(o(),l("div",Pr,[d("div",{ref_key:"tablist",ref:r,class:"plugin-tabs--tab-list",role:"tablist",onKeydown:_},[(o(!0),l(C,null,w(i(t),P=>(o(),l("button",{id:`tab-${P}-${i(L)}`,ref_for:!0,ref_key:"buttonRefs",ref:p,key:P,role:"tab",class:"plugin-tabs--tab","aria-selected":P===i(n),"aria-controls":`panel-${P}-${i(L)}`,tabindex:P===i(n)?0:-1,onClick:()=>i(v)(P)},V(P),9,Lr))),128))],544),u(g.$slots,"default")]))}}),Vr=["id","aria-labelledby"],Ir=h({__name:"PluginTabsTab",props:{label:{}},setup(a){const{uid:e,selected:t}=Ar();return(n,s)=>i(t)===n.label?(o(),l("div",{key:0,id:`panel-${n.label}-${i(e)}`,class:"plugin-tabs--content",role:"tabpanel",tabindex:"0","aria-labelledby":`tab-${n.label}-${i(e)}`},[u(n.$slots,"default",{},void 0,!0)],8,Vr)):m("",!0)}}),Nr=k(Ir,[["__scopeId","data-v-9b0d03d2"]]),Tr=a=>{br(a),a.component("PluginTabs",Sr),a.component("PluginTabsTab",Nr)},Qr={extends:Pe,Layout(){return ye(Pe.Layout,null,{"aside-ads-before":()=>ye(fr)})},enhanceApp({app:a,router:e,siteData:t}){Tr(a)}};export{Qr as R,Br as V,Er as a,wr as b,Mr as c,ba as d,S as u}; diff --git a/previews/PR437/assets/development_contribute.md.lnYHnNmM.js b/previews/PR437/assets/development_contribute.md.lnYHnNmM.js new file mode 100644 index 00000000..18ab9772 --- /dev/null +++ b/previews/PR437/assets/development_contribute.md.lnYHnNmM.js @@ -0,0 +1,3 @@ +import{_ as s,c as t,a2 as a,o as i}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Contribute to YAXArrays.jl","description":"","frontmatter":{},"headers":[],"relativePath":"development/contribute.md","filePath":"development/contribute.md","lastUpdated":null}'),l={name:"development/contribute.md"};function o(n,e,r,p,d,h){return i(),t("div",null,e[0]||(e[0]=[a(`

Contribute to YAXArrays.jl

Pull requests and bug reports are always welcome at the YAXArrays.jl GitHub repository.

Contribute to Documentation

Contributing with examples can be done by first creating a new file example here

new file

  • your_new_file.md at docs/src/UserGuide/

Once this is done you need to add a new entry here at the appropriate level.

add entry to docs

Your new entry should look like:

  • { text: 'Your title example', link: '/UserGuide/your_new_file.md' }

Build docs locally

If you want to take a look at the docs locally before doing a PR follow the next steps:

Install the dependencies in your system, locate yourself at the docs level folder, then do

sh
npm i

Then simply go to your docs env and activate it, i.e.

sh
docs> julia
+julia> ]
+pkg> activate .

Next, run the scripts. Generate files and build docs by running:

sh
include("make.jl")

Now go to your terminal in the same path docs> and run:

sh
npm run docs:dev

This should ouput http://localhost:5173/YAXArrays.jl/, copy/paste this into your browser and you are all set.

`,18)]))}const k=s(l,[["render",o]]);export{u as __pageData,k as default}; diff --git a/previews/PR437/assets/development_contribute.md.lnYHnNmM.lean.js b/previews/PR437/assets/development_contribute.md.lnYHnNmM.lean.js new file mode 100644 index 00000000..18ab9772 --- /dev/null +++ b/previews/PR437/assets/development_contribute.md.lnYHnNmM.lean.js @@ -0,0 +1,3 @@ +import{_ as s,c as t,a2 as a,o as i}from"./chunks/framework.BxolPc_T.js";const u=JSON.parse('{"title":"Contribute to YAXArrays.jl","description":"","frontmatter":{},"headers":[],"relativePath":"development/contribute.md","filePath":"development/contribute.md","lastUpdated":null}'),l={name:"development/contribute.md"};function o(n,e,r,p,d,h){return i(),t("div",null,e[0]||(e[0]=[a(`

Contribute to YAXArrays.jl

Pull requests and bug reports are always welcome at the YAXArrays.jl GitHub repository.

Contribute to Documentation

Contributing with examples can be done by first creating a new file example here

new file

  • your_new_file.md at docs/src/UserGuide/

Once this is done you need to add a new entry here at the appropriate level.

add entry to docs

Your new entry should look like:

  • { text: 'Your title example', link: '/UserGuide/your_new_file.md' }

Build docs locally

If you want to take a look at the docs locally before doing a PR follow the next steps:

Install the dependencies in your system, locate yourself at the docs level folder, then do

sh
npm i

Then simply go to your docs env and activate it, i.e.

sh
docs> julia
+julia> ]
+pkg> activate .

Next, run the scripts. Generate files and build docs by running:

sh
include("make.jl")

Now go to your terminal in the same path docs> and run:

sh
npm run docs:dev

This should ouput http://localhost:5173/YAXArrays.jl/, copy/paste this into your browser and you are all set.

`,18)]))}const k=s(l,[["render",o]]);export{u as __pageData,k as default}; diff --git a/previews/PR437/assets/development_contributors.md.FX1rn6bG.js b/previews/PR437/assets/development_contributors.md.FX1rn6bG.js new file mode 100644 index 00000000..8ab77563 --- /dev/null +++ b/previews/PR437/assets/development_contributors.md.FX1rn6bG.js @@ -0,0 +1 @@ +import{V as u,a as l,b as m,c as g}from"./chunks/theme.C_rChtpL.js";import{B as h,c,G as r,w as s,k as n,o as b,a as e,j as t}from"./chunks/framework.BxolPc_T.js";const p={align:"justify"},z=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page"},"headers":[],"relativePath":"development/contributors.md","filePath":"development/contributors.md","lastUpdated":null}'),v={name:"development/contributors.md"},j=Object.assign(v,{setup(f){const o=[{avatar:"https://www.bgc-jena.mpg.de/employee_images/121366-1667825290?t=eyJ3aWR0aCI6MjEzLCJoZWlnaHQiOjI3NCwiZml0IjoiY3JvcCIsImZpbGVfZXh0ZW5zaW9uIjoid2VicCIsInF1YWxpdHkiOjg2fQ%3D%3D--3e1d41ff4b1ea8928e6734bc473242a90f797dea",name:"Fabian Gans",title:"Geoscientific Programmer",links:[{icon:"github",link:"https://github.com/meggart"}]},{avatar:"https://avatars.githubusercontent.com/u/17124431?v=4",name:"Felix Cremer",title:"PhD Candidate in Remote Sensing",links:[{icon:"github",link:"https://github.com/felixcremer"}]},{avatar:"https://avatars.githubusercontent.com/u/2534009?v=4",name:"Rafael Schouten",title:"Spatial/ecological modelling",links:[{icon:"github",link:"https://github.com/rafaqz"}]},{avatar:"https://avatars.githubusercontent.com/u/19525261?v=4",name:"Lazaro Alonso",title:"Scientist. Data Visualization",links:[{icon:"github",link:"https://github.com/lazarusA"},{icon:"x",link:"https://twitter.com/LazarusAlon"},{icon:"linkedin",link:"https://www.linkedin.com/in/lazaro-alonso/"},{icon:"mastodon",link:"https://julialang.social/@LazaroAlonso"}]}];return(d,a)=>{const i=h("font");return b(),c("div",null,[r(n(g),null,{default:s(()=>[r(n(u),null,{title:s(()=>a[0]||(a[0]=[e("Contributors")])),lead:s(()=>[a[8]||(a[8]=t("strong",null,"Current core contributors ",-1)),a[9]||(a[9]=e()),a[10]||(a[10]=t("br",null,null,-1)),t("div",p,[a[4]||(a[4]=e(" They have taking the lead for the ongoing organizational maintenance and technical direction of ")),r(i,{color:"orange"},{default:s(()=>a[1]||(a[1]=[e("YAXArrays.jl")])),_:1}),a[5]||(a[5]=e(", ")),r(i,{color:"orange"},{default:s(()=>a[2]||(a[2]=[e("DiskArrays.jl")])),_:1}),a[6]||(a[6]=e(" and ")),r(i,{color:"orange"},{default:s(()=>a[3]||(a[3]=[e("DimensionalData.jl")])),_:1}),a[7]||(a[7]=e(". "))])]),_:1}),r(n(l),{size:"small",members:o}),r(n(m),null,{title:s(()=>a[11]||(a[11]=[e("Our valuable contributors")])),lead:s(()=>a[12]||(a[12]=[e(" We appreciate all contributions from the Julia community so that this ecosystem can thrive."),t("br",null,null,-1)])),members:s(()=>a[13]||(a[13]=[t("div",{class:"row"},[t("a",{href:"https://github.com/meggart",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/2539563?v=4"})]),t("a",{href:"https://github.com/felixcremer",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/17124431?v=4"})]),t("a",{href:"https://github.com/lazarusA",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/19525261?v=4"})]),t("a",{href:"https://github.com/gdkrmr",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/12512930?v=4"})]),t("a",{href:"https://github.com/apps/github-actions",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/in/15368?v=4"})]),t("a",{href:"https://github.com/pdimens",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/19176506?v=4"})]),t("a",{href:"https://github.com/twinGu",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/29449917?v=4"})]),t("a",{href:"https://github.com/dpabon",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/13040959?v=4"})]),t("a",{href:"https://github.com/Qfl3x",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/20775896?v=4"})]),t("a",{href:"https://github.com/kongdd",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/9815742?v=4"})]),t("a",{href:"https://github.com/MartinuzziFrancesco",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/10376688?v=4"})]),t("a",{href:"https://github.com/Sonicious",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/16307399?v=4"})]),t("a",{href:"https://github.com/rafaqz",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/2534009?v=4"})]),t("a",{href:"https://github.com/danlooo",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/5780565?v=4"})]),t("a",{href:"https://github.com/MarkusZehner",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/56972144?v=4"})]),t("a",{href:"https://github.com/Balinus",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/3630311?v=4"})]),t("a",{href:"https://github.com/singularitti",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/25192197?v=4"})]),t("a",{href:"https://github.com/ckrich",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/28727495?v=4"})]),t("a",{href:"https://github.com/apps/femtocleaner",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/in/4123?v=4"})]),t("a",{href:"https://github.com/ikselven",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/10441332?v=4"})]),t("a",{href:"https://github.com/linamaes",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/7131773?v=4"})])],-1)])),_:1})]),_:1})])}}});export{z as __pageData,j as default}; diff --git a/previews/PR437/assets/development_contributors.md.FX1rn6bG.lean.js b/previews/PR437/assets/development_contributors.md.FX1rn6bG.lean.js new file mode 100644 index 00000000..8ab77563 --- /dev/null +++ b/previews/PR437/assets/development_contributors.md.FX1rn6bG.lean.js @@ -0,0 +1 @@ +import{V as u,a as l,b as m,c as g}from"./chunks/theme.C_rChtpL.js";import{B as h,c,G as r,w as s,k as n,o as b,a as e,j as t}from"./chunks/framework.BxolPc_T.js";const p={align:"justify"},z=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"page"},"headers":[],"relativePath":"development/contributors.md","filePath":"development/contributors.md","lastUpdated":null}'),v={name:"development/contributors.md"},j=Object.assign(v,{setup(f){const o=[{avatar:"https://www.bgc-jena.mpg.de/employee_images/121366-1667825290?t=eyJ3aWR0aCI6MjEzLCJoZWlnaHQiOjI3NCwiZml0IjoiY3JvcCIsImZpbGVfZXh0ZW5zaW9uIjoid2VicCIsInF1YWxpdHkiOjg2fQ%3D%3D--3e1d41ff4b1ea8928e6734bc473242a90f797dea",name:"Fabian Gans",title:"Geoscientific Programmer",links:[{icon:"github",link:"https://github.com/meggart"}]},{avatar:"https://avatars.githubusercontent.com/u/17124431?v=4",name:"Felix Cremer",title:"PhD Candidate in Remote Sensing",links:[{icon:"github",link:"https://github.com/felixcremer"}]},{avatar:"https://avatars.githubusercontent.com/u/2534009?v=4",name:"Rafael Schouten",title:"Spatial/ecological modelling",links:[{icon:"github",link:"https://github.com/rafaqz"}]},{avatar:"https://avatars.githubusercontent.com/u/19525261?v=4",name:"Lazaro Alonso",title:"Scientist. Data Visualization",links:[{icon:"github",link:"https://github.com/lazarusA"},{icon:"x",link:"https://twitter.com/LazarusAlon"},{icon:"linkedin",link:"https://www.linkedin.com/in/lazaro-alonso/"},{icon:"mastodon",link:"https://julialang.social/@LazaroAlonso"}]}];return(d,a)=>{const i=h("font");return b(),c("div",null,[r(n(g),null,{default:s(()=>[r(n(u),null,{title:s(()=>a[0]||(a[0]=[e("Contributors")])),lead:s(()=>[a[8]||(a[8]=t("strong",null,"Current core contributors ",-1)),a[9]||(a[9]=e()),a[10]||(a[10]=t("br",null,null,-1)),t("div",p,[a[4]||(a[4]=e(" They have taking the lead for the ongoing organizational maintenance and technical direction of ")),r(i,{color:"orange"},{default:s(()=>a[1]||(a[1]=[e("YAXArrays.jl")])),_:1}),a[5]||(a[5]=e(", ")),r(i,{color:"orange"},{default:s(()=>a[2]||(a[2]=[e("DiskArrays.jl")])),_:1}),a[6]||(a[6]=e(" and ")),r(i,{color:"orange"},{default:s(()=>a[3]||(a[3]=[e("DimensionalData.jl")])),_:1}),a[7]||(a[7]=e(". "))])]),_:1}),r(n(l),{size:"small",members:o}),r(n(m),null,{title:s(()=>a[11]||(a[11]=[e("Our valuable contributors")])),lead:s(()=>a[12]||(a[12]=[e(" We appreciate all contributions from the Julia community so that this ecosystem can thrive."),t("br",null,null,-1)])),members:s(()=>a[13]||(a[13]=[t("div",{class:"row"},[t("a",{href:"https://github.com/meggart",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/2539563?v=4"})]),t("a",{href:"https://github.com/felixcremer",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/17124431?v=4"})]),t("a",{href:"https://github.com/lazarusA",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/19525261?v=4"})]),t("a",{href:"https://github.com/gdkrmr",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/12512930?v=4"})]),t("a",{href:"https://github.com/apps/github-actions",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/in/15368?v=4"})]),t("a",{href:"https://github.com/pdimens",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/19176506?v=4"})]),t("a",{href:"https://github.com/twinGu",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/29449917?v=4"})]),t("a",{href:"https://github.com/dpabon",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/13040959?v=4"})]),t("a",{href:"https://github.com/Qfl3x",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/20775896?v=4"})]),t("a",{href:"https://github.com/kongdd",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/9815742?v=4"})]),t("a",{href:"https://github.com/MartinuzziFrancesco",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/10376688?v=4"})]),t("a",{href:"https://github.com/Sonicious",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/16307399?v=4"})]),t("a",{href:"https://github.com/rafaqz",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/2534009?v=4"})]),t("a",{href:"https://github.com/danlooo",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/5780565?v=4"})]),t("a",{href:"https://github.com/MarkusZehner",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/56972144?v=4"})]),t("a",{href:"https://github.com/Balinus",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/3630311?v=4"})]),t("a",{href:"https://github.com/singularitti",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/25192197?v=4"})]),t("a",{href:"https://github.com/ckrich",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/28727495?v=4"})]),t("a",{href:"https://github.com/apps/femtocleaner",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/in/4123?v=4"})]),t("a",{href:"https://github.com/ikselven",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/10441332?v=4"})]),t("a",{href:"https://github.com/linamaes",target:"_blank"},[t("img",{src:"https://avatars.githubusercontent.com/u/7131773?v=4"})])],-1)])),_:1})]),_:1})])}}});export{z as __pageData,j as default}; diff --git a/previews/PR437/assets/get_started.md.Bry90ck5.js b/previews/PR437/assets/get_started.md.Bry90ck5.js new file mode 100644 index 00000000..23e848a0 --- /dev/null +++ b/previews/PR437/assets/get_started.md.Bry90ck5.js @@ -0,0 +1,56 @@ +import{_ as a,c as i,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"get_started.md","filePath":"get_started.md","lastUpdated":null}'),p={name:"get_started.md"};function l(e,s,h,k,r,d){return t(),i("div",null,s[0]||(s[0]=[n(`

Getting Started

Installation

Install Julia v1.10 or above. YAXArrays.jl is available through the Julia package manager. You can enter it by pressing ] in the REPL and then typing

julia
pkg> add YAXArrays

Alternatively, you can also do

julia
import Pkg; Pkg.add("YAXArrays")

Quickstart

Create a simple array from random numbers given the size of each dimension or axis:

julia
using YAXArrays
+
+a = YAXArray(rand(2,3))
╭─────────────────────────╮
+│ 2×3 YAXArray{Float64,2} │
+├─────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(3) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 48.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Assemble a more complex YAXArray with 4 dimensions, i.e. time, x, y and a variable type:

julia
using DimensionalData
+
+# axes or dimensions with name and tick values
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    X(range(1, 10, length=10)),
+    Y(range(1, 5, length=15)),
+    Dim{:variable}(["temperature", "precipitation"])
+)
+
+# the actual data matching the dimensions defined in axlist
+data = rand(20, 10, 15, 2)
+
+# metadata about the array
+props = Dict(
+    "origin" => "YAXArrays.jl example",
+    "x" => "longitude",
+    "y" => "latitude",
+);
+
+a2 = YAXArray(axlist, data, props)
╭────────────────────────────────╮
+│ 20×10×15×2 YAXArray{Float64,4} │
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+  ↓ time     Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+  → X        Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ Y        Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+  ⬔ variable Categorical{String} ["temperature", "precipitation"] ReverseOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, String} with 3 entries:
+  "y"      => "latitude"
+  "x"      => "longitude"
+  "origin" => "YAXArrays.jl example"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Get the temperature map at the first point in time:

julia
a2[variable=At("temperature"), time=1].data
10×15 view(::Array{Float64, 4}, 1, :, :, 1) with eltype Float64:
+ 0.0462624  0.541399  0.884596  0.466542   …  0.433215  0.39914    0.253557
+ 0.424205   0.783796  0.186312  0.698795      0.621626  0.0845415  0.397222
+ 0.649498   0.861755  0.272109  0.137422      0.104073  0.834933   0.708253
+ 0.342288   0.723246  0.267431  0.71243       0.358337  0.091767   0.93618
+ 0.165788   0.198967  0.239879  0.138996      0.409423  0.263174   0.213509
+ 0.921833   0.171584  0.565253  0.178559   …  0.27394   0.291786   0.358056
+ 0.451794   0.538223  0.840426  0.210596      0.56083   0.324527   0.712428
+ 0.788957   0.695756  0.291145  0.682179      0.152689  0.925986   0.138529
+ 0.800129   0.773651  0.400935  0.249043      0.75783   0.9316     0.985469
+ 0.350231   0.122751  0.497997  0.0720417     0.290209  0.344472   0.776623

Updates

TIP

The Julia Compiler is always improving. As such, we recommend using the latest stable version of Julia.

You may check the installed version with:

julia
pkg> st YAXArrays

INFO

With YAXArrays.jl 0.5 we switched the underlying data type to be a subtype of the DimensionalData.jl types. Therefore the indexing with named dimensions changed to the DimensionalData syntax. See the DimensionalData.jl docs.

`,21)]))}const E=a(p,[["render",l]]);export{g as __pageData,E as default}; diff --git a/previews/PR437/assets/get_started.md.Bry90ck5.lean.js b/previews/PR437/assets/get_started.md.Bry90ck5.lean.js new file mode 100644 index 00000000..23e848a0 --- /dev/null +++ b/previews/PR437/assets/get_started.md.Bry90ck5.lean.js @@ -0,0 +1,56 @@ +import{_ as a,c as i,a2 as n,o as t}from"./chunks/framework.BxolPc_T.js";const g=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"get_started.md","filePath":"get_started.md","lastUpdated":null}'),p={name:"get_started.md"};function l(e,s,h,k,r,d){return t(),i("div",null,s[0]||(s[0]=[n(`

Getting Started

Installation

Install Julia v1.10 or above. YAXArrays.jl is available through the Julia package manager. You can enter it by pressing ] in the REPL and then typing

julia
pkg> add YAXArrays

Alternatively, you can also do

julia
import Pkg; Pkg.add("YAXArrays")

Quickstart

Create a simple array from random numbers given the size of each dimension or axis:

julia
using YAXArrays
+
+a = YAXArray(rand(2,3))
╭─────────────────────────╮
+│ 2×3 YAXArray{Float64,2} │
+├─────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(3) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 48.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Assemble a more complex YAXArray with 4 dimensions, i.e. time, x, y and a variable type:

julia
using DimensionalData
+
+# axes or dimensions with name and tick values
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    X(range(1, 10, length=10)),
+    Y(range(1, 5, length=15)),
+    Dim{:variable}(["temperature", "precipitation"])
+)
+
+# the actual data matching the dimensions defined in axlist
+data = rand(20, 10, 15, 2)
+
+# metadata about the array
+props = Dict(
+    "origin" => "YAXArrays.jl example",
+    "x" => "longitude",
+    "y" => "latitude",
+);
+
+a2 = YAXArray(axlist, data, props)
╭────────────────────────────────╮
+│ 20×10×15×2 YAXArray{Float64,4} │
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+  ↓ time     Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+  → X        Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ Y        Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+  ⬔ variable Categorical{String} ["temperature", "precipitation"] ReverseOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, String} with 3 entries:
+  "y"      => "latitude"
+  "x"      => "longitude"
+  "origin" => "YAXArrays.jl example"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Get the temperature map at the first point in time:

julia
a2[variable=At("temperature"), time=1].data
10×15 view(::Array{Float64, 4}, 1, :, :, 1) with eltype Float64:
+ 0.0462624  0.541399  0.884596  0.466542   …  0.433215  0.39914    0.253557
+ 0.424205   0.783796  0.186312  0.698795      0.621626  0.0845415  0.397222
+ 0.649498   0.861755  0.272109  0.137422      0.104073  0.834933   0.708253
+ 0.342288   0.723246  0.267431  0.71243       0.358337  0.091767   0.93618
+ 0.165788   0.198967  0.239879  0.138996      0.409423  0.263174   0.213509
+ 0.921833   0.171584  0.565253  0.178559   …  0.27394   0.291786   0.358056
+ 0.451794   0.538223  0.840426  0.210596      0.56083   0.324527   0.712428
+ 0.788957   0.695756  0.291145  0.682179      0.152689  0.925986   0.138529
+ 0.800129   0.773651  0.400935  0.249043      0.75783   0.9316     0.985469
+ 0.350231   0.122751  0.497997  0.0720417     0.290209  0.344472   0.776623

Updates

TIP

The Julia Compiler is always improving. As such, we recommend using the latest stable version of Julia.

You may check the installed version with:

julia
pkg> st YAXArrays

INFO

With YAXArrays.jl 0.5 we switched the underlying data type to be a subtype of the DimensionalData.jl types. Therefore the indexing with named dimensions changed to the DimensionalData syntax. See the DimensionalData.jl docs.

`,21)]))}const E=a(p,[["render",l]]);export{g as __pageData,E as default}; diff --git a/previews/PR437/assets/index.md.BUnK4bB7.js b/previews/PR437/assets/index.md.BUnK4bB7.js new file mode 100644 index 00000000..35777ebb --- /dev/null +++ b/previews/PR437/assets/index.md.BUnK4bB7.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.BxolPc_T.js";const f=JSON.parse(`{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"YAXArrays.jl","text":"Yet another xarray-like Julia package","tagline":"A package for operating on out-of-core labeled arrays, based on stores like NetCDF, Zarr or GDAL.","image":{"src":"/logo.png","alt":"VitePress"},"actions":[{"theme":"brand","text":"Get Started","link":"/get_started"},{"theme":"alt","text":"View on Github","link":"https://github.com/JuliaDataCubes/YAXArrays.jl"},{"theme":"alt","text":"API reference","link":"/api"}]},"features":[{"title":"Flexible I/O capabilities","details":"Open and operate on NetCDF and Zarr datasets directly. Or bring in data from other sources with ArchGDAL.jl, GRIBDatasets.jl, GeoJSON.jl, HDF5.jl, Shapefile.jl, GeoParquet.jl, etc.","link":"/UserGuide/read"},{"title":"Interoperability","details":"Well integrated with Julia's ecosystem, i.e., distributed operations are native. And plotting with Makie.jl is well supported."},{"title":"Named dimensions and GroupBy(in memory)","details":"Apply operations over named dimensions, select values by labels and integers as well as efficient split-apply-combine operations with groupby via DimensionalData.jl.","link":"/UserGuide/group"},{"title":"Efficiency","details":"Efficient mapslices(x) and mapCube operations on huge multiple arrays, optimized for high-latency data access (object storage, compressed datasets).","link":"/UserGuide/compute"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}`),o={name:"index.md"};function i(r,n,l,s,d,c){return a(),t("div")}const m=e(o,[["render",i]]);export{f as __pageData,m as default}; diff --git a/previews/PR437/assets/index.md.BUnK4bB7.lean.js b/previews/PR437/assets/index.md.BUnK4bB7.lean.js new file mode 100644 index 00000000..35777ebb --- /dev/null +++ b/previews/PR437/assets/index.md.BUnK4bB7.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.BxolPc_T.js";const f=JSON.parse(`{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"YAXArrays.jl","text":"Yet another xarray-like Julia package","tagline":"A package for operating on out-of-core labeled arrays, based on stores like NetCDF, Zarr or GDAL.","image":{"src":"/logo.png","alt":"VitePress"},"actions":[{"theme":"brand","text":"Get Started","link":"/get_started"},{"theme":"alt","text":"View on Github","link":"https://github.com/JuliaDataCubes/YAXArrays.jl"},{"theme":"alt","text":"API reference","link":"/api"}]},"features":[{"title":"Flexible I/O capabilities","details":"Open and operate on NetCDF and Zarr datasets directly. Or bring in data from other sources with ArchGDAL.jl, GRIBDatasets.jl, GeoJSON.jl, HDF5.jl, Shapefile.jl, GeoParquet.jl, etc.","link":"/UserGuide/read"},{"title":"Interoperability","details":"Well integrated with Julia's ecosystem, i.e., distributed operations are native. And plotting with Makie.jl is well supported."},{"title":"Named dimensions and GroupBy(in memory)","details":"Apply operations over named dimensions, select values by labels and integers as well as efficient split-apply-combine operations with groupby via DimensionalData.jl.","link":"/UserGuide/group"},{"title":"Efficiency","details":"Efficient mapslices(x) and mapCube operations on huge multiple arrays, optimized for high-latency data access (object storage, compressed datasets).","link":"/UserGuide/compute"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}`),o={name:"index.md"};function i(r,n,l,s,d,c){return a(),t("div")}const m=e(o,[["render",i]]);export{f as __pageData,m as default}; diff --git a/previews/PR437/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 b/previews/PR437/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 new file mode 100644 index 00000000..b6b603d5 Binary files /dev/null and b/previews/PR437/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 differ diff --git a/previews/PR437/assets/inter-italic-cyrillic.By2_1cv3.woff2 b/previews/PR437/assets/inter-italic-cyrillic.By2_1cv3.woff2 new file mode 100644 index 00000000..def40a4f Binary files /dev/null and b/previews/PR437/assets/inter-italic-cyrillic.By2_1cv3.woff2 differ diff --git a/previews/PR437/assets/inter-italic-greek-ext.1u6EdAuj.woff2 b/previews/PR437/assets/inter-italic-greek-ext.1u6EdAuj.woff2 new file mode 100644 index 00000000..e070c3d3 Binary files /dev/null and b/previews/PR437/assets/inter-italic-greek-ext.1u6EdAuj.woff2 differ diff --git a/previews/PR437/assets/inter-italic-greek.DJ8dCoTZ.woff2 b/previews/PR437/assets/inter-italic-greek.DJ8dCoTZ.woff2 new file mode 100644 index 00000000..a3c16ca4 Binary files /dev/null and b/previews/PR437/assets/inter-italic-greek.DJ8dCoTZ.woff2 differ diff --git a/previews/PR437/assets/inter-italic-latin-ext.CN1xVJS-.woff2 b/previews/PR437/assets/inter-italic-latin-ext.CN1xVJS-.woff2 new file mode 100644 index 00000000..2210a899 Binary files /dev/null and b/previews/PR437/assets/inter-italic-latin-ext.CN1xVJS-.woff2 differ diff --git a/previews/PR437/assets/inter-italic-latin.C2AdPX0b.woff2 b/previews/PR437/assets/inter-italic-latin.C2AdPX0b.woff2 new file mode 100644 index 00000000..790d62dc Binary files /dev/null and b/previews/PR437/assets/inter-italic-latin.C2AdPX0b.woff2 differ diff --git a/previews/PR437/assets/inter-italic-vietnamese.BSbpV94h.woff2 b/previews/PR437/assets/inter-italic-vietnamese.BSbpV94h.woff2 new file mode 100644 index 00000000..1eec0775 Binary files /dev/null and b/previews/PR437/assets/inter-italic-vietnamese.BSbpV94h.woff2 differ diff --git a/previews/PR437/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 b/previews/PR437/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 new file mode 100644 index 00000000..2cfe6153 Binary files /dev/null and b/previews/PR437/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 differ diff --git a/previews/PR437/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 b/previews/PR437/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 new file mode 100644 index 00000000..e3886dd1 Binary files /dev/null and b/previews/PR437/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 differ diff --git a/previews/PR437/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 b/previews/PR437/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 new file mode 100644 index 00000000..36d67487 Binary files /dev/null and b/previews/PR437/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 differ diff --git a/previews/PR437/assets/inter-roman-greek.BBVDIX6e.woff2 b/previews/PR437/assets/inter-roman-greek.BBVDIX6e.woff2 new file mode 100644 index 00000000..2bed1e85 Binary files /dev/null and b/previews/PR437/assets/inter-roman-greek.BBVDIX6e.woff2 differ diff --git a/previews/PR437/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 b/previews/PR437/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 new file mode 100644 index 00000000..9a8d1e2b Binary files /dev/null and b/previews/PR437/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 differ diff --git a/previews/PR437/assets/inter-roman-latin.Di8DUHzh.woff2 b/previews/PR437/assets/inter-roman-latin.Di8DUHzh.woff2 new file mode 100644 index 00000000..07d3c53a Binary files /dev/null and b/previews/PR437/assets/inter-roman-latin.Di8DUHzh.woff2 differ diff --git a/previews/PR437/assets/inter-roman-vietnamese.BjW4sHH5.woff2 b/previews/PR437/assets/inter-roman-vietnamese.BjW4sHH5.woff2 new file mode 100644 index 00000000..57bdc22a Binary files /dev/null and b/previews/PR437/assets/inter-roman-vietnamese.BjW4sHH5.woff2 differ diff --git a/previews/PR437/assets/jtwtgjr.96k_BqPR.jpeg b/previews/PR437/assets/jtwtgjr.96k_BqPR.jpeg new file mode 100644 index 00000000..c10e4016 Binary files /dev/null and b/previews/PR437/assets/jtwtgjr.96k_BqPR.jpeg differ diff --git a/previews/PR437/assets/okmnbox.CBBZcGwj.png b/previews/PR437/assets/okmnbox.CBBZcGwj.png new file mode 100644 index 00000000..a32b49ed Binary files /dev/null and b/previews/PR437/assets/okmnbox.CBBZcGwj.png differ diff --git a/previews/PR437/assets/palueig.xrZxBsPv.jpeg b/previews/PR437/assets/palueig.xrZxBsPv.jpeg new file mode 100644 index 00000000..3a5ea565 Binary files /dev/null and b/previews/PR437/assets/palueig.xrZxBsPv.jpeg differ diff --git a/previews/PR437/assets/style.DagAZRcD.css b/previews/PR437/assets/style.DagAZRcD.css new file mode 100644 index 00000000..c0b41614 --- /dev/null +++ b/previews/PR437/assets/style.DagAZRcD.css @@ -0,0 +1 @@ +@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/YAXArrays.jl/previews/PR437/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Heiti SC", "Microsoft YaHei", "DengXian", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{overflow-x:auto}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.vpi-social-discord{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z'/%3E%3C/svg%3E")}.vpi-social-facebook{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z'/%3E%3C/svg%3E")}.vpi-social-github{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-instagram{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.03.084c-1.277.06-2.149.264-2.91.563a5.874 5.874 0 0 0-2.124 1.388 5.878 5.878 0 0 0-1.38 2.127C.321 4.926.12 5.8.064 7.076.008 8.354-.005 8.764.001 12.023c.007 3.259.021 3.667.083 4.947.061 1.277.264 2.149.563 2.911.308.789.72 1.457 1.388 2.123a5.872 5.872 0 0 0 2.129 1.38c.763.295 1.636.496 2.913.552 1.278.056 1.689.069 4.947.063 3.257-.007 3.668-.021 4.947-.082 1.28-.06 2.147-.265 2.91-.563a5.881 5.881 0 0 0 2.123-1.388 5.881 5.881 0 0 0 1.38-2.129c.295-.763.496-1.636.551-2.912.056-1.28.07-1.69.063-4.948-.006-3.258-.02-3.667-.081-4.947-.06-1.28-.264-2.148-.564-2.911a5.892 5.892 0 0 0-1.387-2.123 5.857 5.857 0 0 0-2.128-1.38C19.074.322 18.202.12 16.924.066 15.647.009 15.236-.006 11.977 0 8.718.008 8.31.021 7.03.084m.14 21.693c-1.17-.05-1.805-.245-2.228-.408a3.736 3.736 0 0 1-1.382-.895 3.695 3.695 0 0 1-.9-1.378c-.165-.423-.363-1.058-.417-2.228-.06-1.264-.072-1.644-.08-4.848-.006-3.204.006-3.583.061-4.848.05-1.169.246-1.805.408-2.228.216-.561.477-.96.895-1.382a3.705 3.705 0 0 1 1.379-.9c.423-.165 1.057-.361 2.227-.417 1.265-.06 1.644-.072 4.848-.08 3.203-.006 3.583.006 4.85.062 1.168.05 1.804.244 2.227.408.56.216.96.475 1.382.895.421.42.681.817.9 1.378.165.422.362 1.056.417 2.227.06 1.265.074 1.645.08 4.848.005 3.203-.006 3.583-.061 4.848-.051 1.17-.245 1.805-.408 2.23-.216.56-.477.96-.896 1.38a3.705 3.705 0 0 1-1.378.9c-.422.165-1.058.362-2.226.418-1.266.06-1.645.072-4.85.079-3.204.007-3.582-.006-4.848-.06m9.783-16.192a1.44 1.44 0 1 0 1.437-1.442 1.44 1.44 0 0 0-1.437 1.442M5.839 12.012a6.161 6.161 0 1 0 12.323-.024 6.162 6.162 0 0 0-12.323.024M8 12.008A4 4 0 1 1 12.008 16 4 4 0 0 1 8 12.008'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E")}.vpi-social-mastodon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E")}.vpi-social-npm{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z'/%3E%3C/svg%3E")}.vpi-social-slack{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z'/%3E%3C/svg%3E")}.vpi-social-twitter,.vpi-social-x{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E")}.vpi-social-youtube{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc h4{margin:24px 0 0;letter-spacing:-.01em;line-height:24px;font-size:18px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s;color:var(--vp-c-text-2)}.vp-doc blockquote>p{margin:0;font-size:16px;transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code,.vp-doc h4>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-b06cdb19]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-b06cdb19],.VPBackdrop.fade-leave-to[data-v-b06cdb19]{opacity:0}.VPBackdrop.fade-leave-active[data-v-b06cdb19]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-b06cdb19]{display:none}}.NotFound[data-v-951cab6c]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-951cab6c]{padding:96px 32px 168px}}.code[data-v-951cab6c]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-951cab6c]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-951cab6c]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-951cab6c]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-951cab6c]{padding-top:20px}.link[data-v-951cab6c]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-951cab6c]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-3f927ebe]{position:relative;z-index:1}.nested[data-v-3f927ebe]{padding-right:16px;padding-left:16px}.outline-link[data-v-3f927ebe]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-3f927ebe]:hover,.outline-link.active[data-v-3f927ebe]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-3f927ebe]{padding-left:13px}.VPDocAsideOutline[data-v-b38bf2ff]{display:none}.VPDocAsideOutline.has-outline[data-v-b38bf2ff]{display:block}.content[data-v-b38bf2ff]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-b38bf2ff]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-b38bf2ff]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-6d7b3c46]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-6d7b3c46]{flex-grow:1}.VPDocAside[data-v-6d7b3c46] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-6d7b3c46] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-6d7b3c46] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-475f71b8]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-475f71b8]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-4f9813fa]{margin-top:64px}.edit-info[data-v-4f9813fa]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-4f9813fa]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-4f9813fa]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-4f9813fa]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-4f9813fa]{margin-right:8px}.prev-next[data-v-4f9813fa]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-4f9813fa]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-4f9813fa]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-4f9813fa]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-4f9813fa]{margin-left:auto;text-align:right}.desc[data-v-4f9813fa]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-4f9813fa]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-83890dd9]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-83890dd9]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-83890dd9]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-83890dd9]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-83890dd9]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-83890dd9]{display:flex;justify-content:center}.VPDoc .aside[data-v-83890dd9]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-83890dd9]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-83890dd9]{max-width:1104px}}.container[data-v-83890dd9]{margin:0 auto;width:100%}.aside[data-v-83890dd9]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-83890dd9]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-83890dd9]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-83890dd9]::-webkit-scrollbar{display:none}.aside-curtain[data-v-83890dd9]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-83890dd9]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-83890dd9]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-83890dd9]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-83890dd9]{order:1;margin:0;min-width:640px}}.content-container[data-v-83890dd9]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-83890dd9]{max-width:688px}.VPButton[data-v-14206e74]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-14206e74]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-14206e74]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-14206e74]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-14206e74]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-14206e74]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-14206e74]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-14206e74]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-14206e74]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-14206e74]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-14206e74]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-14206e74]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-14206e74]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-35a7d0b8]{display:none}.dark .VPImage.light[data-v-35a7d0b8]{display:none}.VPHero[data-v-955009fc]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-955009fc]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-955009fc]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-955009fc]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-955009fc]{flex-direction:row}}.main[data-v-955009fc]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-955009fc]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-955009fc]{text-align:left}}@media (min-width: 960px){.main[data-v-955009fc]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-955009fc]{max-width:592px}}.name[data-v-955009fc],.text[data-v-955009fc]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-955009fc],.VPHero.has-image .text[data-v-955009fc]{margin:0 auto}.name[data-v-955009fc]{color:var(--vp-home-hero-name-color)}.clip[data-v-955009fc]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-955009fc],.text[data-v-955009fc]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-955009fc],.text[data-v-955009fc]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-955009fc],.VPHero.has-image .text[data-v-955009fc]{margin:0}}.tagline[data-v-955009fc]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-955009fc]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-955009fc]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-955009fc]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-955009fc]{margin:0}}.actions[data-v-955009fc]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-955009fc]{justify-content:center}@media (min-width: 640px){.actions[data-v-955009fc]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-955009fc]{justify-content:flex-start}}.action[data-v-955009fc]{flex-shrink:0;padding:6px}.image[data-v-955009fc]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-955009fc]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-955009fc]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-955009fc]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-955009fc]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-955009fc]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-955009fc]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-955009fc]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-955009fc]{width:320px;height:320px}}[data-v-955009fc] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-955009fc] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-955009fc] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-f5e9645b]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-f5e9645b]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-f5e9645b]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-f5e9645b]>.VPImage{margin-bottom:20px}.icon[data-v-f5e9645b]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-f5e9645b]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-f5e9645b]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-f5e9645b]{padding-top:8px}.link-text-value[data-v-f5e9645b]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-f5e9645b]{margin-left:6px}.VPFeatures[data-v-d0a190d7]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-d0a190d7]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-d0a190d7]{padding:0 64px}}.container[data-v-d0a190d7]{margin:0 auto;max-width:1152px}.items[data-v-d0a190d7]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-d0a190d7]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-d0a190d7],.item.grid-4[data-v-d0a190d7],.item.grid-6[data-v-d0a190d7]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-d0a190d7],.item.grid-4[data-v-d0a190d7]{width:50%}.item.grid-3[data-v-d0a190d7],.item.grid-6[data-v-d0a190d7]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-d0a190d7]{width:25%}}.container[data-v-7a48a447]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-7a48a447]{padding:0 48px}}@media (min-width: 960px){.container[data-v-7a48a447]{width:100%;padding:0 64px}}.vp-doc[data-v-7a48a447] .VPHomeSponsors,.vp-doc[data-v-7a48a447] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-7a48a447] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-7a48a447] .VPHomeSponsors a,.vp-doc[data-v-7a48a447] .VPTeamPage a{text-decoration:none}.VPHome[data-v-cbb6ec48]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-cbb6ec48]{margin-bottom:128px}}.VPContent[data-v-91765379]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-91765379]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-91765379]{margin:0}@media (min-width: 960px){.VPContent[data-v-91765379]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-91765379]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-91765379]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-c970a860]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-c970a860]{display:none}.VPFooter[data-v-c970a860] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-c970a860] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-c970a860]{padding:32px}}.container[data-v-c970a860]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-c970a860],.copyright[data-v-c970a860]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-bc9dc845]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-bc9dc845]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-bc9dc845]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-bc9dc845]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-bc9dc845]{color:var(--vp-c-text-1)}.icon[data-v-bc9dc845]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-bc9dc845]{font-size:14px}.icon[data-v-bc9dc845]{font-size:16px}}.open>.icon[data-v-bc9dc845]{transform:rotate(90deg)}.items[data-v-bc9dc845]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-bc9dc845]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-bc9dc845]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-bc9dc845]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-bc9dc845]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-bc9dc845]{transition:all .2s ease-out}.flyout-leave-active[data-v-bc9dc845]{transition:all .15s ease-in}.flyout-enter-from[data-v-bc9dc845],.flyout-leave-to[data-v-bc9dc845]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-070ab83d]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-070ab83d]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-070ab83d]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-070ab83d]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-070ab83d]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-070ab83d]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-070ab83d]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-070ab83d]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-070ab83d]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-070ab83d]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-070ab83d]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-070ab83d]{display:none}}.menu-icon[data-v-070ab83d]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-070ab83d]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-070ab83d]{padding:12px 32px 11px}}.VPSwitch[data-v-4a1c76db]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-4a1c76db]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-4a1c76db]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-4a1c76db]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-4a1c76db] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-4a1c76db] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-e40a8bb6]{opacity:1}.moon[data-v-e40a8bb6],.dark .sun[data-v-e40a8bb6]{opacity:0}.dark .moon[data-v-e40a8bb6]{opacity:1}.dark .VPSwitchAppearance[data-v-e40a8bb6] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-af096f4a]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-af096f4a]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-8b74d055]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-8b74d055]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-8b74d055]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-8b74d055]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-48c802d0]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-48c802d0]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-48c802d0]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-48c802d0]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-7dd3104a]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-7dd3104a] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-7dd3104a] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-7dd3104a] .group:last-child{padding-bottom:0}.VPMenu[data-v-7dd3104a] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-7dd3104a] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-7dd3104a] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-7dd3104a] .action{padding-left:24px}.VPFlyout[data-v-e5380155]{position:relative}.VPFlyout[data-v-e5380155]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-e5380155]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-e5380155]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-e5380155]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-e5380155]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-e5380155],.button[aria-expanded=true]+.menu[data-v-e5380155]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-e5380155]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-e5380155]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-e5380155]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-e5380155]{margin-right:0;font-size:16px}.text-icon[data-v-e5380155]{margin-left:4px;font-size:14px}.icon[data-v-e5380155]{font-size:20px;transition:fill .25s}.menu[data-v-e5380155]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-717b8b75]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-717b8b75]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-717b8b75]>svg,.VPSocialLink[data-v-717b8b75]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-ee7a9424]{display:flex;justify-content:center}.VPNavBarExtra[data-v-925effce]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-925effce]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-925effce]{display:none}}.trans-title[data-v-925effce]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-925effce],.item.social-links[data-v-925effce]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-925effce]{min-width:176px}.appearance-action[data-v-925effce]{margin-right:-2px}.social-links-list[data-v-925effce]{margin:-4px -8px}.VPNavBarHamburger[data-v-5dea55bf]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-5dea55bf]{display:none}}.container[data-v-5dea55bf]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-5dea55bf]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-5dea55bf]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-5dea55bf]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-5dea55bf]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-5dea55bf]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-5dea55bf]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-5dea55bf],.VPNavBarHamburger.active:hover .middle[data-v-5dea55bf],.VPNavBarHamburger.active:hover .bottom[data-v-5dea55bf]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-5dea55bf],.middle[data-v-5dea55bf],.bottom[data-v-5dea55bf]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-5dea55bf]{top:0;left:0;transform:translate(0)}.middle[data-v-5dea55bf]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-5dea55bf]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-ed5ac1f6]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-ed5ac1f6],.VPNavBarMenuLink[data-v-ed5ac1f6]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-e6d46098]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-e6d46098]{display:flex}}/*! @docsearch/css 3.6.1 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-164c457f]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-164c457f]{display:flex;align-items:center}}.title[data-v-28a961f9]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-28a961f9]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-28a961f9]{border-bottom-color:var(--vp-c-divider)}}[data-v-28a961f9] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-c80d9ad0]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-c80d9ad0]{display:flex;align-items:center}}.title[data-v-c80d9ad0]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-822684d1]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .25s}.VPNavBar.screen-open[data-v-822684d1]{transition:none;background-color:var(--vp-nav-bg-color);border-bottom:1px solid var(--vp-c-divider)}.VPNavBar[data-v-822684d1]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-822684d1]:not(.home){background-color:transparent}.VPNavBar[data-v-822684d1]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-822684d1]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-822684d1]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-822684d1]{padding:0}}.container[data-v-822684d1]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-822684d1],.container>.content[data-v-822684d1]{pointer-events:none}.container[data-v-822684d1] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-822684d1]{max-width:100%}}.title[data-v-822684d1]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-822684d1]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-822684d1]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-822684d1]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-822684d1]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-822684d1]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-822684d1]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-822684d1]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-822684d1]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-822684d1]{column-gap:.5rem}}.menu+.translations[data-v-822684d1]:before,.menu+.appearance[data-v-822684d1]:before,.menu+.social-links[data-v-822684d1]:before,.translations+.appearance[data-v-822684d1]:before,.appearance+.social-links[data-v-822684d1]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-822684d1]:before,.translations+.appearance[data-v-822684d1]:before{margin-right:16px}.appearance+.social-links[data-v-822684d1]:before{margin-left:16px}.social-links[data-v-822684d1]{margin-right:-8px}.divider[data-v-822684d1]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-822684d1]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-822684d1]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-822684d1]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-822684d1]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-822684d1]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-822684d1]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-ffb44008]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-ffb44008]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-27d04aeb]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-27d04aeb]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-7179dbb7]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-7179dbb7]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-4b8941ac]{display:block}.title[data-v-4b8941ac]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-875057a5]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-875057a5]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-875057a5]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-875057a5]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-875057a5]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-875057a5]{transform:rotate(45deg)}.button[data-v-875057a5]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-875057a5]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-875057a5]{transition:transform .25s}.group[data-v-875057a5]:first-child{padding-top:0}.group+.group[data-v-875057a5],.group+.item[data-v-875057a5]{padding-top:4px}.VPNavScreenTranslations[data-v-362991c2]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-362991c2]{height:auto}.title[data-v-362991c2]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-362991c2]{font-size:16px}.icon.lang[data-v-362991c2]{margin-right:8px}.icon.chevron[data-v-362991c2]{margin-left:4px}.list[data-v-362991c2]{padding:4px 0 0 24px}.link[data-v-362991c2]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-833aabba]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .25s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-833aabba],.VPNavScreen.fade-leave-active[data-v-833aabba]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-833aabba],.VPNavScreen.fade-leave-active .container[data-v-833aabba]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-833aabba],.VPNavScreen.fade-leave-to[data-v-833aabba]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-833aabba],.VPNavScreen.fade-leave-to .container[data-v-833aabba]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-833aabba]{display:none}}.container[data-v-833aabba]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-833aabba],.menu+.appearance[data-v-833aabba],.translations+.appearance[data-v-833aabba]{margin-top:24px}.menu+.social-links[data-v-833aabba]{margin-top:16px}.appearance+.social-links[data-v-833aabba]{margin-top:16px}.VPNav[data-v-f1e365da]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-f1e365da]{position:fixed}}.VPSidebarItem.level-0[data-v-196b2e5f]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-196b2e5f]{padding-bottom:10px}.item[data-v-196b2e5f]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-196b2e5f]{cursor:pointer}.indicator[data-v-196b2e5f]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-196b2e5f],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-196b2e5f],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-196b2e5f],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-196b2e5f]{background-color:var(--vp-c-brand-1)}.link[data-v-196b2e5f]{display:flex;align-items:center;flex-grow:1}.text[data-v-196b2e5f]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-196b2e5f]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-196b2e5f],.VPSidebarItem.level-2 .text[data-v-196b2e5f],.VPSidebarItem.level-3 .text[data-v-196b2e5f],.VPSidebarItem.level-4 .text[data-v-196b2e5f],.VPSidebarItem.level-5 .text[data-v-196b2e5f]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-196b2e5f],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-196b2e5f],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-196b2e5f],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-196b2e5f],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-196b2e5f],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-196b2e5f]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-1.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-2.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-3.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-4.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-5.has-active>.item>.text[data-v-196b2e5f],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-196b2e5f],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-196b2e5f],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-196b2e5f],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-196b2e5f],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-196b2e5f],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-196b2e5f]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-196b2e5f],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-196b2e5f],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-196b2e5f],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-196b2e5f],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-196b2e5f],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-196b2e5f]{color:var(--vp-c-brand-1)}.caret[data-v-196b2e5f]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-196b2e5f]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-196b2e5f]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-196b2e5f]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-196b2e5f]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-196b2e5f],.VPSidebarItem.level-2 .items[data-v-196b2e5f],.VPSidebarItem.level-3 .items[data-v-196b2e5f],.VPSidebarItem.level-4 .items[data-v-196b2e5f],.VPSidebarItem.level-5 .items[data-v-196b2e5f]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-196b2e5f]{display:none}.no-transition[data-v-9e426adc] .caret-icon{transition:none}.group+.group[data-v-9e426adc]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-9e426adc]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSidebar[data-v-18756405]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-18756405]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-18756405]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-18756405]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-18756405]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-18756405]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-18756405]{outline:0}.VPSkipLink[data-v-c3508ec8]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-c3508ec8]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-c3508ec8]{top:14px;left:16px}}.Layout[data-v-a9a9e638]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-db81191c]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-db81191c]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-db81191c]{margin:128px 0}}.VPHomeSponsors[data-v-db81191c]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-db81191c]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-db81191c]{padding:0 64px}}.container[data-v-db81191c]{margin:0 auto;max-width:1152px}.love[data-v-db81191c]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-db81191c]{display:inline-block}.message[data-v-db81191c]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-db81191c]{padding-top:32px}.action[data-v-db81191c]{padding-top:40px;text-align:center}.VPTeamPage[data-v-c2f8e101]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-c2f8e101]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-c2f8e101-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-c2f8e101-s],.VPTeamMembers+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-c2f8e101-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-c2f8e101-s],.VPTeamMembers+.VPTeamPageSection[data-v-c2f8e101-s]{margin-top:96px}}.VPTeamMembers[data-v-c2f8e101-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-c2f8e101-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-c2f8e101-s]{padding:0 64px}}.VPTeamPageTitle[data-v-e277e15c]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-e277e15c]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-e277e15c]{padding:80px 64px 48px}}.title[data-v-e277e15c]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-e277e15c]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-e277e15c]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-e277e15c]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-d43bc49d]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-d43bc49d]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-d43bc49d]{padding:0 64px}}.title[data-v-d43bc49d]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-d43bc49d]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-d43bc49d]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-d43bc49d]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-d43bc49d]{padding-top:40px}.VPTeamMembersItem[data-v-f9987cb6]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f9987cb6]{padding:32px}.VPTeamMembersItem.small .data[data-v-f9987cb6]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f9987cb6]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f9987cb6]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f9987cb6]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f9987cb6]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f9987cb6]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f9987cb6]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f9987cb6]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f9987cb6]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f9987cb6]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f9987cb6]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f9987cb6]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f9987cb6]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f9987cb6]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f9987cb6]{text-align:center}.avatar[data-v-f9987cb6]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f9987cb6]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f9987cb6]{margin:0;font-weight:600}.affiliation[data-v-f9987cb6]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f9987cb6]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f9987cb6]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f9987cb6]{margin:0 auto}.desc[data-v-f9987cb6] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f9987cb6]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f9987cb6]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f9987cb6]:hover,.sp .sp-link.link[data-v-f9987cb6]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f9987cb6]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-fba19bad]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-fba19bad]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-fba19bad]{max-width:876px}.VPTeamMembers.medium .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-fba19bad]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-fba19bad]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-fba19bad]{max-width:760px}.container[data-v-fba19bad]{display:grid;gap:24px;margin:0 auto;max-width:1152px}.enjoyer{margin-top:.5rem;margin-bottom:0rem;border-radius:14px;padding-top:.2rem;padding-bottom:.2rem;position:relative;font-size:.9rem;font-weight:700;line-height:1.1rem;display:flex;align-items:center;justify-content:center;width:100%;gap:1rem;background-color:var(--vp-c-bg-alt);border:2px solid var(--vp-c-bg-alt);transition:border-color .5s}.enjoyer:hover{border:2px solid var(--vp-c-brand-lighter)}.enjoyer img{transition:transform .5s;transform:scale(1.25)}.enjoyer:hover img{transform:scale(1.75)}.enjoyer .heading{background-image:linear-gradient(120deg,#6887b1 16%,var(--vp-c-brand-lighter),var(--vp-c-brand-lighter));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.enjoyer .extra-info{color:var(--vp-c-text-1);opacity:0;font-size:.7rem;padding-left:.1rem;transition:opacity .5s}.enjoyer:hover .extra-info{opacity:.9}:root{--vp-plugin-tabs-tab-text-color: var(--vp-c-text-2);--vp-plugin-tabs-tab-active-text-color: var(--vp-c-text-1);--vp-plugin-tabs-tab-hover-text-color: var(--vp-c-text-1);--vp-plugin-tabs-tab-bg: var(--vp-c-bg-soft);--vp-plugin-tabs-tab-divider: var(--vp-c-divider);--vp-plugin-tabs-tab-active-bar-color: var(--vp-c-brand-1)}.plugin-tabs{margin:16px 0;background-color:var(--vp-plugin-tabs-tab-bg);border-radius:8px}.plugin-tabs--tab-list{position:relative;padding:0 12px;overflow-x:auto;overflow-y:hidden}.plugin-tabs--tab-list:after{content:"";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--vp-plugin-tabs-tab-divider)}.plugin-tabs--tab{position:relative;padding:0 12px;line-height:48px;border-bottom:2px solid transparent;color:var(--vp-plugin-tabs-tab-text-color);font-size:14px;font-weight:500;white-space:nowrap;transition:color .25s}.plugin-tabs--tab[aria-selected=true]{color:var(--vp-plugin-tabs-tab-active-text-color)}.plugin-tabs--tab:hover{color:var(--vp-plugin-tabs-tab-hover-text-color)}.plugin-tabs--tab:after{content:"";position:absolute;bottom:-2px;left:8px;right:8px;height:2px;background-color:transparent;transition:background-color .25s;z-index:1}.plugin-tabs--tab[aria-selected=true]:after{background-color:var(--vp-plugin-tabs-tab-active-bar-color)}.plugin-tabs--content[data-v-9b0d03d2]{padding:16px}.plugin-tabs--content[data-v-9b0d03d2]>:first-child:first-child{margin-top:0}.plugin-tabs--content[data-v-9b0d03d2]>:last-child:last-child{margin-bottom:0}.plugin-tabs--content[data-v-9b0d03d2]>div[class*=language-]{border-radius:8px;margin:16px 0}:root:not(.dark) .plugin-tabs--content[data-v-9b0d03d2] div[class*=language-]{background-color:var(--vp-c-bg)}.VPHero .clip{white-space:pre;max-width:500px}@font-face{font-family:JuliaMono-Regular;src:url(https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2)}:root{--vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--vp-font-family-mono: JuliaMono-Regular, monospace}.mono-no-substitutions{font-family:JuliaMono-Light,monospace;font-feature-settings:"calt" off}.mono-no-substitutions-alt{font-family:JuliaMono-Light,monospace;font-variant-ligatures:none}pre,code{font-family:JuliaMono-Light,monospace;font-feature-settings:"calt" off}:root{--c-white-dark: #f8f8f8;--c-black-darker: #0d121b;--c-black: #0f0d0d;--c-black-light: #1b1c1e;--c-black-lighter: #262a44;--vp-c-brand: #0b0c0f;--vp-c-brand-light: #747bff;--vp-c-brand-lighter: #3d6692;--vp-c-brand-lightest: #bcc0ff;--vp-c-brand-dark: #535bf2;--vp-c-brand-darker: #454ce1;--vp-c-brand-dimm: rgba(255, 144, 100, .08)}:root{--vp-button-brand-border: var(--vp-c-brand-light);--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand);--vp-button-brand-hover-border: var(--vp-c-brand-light);--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-light);--vp-button-brand-active-border: var(--vp-c-brand-light);--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-button-brand-bg)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );--vp-home-hero-image-background-image: linear-gradient( -45deg, #bd34fe 50%, #47caff 50% );--vp-home-hero-image-filter: blur(40px)}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(72px)}}:root{--vp-custom-block-tip-border: var(--vp-c-brand);--vp-custom-block-tip-text: var(--vp-c-brand-darker);--vp-custom-block-tip-bg: var(--vp-c-brand-dimm)}.dark{--vp-custom-block-tip-border: var(--vp-c-brand);--vp-custom-block-tip-text: var(--vp-c-brand-lightest);--vp-custom-block-tip-bg: var(--vp-c-brand-dimm)}.DocSearch{--docsearch-primary-color: var(--vp-c-brand) !important}mjx-container>svg{display:block;margin:auto}mjx-container{padding:.5rem 0}mjx-container{display:inline-block;margin:auto 2px -2px}mjx-container>svg{margin:auto;display:inline-block}:root{--vp-c-brand-1: #0087d7;--vp-c-brand-2: #0773b2;--vp-c-brand-3: #347090;--vp-c-sponsor: #ee4e95;--vitest-c-sponsor-hover: #c13071}.dark{--vp-c-bg: var(--c-black);--vp-c-bg-soft: var(--c-black-light);--vp-c-bg-soft-up: var(--c-black-lighter);--vp-c-bg-mute: var(--c-black-light);--vp-c-bg-soft-mute: var(--c-black-lighter);--vp-c-bg-alt: #111111;--vp-c-bg-elv: var(--vp-c-bg-soft);--vp-c-bg-elv-mute: var(--vp-c-bg-soft-mute);--vp-c-mute: var(--vp-c-bg-mute);--vp-c-mute-dark: var(--c-black-lighter);--vp-c-mute-darker: var(--c-black-darker);--vp-c-brand-1: #ff875f;--vp-c-brand-2: #ff875f;--vp-c-brand-3: #ff875f;--vp-c-sponsor: #ff875f;--vitest-c-sponsor-hover: #e51370}.VPDoc.has-aside .content-container{max-width:100%!important}.aside{max-width:200px!important;padding-left:0!important}.VPDoc{padding-top:15px!important;padding-left:5px!important}.VPDocOutlineItem li{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:200px}.VPNavBar .title{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}@media (max-width: 960px){.VPDoc{padding-left:25px!important}}:root{--vp-c-bg-input-light: #eef0f3;--vp-c-bg-output-light: #f8f9fb;--vp-c-bg-input-dark: #1a1a1a;--vp-c-bg-output-dark: #101418}:root{--vp-c-bg-input: var(--vp-c-bg-input-light);--vp-c-bg-output: var(--vp-c-bg-output-light)}.dark{--vp-c-bg-input: var(--vp-c-bg-input-dark);--vp-c-bg-output: var(--vp-c-bg-output-dark)}.language-julia{background-color:var(--vp-c-bg-input)!important}.language-{background-color:var(--vp-c-bg-output)!important}.row img{border-radius:50%;width:60px;height:60px}.row{display:flex;flex-wrap:wrap;padding:0 4px}.VPLocalSearchBox[data-v-5b749456]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-5b749456]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-5b749456]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-5b749456]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-5b749456]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-5b749456]{padding:0 8px}}.search-bar[data-v-5b749456]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-5b749456]{display:block;font-size:18px}.navigate-icon[data-v-5b749456]{display:block;font-size:14px}.search-icon[data-v-5b749456]{margin:8px}@media (max-width: 767px){.search-icon[data-v-5b749456]{display:none}}.search-input[data-v-5b749456]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-5b749456]{padding:6px 4px}}.search-actions[data-v-5b749456]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-5b749456]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-5b749456]{display:none}}.search-actions button[data-v-5b749456]{padding:8px}.search-actions button[data-v-5b749456]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-5b749456]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-5b749456]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-5b749456]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-5b749456]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-5b749456]{display:none}}.search-keyboard-shortcuts kbd[data-v-5b749456]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-5b749456]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-5b749456]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-5b749456]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-5b749456]{margin:8px}}.titles[data-v-5b749456]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-5b749456]{display:flex;align-items:center;gap:4px}.title.main[data-v-5b749456]{font-weight:500}.title-icon[data-v-5b749456]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-5b749456]{opacity:.5}.result.selected[data-v-5b749456]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-5b749456]{position:relative}.excerpt[data-v-5b749456]{opacity:50%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;margin-top:4px}.result.selected .excerpt[data-v-5b749456]{opacity:1}.excerpt[data-v-5b749456] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-5b749456] mark,.excerpt[data-v-5b749456] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-5b749456] .vp-code-group .tabs{display:none}.excerpt[data-v-5b749456] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-5b749456]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-5b749456]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-5b749456],.result.selected .title-icon[data-v-5b749456]{color:var(--vp-c-brand-1)!important}.no-results[data-v-5b749456]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-5b749456]{flex:none} diff --git a/previews/PR437/assets/swuusvv.D-ZdEt0g.png b/previews/PR437/assets/swuusvv.D-ZdEt0g.png new file mode 100644 index 00000000..bcf473c0 Binary files /dev/null and b/previews/PR437/assets/swuusvv.D-ZdEt0g.png differ diff --git a/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.js b/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.js new file mode 100644 index 00000000..b632d9ed --- /dev/null +++ b/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.js @@ -0,0 +1,72 @@ +import{_ as i,c as a,a2 as n,o as h}from"./chunks/framework.BxolPc_T.js";const l="/YAXArrays.jl/previews/PR437/assets/byjkepm.BBOgXAcy.png",k="/YAXArrays.jl/previews/PR437/assets/swuusvv.D-ZdEt0g.png",c=JSON.parse('{"title":"Mean Seasonal Cycle for a single pixel","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/mean_seasonal_cycle.md","filePath":"tutorials/mean_seasonal_cycle.md","lastUpdated":null}'),p={name:"tutorials/mean_seasonal_cycle.md"};function t(e,s,E,d,r,g){return h(),a("div",null,s[0]||(s[0]=[n(`

Mean Seasonal Cycle for a single pixel

julia
using CairoMakie
+CairoMakie.activate!()
+using Dates
+using Statistics

We define the data span. For simplicity, three non-leap years were selected.

julia
t =  Date("2021-01-01"):Day(1):Date("2023-12-31")
+NpY = 3
3

and create some seasonal dummy data

julia
x = repeat(range(0, , length=365), NpY)
+var = @. sin(x) + 0.1 * randn()
julia
fig, ax, obj = lines(t, var; color = :purple, linewidth=1.25,
+    axis=(; xlabel="Time", ylabel="Variable"),
+    figure = (; size = (600,400))
+    )
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig

Define the cube

julia
julia> using YAXArrays, DimensionalData
+
+julia> axes = (Dim{:Time}(t),)
(Time Date("2021-01-01"):Dates.Day(1):Date("2023-12-31"))
julia
julia> c = YAXArray(axes, var)
╭──────────────────────────────────╮
+1095-element YAXArray{Float64,1}
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+Time Sampled{Date} Date("2021-01-01"):Dates.Day(1):Date("2023-12-31") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 8.55 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Let's calculate the mean seasonal cycle of our dummy variable 'var'

julia
function mean_seasonal_cycle(c; ndays = 365)
+    ## filterig by month-day
+    monthday = map(x->Dates.format(x, "u-d"), collect(c.Time))
+    datesid = unique(monthday)
+    ## number of years
+    NpY = Int(size(monthday,1)/ndays)
+    idx = Int.(zeros(ndays, NpY))
+    ## get the day-month indices for data subsetting
+    for i in 1:ndays
+        idx[i,:] = Int.(findall(x-> x == datesid[i], monthday))
+    end
+    ## compute the mean seasonal cycle
+    mscarray = map(x->var[x], idx)
+    msc = mapslices(mean, mscarray, dims=2)
+    return msc
+end
+
+msc = mean_seasonal_cycle(c);
365×1 Matrix{Float64}:
+ -0.08292452722604059
+ -0.02034926101455332
+  0.011564383769804764
+  0.023779014536715975
+  0.05254540122374988
+  0.08887819459347718
+  0.14719040256891566
+  0.11322047410821301
+  0.15227894345884566
+  0.12143335632591595
+
+ -0.27831029907148686
+ -0.19438512289805546
+ -0.05058428806431179
+ -0.14516899355200824
+ -0.12128913574359863
+  0.0024136950999947768
+  0.03315745304050341
+  0.010730686374072013
+  0.014073923933364077

TODO: Apply the new groupby funtion from DD

Plot results: mean seasonal cycle

julia
fig, ax, obj = lines(1:365, var[1:365]; label="2021", color=:black,
+    linewidth=2.0, linestyle=:dot,
+    axis = (;  xlabel="Day of Year", ylabel="Variable"),
+    figure=(; size = (600,400))
+    )
+lines!(1:365, var[366:730], label="2022", color=:brown,
+    linewidth=1.5, linestyle=:dash
+    )
+lines!(1:365, msc[:,1]; label="MSC", color=:dodgerblue, linewidth=2.5)
+axislegend()
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig
+current_figure()

',21)]))}const F=i(p,[["render",t]]);export{c as __pageData,F as default}; diff --git a/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.lean.js b/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.lean.js new file mode 100644 index 00000000..b632d9ed --- /dev/null +++ b/previews/PR437/assets/tutorials_mean_seasonal_cycle.md.nfqRn4A8.lean.js @@ -0,0 +1,72 @@ +import{_ as i,c as a,a2 as n,o as h}from"./chunks/framework.BxolPc_T.js";const l="/YAXArrays.jl/previews/PR437/assets/byjkepm.BBOgXAcy.png",k="/YAXArrays.jl/previews/PR437/assets/swuusvv.D-ZdEt0g.png",c=JSON.parse('{"title":"Mean Seasonal Cycle for a single pixel","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/mean_seasonal_cycle.md","filePath":"tutorials/mean_seasonal_cycle.md","lastUpdated":null}'),p={name:"tutorials/mean_seasonal_cycle.md"};function t(e,s,E,d,r,g){return h(),a("div",null,s[0]||(s[0]=[n(`

Mean Seasonal Cycle for a single pixel

julia
using CairoMakie
+CairoMakie.activate!()
+using Dates
+using Statistics

We define the data span. For simplicity, three non-leap years were selected.

julia
t =  Date("2021-01-01"):Day(1):Date("2023-12-31")
+NpY = 3
3

and create some seasonal dummy data

julia
x = repeat(range(0, , length=365), NpY)
+var = @. sin(x) + 0.1 * randn()
julia
fig, ax, obj = lines(t, var; color = :purple, linewidth=1.25,
+    axis=(; xlabel="Time", ylabel="Variable"),
+    figure = (; size = (600,400))
+    )
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig

Define the cube

julia
julia> using YAXArrays, DimensionalData
+
+julia> axes = (Dim{:Time}(t),)
(Time Date("2021-01-01"):Dates.Day(1):Date("2023-12-31"))
julia
julia> c = YAXArray(axes, var)
╭──────────────────────────────────╮
+1095-element YAXArray{Float64,1}
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+Time Sampled{Date} Date("2021-01-01"):Dates.Day(1):Date("2023-12-31") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 8.55 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Let's calculate the mean seasonal cycle of our dummy variable 'var'

julia
function mean_seasonal_cycle(c; ndays = 365)
+    ## filterig by month-day
+    monthday = map(x->Dates.format(x, "u-d"), collect(c.Time))
+    datesid = unique(monthday)
+    ## number of years
+    NpY = Int(size(monthday,1)/ndays)
+    idx = Int.(zeros(ndays, NpY))
+    ## get the day-month indices for data subsetting
+    for i in 1:ndays
+        idx[i,:] = Int.(findall(x-> x == datesid[i], monthday))
+    end
+    ## compute the mean seasonal cycle
+    mscarray = map(x->var[x], idx)
+    msc = mapslices(mean, mscarray, dims=2)
+    return msc
+end
+
+msc = mean_seasonal_cycle(c);
365×1 Matrix{Float64}:
+ -0.08292452722604059
+ -0.02034926101455332
+  0.011564383769804764
+  0.023779014536715975
+  0.05254540122374988
+  0.08887819459347718
+  0.14719040256891566
+  0.11322047410821301
+  0.15227894345884566
+  0.12143335632591595
+
+ -0.27831029907148686
+ -0.19438512289805546
+ -0.05058428806431179
+ -0.14516899355200824
+ -0.12128913574359863
+  0.0024136950999947768
+  0.03315745304050341
+  0.010730686374072013
+  0.014073923933364077

TODO: Apply the new groupby funtion from DD

Plot results: mean seasonal cycle

julia
fig, ax, obj = lines(1:365, var[1:365]; label="2021", color=:black,
+    linewidth=2.0, linestyle=:dot,
+    axis = (;  xlabel="Day of Year", ylabel="Variable"),
+    figure=(; size = (600,400))
+    )
+lines!(1:365, var[366:730], label="2022", color=:brown,
+    linewidth=1.5, linestyle=:dash
+    )
+lines!(1:365, msc[:,1]; label="MSC", color=:dodgerblue, linewidth=2.5)
+axislegend()
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig
+current_figure()

',21)]))}const F=i(p,[["render",t]]);export{c as __pageData,F as default}; diff --git a/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.js b/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.js new file mode 100644 index 00000000..67165764 --- /dev/null +++ b/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.js @@ -0,0 +1 @@ +import{_ as t,c as a,a2 as r,o}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Other tutorials","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/other_tutorials.md","filePath":"tutorials/other_tutorials.md","lastUpdated":null}'),i={name:"tutorials/other_tutorials.md"};function l(s,e,n,h,u,f){return o(),a("div",null,e[0]||(e[0]=[r('

Other tutorials

If you are interested in learning how to work with YAXArrays for different use cases you can follow along one of the following tutorials.

  • Currently the overview tutorial is located at ESDLTutorials Repository

  • You can find further tutorial videos at the EO College. Beware that the syntax in the video tutorials might be slightly changed.

  • the other tutorials are still work in progress.

General overview of the functionality of YAXArrays

This tutorial provides a broad overview about the features of YAXArrays.

Table-style iteration over YAXArrays

Work in progress

Sometimes you want to combine the data that is represented in the data cube with other datasets, which are best described as a data frame. In this tutorial you will learn how to use the Tables.jl interface to iterate over the data in the YAXArray.

Combining multiple tiff files into a zarr based datacube

',9)]))}const b=t(i,[["render",l]]);export{c as __pageData,b as default}; diff --git a/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.lean.js b/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.lean.js new file mode 100644 index 00000000..67165764 --- /dev/null +++ b/previews/PR437/assets/tutorials_other_tutorials.md.Dz1rAnJW.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,a2 as r,o}from"./chunks/framework.BxolPc_T.js";const c=JSON.parse('{"title":"Other tutorials","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/other_tutorials.md","filePath":"tutorials/other_tutorials.md","lastUpdated":null}'),i={name:"tutorials/other_tutorials.md"};function l(s,e,n,h,u,f){return o(),a("div",null,e[0]||(e[0]=[r('

Other tutorials

If you are interested in learning how to work with YAXArrays for different use cases you can follow along one of the following tutorials.

  • Currently the overview tutorial is located at ESDLTutorials Repository

  • You can find further tutorial videos at the EO College. Beware that the syntax in the video tutorials might be slightly changed.

  • the other tutorials are still work in progress.

General overview of the functionality of YAXArrays

This tutorial provides a broad overview about the features of YAXArrays.

Table-style iteration over YAXArrays

Work in progress

Sometimes you want to combine the data that is represented in the data cube with other datasets, which are best described as a data frame. In this tutorial you will learn how to use the Tables.jl interface to iterate over the data in the YAXArray.

Combining multiple tiff files into a zarr based datacube

',9)]))}const b=t(i,[["render",l]]);export{c as __pageData,b as default}; diff --git a/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.js b/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.js new file mode 100644 index 00000000..1491eb90 --- /dev/null +++ b/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.js @@ -0,0 +1,54 @@ +import{_ as i,c as a,a2 as h,o as n}from"./chunks/framework.BxolPc_T.js";const t="/YAXArrays.jl/previews/PR437/assets/palueig.xrZxBsPv.jpeg",k="/YAXArrays.jl/previews/PR437/assets/adzshwu.B7KFIfDV.jpeg",l="/YAXArrays.jl/previews/PR437/assets/jtwtgjr.96k_BqPR.jpeg",F=JSON.parse('{"title":"Plotting maps","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/plottingmaps.md","filePath":"tutorials/plottingmaps.md","lastUpdated":null}'),p={name:"tutorials/plottingmaps.md"};function e(E,s,r,d,g,y){return n(),a("div",null,s[0]||(s[0]=[h(`

Plotting maps

As test data we use the CMIP6 Scenarios.

julia
using Zarr, YAXArrays, Dates
+using DimensionalData
+using GLMakie, GeoMakie
+using GLMakie.GeometryBasics
+
+store ="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
"gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
julia
julia> g = open_dataset(zopen(store, consolidated=true))
YAXArray Dataset
+Shared Axes:
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)
julia
julia> c = g["tas"];

Subset, first time step

julia
julia> ct1_slice = c[Ti = Near(Date("2015-01-01"))];

use lookup to get axis values

julia
lon = lookup(ct1_slice, :lon)
+lat = lookup(ct1_slice, :lat)
+data = ct1_slice.data[:,:];

Heatmap plot

julia
GLMakie.activate!()
+
+fig, ax, plt = heatmap(ct1_slice; colormap = :seaborn_icefire_gradient,
+    axis = (; aspect=DataAspect()),
+    figure = (; size = (1200,600), fontsize=24))
+fig

Wintri Projection

Some transformations

julia
δlon = (lon[2]-lon[1])/2
+nlon = lon .- 180 .+ δlon
+ndata = circshift(data, (192,1))

and add Coastlines with GeoMakie.coastlines(),

julia
fig = Figure(;size=(1200,600))
+ax = GeoAxis(fig[1,1])
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

Moll projection

julia
fig = Figure(; size=(1200,600))
+ax = GeoAxis(fig[1,1]; dest = "+proj=moll")
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

3D sphere plot

julia
using Bonito, WGLMakie
+Page(exportable=true, offline=true)
+
+WGLMakie.activate!()
+Makie.inline!(true) # Make sure to inline plots into Documenter output!
+
+ds = replace(ndata, missing =>NaN)
+sphere = uv_normal_mesh(Tesselation(Sphere(Point3f(0), 1), 128))
+
+fig = Figure(backgroundcolor=:grey25, size=(500,500))
+ax = LScene(fig[1,1], show_axis=false)
+mesh!(ax, sphere; color = ds'[end:-1:1,:], shading=false,
+    colormap = :seaborn_icefire_gradient)
+zoom!(ax.scene, cameracontrols(ax.scene), 0.5)
+rotate!(ax.scene, 2.5)
+fig
`,25)]))}const c=i(p,[["render",e]]);export{F as __pageData,c as default}; diff --git a/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.lean.js b/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.lean.js new file mode 100644 index 00000000..1491eb90 --- /dev/null +++ b/previews/PR437/assets/tutorials_plottingmaps.md.ebeaPQxL.lean.js @@ -0,0 +1,54 @@ +import{_ as i,c as a,a2 as h,o as n}from"./chunks/framework.BxolPc_T.js";const t="/YAXArrays.jl/previews/PR437/assets/palueig.xrZxBsPv.jpeg",k="/YAXArrays.jl/previews/PR437/assets/adzshwu.B7KFIfDV.jpeg",l="/YAXArrays.jl/previews/PR437/assets/jtwtgjr.96k_BqPR.jpeg",F=JSON.parse('{"title":"Plotting maps","description":"","frontmatter":{},"headers":[],"relativePath":"tutorials/plottingmaps.md","filePath":"tutorials/plottingmaps.md","lastUpdated":null}'),p={name:"tutorials/plottingmaps.md"};function e(E,s,r,d,g,y){return n(),a("div",null,s[0]||(s[0]=[h(`

Plotting maps

As test data we use the CMIP6 Scenarios.

julia
using Zarr, YAXArrays, Dates
+using DimensionalData
+using GLMakie, GeoMakie
+using GLMakie.GeometryBasics
+
+store ="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
"gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
julia
julia> g = open_dataset(zopen(store, consolidated=true))
YAXArray Dataset
+Shared Axes:
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)
julia
julia> c = g["tas"];

Subset, first time step

julia
julia> ct1_slice = c[Ti = Near(Date("2015-01-01"))];

use lookup to get axis values

julia
lon = lookup(ct1_slice, :lon)
+lat = lookup(ct1_slice, :lat)
+data = ct1_slice.data[:,:];

Heatmap plot

julia
GLMakie.activate!()
+
+fig, ax, plt = heatmap(ct1_slice; colormap = :seaborn_icefire_gradient,
+    axis = (; aspect=DataAspect()),
+    figure = (; size = (1200,600), fontsize=24))
+fig

Wintri Projection

Some transformations

julia
δlon = (lon[2]-lon[1])/2
+nlon = lon .- 180 .+ δlon
+ndata = circshift(data, (192,1))

and add Coastlines with GeoMakie.coastlines(),

julia
fig = Figure(;size=(1200,600))
+ax = GeoAxis(fig[1,1])
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

Moll projection

julia
fig = Figure(; size=(1200,600))
+ax = GeoAxis(fig[1,1]; dest = "+proj=moll")
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

3D sphere plot

julia
using Bonito, WGLMakie
+Page(exportable=true, offline=true)
+
+WGLMakie.activate!()
+Makie.inline!(true) # Make sure to inline plots into Documenter output!
+
+ds = replace(ndata, missing =>NaN)
+sphere = uv_normal_mesh(Tesselation(Sphere(Point3f(0), 1), 128))
+
+fig = Figure(backgroundcolor=:grey25, size=(500,500))
+ax = LScene(fig[1,1], show_axis=false)
+mesh!(ax, sphere; color = ds'[end:-1:1,:], shading=false,
+    colormap = :seaborn_icefire_gradient)
+zoom!(ax.scene, cameracontrols(ax.scene), 0.5)
+rotate!(ax.scene, 2.5)
+fig
`,25)]))}const c=i(p,[["render",e]]);export{F as __pageData,c as default}; diff --git a/previews/PR437/assets/zxfqnjz.DMLwX5kL.jpeg b/previews/PR437/assets/zxfqnjz.DMLwX5kL.jpeg new file mode 100644 index 00000000..d52650a1 Binary files /dev/null and b/previews/PR437/assets/zxfqnjz.DMLwX5kL.jpeg differ diff --git a/previews/PR437/development/contribute.html b/previews/PR437/development/contribute.html new file mode 100644 index 00000000..249de862 --- /dev/null +++ b/previews/PR437/development/contribute.html @@ -0,0 +1,27 @@ + + + + + + Contribute to YAXArrays.jl | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Contribute to YAXArrays.jl

Pull requests and bug reports are always welcome at the YAXArrays.jl GitHub repository.

Contribute to Documentation

Contributing with examples can be done by first creating a new file example here

new file

  • your_new_file.md at docs/src/UserGuide/

Once this is done you need to add a new entry here at the appropriate level.

add entry to docs

Your new entry should look like:

  • { text: 'Your title example', link: '/UserGuide/your_new_file.md' }

Build docs locally

If you want to take a look at the docs locally before doing a PR follow the next steps:

Install the dependencies in your system, locate yourself at the docs level folder, then do

sh
npm i

Then simply go to your docs env and activate it, i.e.

sh
docs> julia
+julia> ]
+pkg> activate .

Next, run the scripts. Generate files and build docs by running:

sh
include("make.jl")

Now go to your terminal in the same path docs> and run:

sh
npm run docs:dev

This should ouput http://localhost:5173/YAXArrays.jl/, copy/paste this into your browser and you are all set.

+ + + + \ No newline at end of file diff --git a/previews/PR437/development/contributors.html b/previews/PR437/development/contributors.html new file mode 100644 index 00000000..2fe47f77 --- /dev/null +++ b/previews/PR437/development/contributors.html @@ -0,0 +1,25 @@ + + + + + + YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Contributors

Current core contributors

They have taking the lead for the ongoing organizational maintenance and technical direction of , and .

Fabian Gans

Fabian Gans

Geoscientific Programmer

Felix Cremer

Felix Cremer

PhD Candidate in Remote Sensing

Rafael Schouten

Rafael Schouten

Spatial/ecological modelling

Lazaro Alonso

Lazaro Alonso

Scientist. Data Visualization

Our valuable contributors

We appreciate all contributions from the Julia community so that this ecosystem can thrive.

+ + + + \ No newline at end of file diff --git a/previews/PR437/favicon.ico b/previews/PR437/favicon.ico new file mode 100644 index 00000000..80dd3a80 Binary files /dev/null and b/previews/PR437/favicon.ico differ diff --git a/previews/PR437/get_started.html b/previews/PR437/get_started.html new file mode 100644 index 00000000..dbdb700b --- /dev/null +++ b/previews/PR437/get_started.html @@ -0,0 +1,80 @@ + + + + + + Getting Started | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Getting Started

Installation

Install Julia v1.10 or above. YAXArrays.jl is available through the Julia package manager. You can enter it by pressing ] in the REPL and then typing

julia
pkg> add YAXArrays

Alternatively, you can also do

julia
import Pkg; Pkg.add("YAXArrays")

Quickstart

Create a simple array from random numbers given the size of each dimension or axis:

julia
using YAXArrays
+
+a = YAXArray(rand(2,3))
╭─────────────────────────╮
+│ 2×3 YAXArray{Float64,2} │
+├─────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Dim_1 Sampled{Int64} Base.OneTo(2) ForwardOrdered Regular Points,
+  → Dim_2 Sampled{Int64} Base.OneTo(3) ForwardOrdered Regular Points
+├─────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├────────────────────────────────────────────────────────── file size ┤ 
+  file size: 48.0 bytes
+└─────────────────────────────────────────────────────────────────────┘

Assemble a more complex YAXArray with 4 dimensions, i.e. time, x, y and a variable type:

julia
using DimensionalData
+
+# axes or dimensions with name and tick values
+axlist = (
+    Dim{:time}(range(1, 20, length=20)),
+    X(range(1, 10, length=10)),
+    Y(range(1, 5, length=15)),
+    Dim{:variable}(["temperature", "precipitation"])
+)
+
+# the actual data matching the dimensions defined in axlist
+data = rand(20, 10, 15, 2)
+
+# metadata about the array
+props = Dict(
+    "origin" => "YAXArrays.jl example",
+    "x" => "longitude",
+    "y" => "latitude",
+);
+
+a2 = YAXArray(axlist, data, props)
╭────────────────────────────────╮
+│ 20×10×15×2 YAXArray{Float64,4} │
+├────────────────────────────────┴─────────────────────────────────────── dims ┐
+  ↓ time     Sampled{Float64} 1.0:1.0:20.0 ForwardOrdered Regular Points,
+  → X        Sampled{Float64} 1.0:1.0:10.0 ForwardOrdered Regular Points,
+  ↗ Y        Sampled{Float64} 1.0:0.2857142857142857:5.0 ForwardOrdered Regular Points,
+  ⬔ variable Categorical{String} ["temperature", "precipitation"] ReverseOrdered
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, String} with 3 entries:
+  "y"      => "latitude"
+  "x"      => "longitude"
+  "origin" => "YAXArrays.jl example"
+├─────────────────────────────────────────────────────────────────── file size ┤ 
+  file size: 46.88 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Get the temperature map at the first point in time:

julia
a2[variable=At("temperature"), time=1].data
10×15 view(::Array{Float64, 4}, 1, :, :, 1) with eltype Float64:
+ 0.0462624  0.541399  0.884596  0.466542   …  0.433215  0.39914    0.253557
+ 0.424205   0.783796  0.186312  0.698795      0.621626  0.0845415  0.397222
+ 0.649498   0.861755  0.272109  0.137422      0.104073  0.834933   0.708253
+ 0.342288   0.723246  0.267431  0.71243       0.358337  0.091767   0.93618
+ 0.165788   0.198967  0.239879  0.138996      0.409423  0.263174   0.213509
+ 0.921833   0.171584  0.565253  0.178559   …  0.27394   0.291786   0.358056
+ 0.451794   0.538223  0.840426  0.210596      0.56083   0.324527   0.712428
+ 0.788957   0.695756  0.291145  0.682179      0.152689  0.925986   0.138529
+ 0.800129   0.773651  0.400935  0.249043      0.75783   0.9316     0.985469
+ 0.350231   0.122751  0.497997  0.0720417     0.290209  0.344472   0.776623

Updates

TIP

The Julia Compiler is always improving. As such, we recommend using the latest stable version of Julia.

You may check the installed version with:

julia
pkg> st YAXArrays

INFO

With YAXArrays.jl 0.5 we switched the underlying data type to be a subtype of the DimensionalData.jl types. Therefore the indexing with named dimensions changed to the DimensionalData syntax. See the DimensionalData.jl docs.

+ + + + \ No newline at end of file diff --git a/previews/PR437/hashmap.json b/previews/PR437/hashmap.json new file mode 100644 index 00000000..f867fb10 --- /dev/null +++ b/previews/PR437/hashmap.json @@ -0,0 +1 @@ +{"api.md":"BbyteFGm","development_contribute.md":"lnYHnNmM","development_contributors.md":"FX1rn6bG","get_started.md":"Bry90ck5","index.md":"BUnK4bB7","tutorials_mean_seasonal_cycle.md":"nfqRn4A8","tutorials_other_tutorials.md":"Dz1rAnJW","tutorials_plottingmaps.md":"ebeaPQxL","userguide_cache.md":"B_Z0kQqJ","userguide_chunk.md":"CuKskIwf","userguide_combine.md":"D52gFSsu","userguide_compute.md":"B_a3BBtd","userguide_convert.md":"dKg9ro9h","userguide_create.md":"hCVHNj4a","userguide_faq.md":"BqoiJUSy","userguide_group.md":"BbGChzju","userguide_read.md":"cM3lYpD2","userguide_select.md":"DH9eTP1O","userguide_types.md":"CpkihWi2","userguide_write.md":"CjqlGJAC"} diff --git a/previews/PR437/index.html b/previews/PR437/index.html new file mode 100644 index 00000000..e7c4b585 --- /dev/null +++ b/previews/PR437/index.html @@ -0,0 +1,25 @@ + + + + + + YAXArrays.jl + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/previews/PR437/logo.png b/previews/PR437/logo.png new file mode 100644 index 00000000..80dd3a80 Binary files /dev/null and b/previews/PR437/logo.png differ diff --git a/previews/PR437/logo.svg b/previews/PR437/logo.svg new file mode 100644 index 00000000..1d1b362f --- /dev/null +++ b/previews/PR437/logo.svg @@ -0,0 +1,324 @@ + + + +YAXArrays.jl diff --git a/previews/PR437/siteinfo.js b/previews/PR437/siteinfo.js new file mode 100644 index 00000000..f0de0496 --- /dev/null +++ b/previews/PR437/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "previews/PR437"; diff --git a/previews/PR437/tutorials/mean_seasonal_cycle.html b/previews/PR437/tutorials/mean_seasonal_cycle.html new file mode 100644 index 00000000..28756a4e --- /dev/null +++ b/previews/PR437/tutorials/mean_seasonal_cycle.html @@ -0,0 +1,96 @@ + + + + + + Mean Seasonal Cycle for a single pixel | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Mean Seasonal Cycle for a single pixel

julia
using CairoMakie
+CairoMakie.activate!()
+using Dates
+using Statistics

We define the data span. For simplicity, three non-leap years were selected.

julia
t =  Date("2021-01-01"):Day(1):Date("2023-12-31")
+NpY = 3
3

and create some seasonal dummy data

julia
x = repeat(range(0, , length=365), NpY)
+var = @. sin(x) + 0.1 * randn()
julia
fig, ax, obj = lines(t, var; color = :purple, linewidth=1.25,
+    axis=(; xlabel="Time", ylabel="Variable"),
+    figure = (; size = (600,400))
+    )
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig

Define the cube

julia
julia> using YAXArrays, DimensionalData
+
+julia> axes = (Dim{:Time}(t),)
(Time Date("2021-01-01"):Dates.Day(1):Date("2023-12-31"))
julia
julia> c = YAXArray(axes, var)
╭──────────────────────────────────╮
+1095-element YAXArray{Float64,1}
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+Time Sampled{Date} Date("2021-01-01"):Dates.Day(1):Date("2023-12-31") ForwardOrdered Regular Points
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Dict{String, Any}()
+├─────────────────────────────────────────────────────────────────── file size ┤
+  file size: 8.55 KB
+└──────────────────────────────────────────────────────────────────────────────┘

Let's calculate the mean seasonal cycle of our dummy variable 'var'

julia
function mean_seasonal_cycle(c; ndays = 365)
+    ## filterig by month-day
+    monthday = map(x->Dates.format(x, "u-d"), collect(c.Time))
+    datesid = unique(monthday)
+    ## number of years
+    NpY = Int(size(monthday,1)/ndays)
+    idx = Int.(zeros(ndays, NpY))
+    ## get the day-month indices for data subsetting
+    for i in 1:ndays
+        idx[i,:] = Int.(findall(x-> x == datesid[i], monthday))
+    end
+    ## compute the mean seasonal cycle
+    mscarray = map(x->var[x], idx)
+    msc = mapslices(mean, mscarray, dims=2)
+    return msc
+end
+
+msc = mean_seasonal_cycle(c);
365×1 Matrix{Float64}:
+ -0.08292452722604059
+ -0.02034926101455332
+  0.011564383769804764
+  0.023779014536715975
+  0.05254540122374988
+  0.08887819459347718
+  0.14719040256891566
+  0.11322047410821301
+  0.15227894345884566
+  0.12143335632591595
+
+ -0.27831029907148686
+ -0.19438512289805546
+ -0.05058428806431179
+ -0.14516899355200824
+ -0.12128913574359863
+  0.0024136950999947768
+  0.03315745304050341
+  0.010730686374072013
+  0.014073923933364077

TODO: Apply the new groupby funtion from DD

Plot results: mean seasonal cycle

julia
fig, ax, obj = lines(1:365, var[1:365]; label="2021", color=:black,
+    linewidth=2.0, linestyle=:dot,
+    axis = (;  xlabel="Day of Year", ylabel="Variable"),
+    figure=(; size = (600,400))
+    )
+lines!(1:365, var[366:730], label="2022", color=:brown,
+    linewidth=1.5, linestyle=:dash
+    )
+lines!(1:365, msc[:,1]; label="MSC", color=:dodgerblue, linewidth=2.5)
+axislegend()
+ax.xticklabelrotation = π / 4
+ax.xticklabelalign = (:right, :center)
+fig
+current_figure()

+ + + + \ No newline at end of file diff --git a/previews/PR437/tutorials/other_tutorials.html b/previews/PR437/tutorials/other_tutorials.html new file mode 100644 index 00000000..4c038a82 --- /dev/null +++ b/previews/PR437/tutorials/other_tutorials.html @@ -0,0 +1,25 @@ + + + + + + Other tutorials | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Other tutorials

If you are interested in learning how to work with YAXArrays for different use cases you can follow along one of the following tutorials.

  • Currently the overview tutorial is located at ESDLTutorials Repository

  • You can find further tutorial videos at the EO College. Beware that the syntax in the video tutorials might be slightly changed.

  • the other tutorials are still work in progress.

General overview of the functionality of YAXArrays

This tutorial provides a broad overview about the features of YAXArrays.

Table-style iteration over YAXArrays

Work in progress

Sometimes you want to combine the data that is represented in the data cube with other datasets, which are best described as a data frame. In this tutorial you will learn how to use the Tables.jl interface to iterate over the data in the YAXArray.

Combining multiple tiff files into a zarr based datacube

+ + + + \ No newline at end of file diff --git a/previews/PR437/tutorials/plottingmaps.html b/previews/PR437/tutorials/plottingmaps.html new file mode 100644 index 00000000..d1aeffc6 --- /dev/null +++ b/previews/PR437/tutorials/plottingmaps.html @@ -0,0 +1,78 @@ + + + + + + Plotting maps | YAXArrays.jl + + + + + + + + + + + + + + +
Skip to content

Plotting maps

As test data we use the CMIP6 Scenarios.

julia
using Zarr, YAXArrays, Dates
+using DimensionalData
+using GLMakie, GeoMakie
+using GLMakie.GeometryBasics
+
+store ="gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
"gs://cmip6/CMIP6/ScenarioMIP/DKRZ/MPI-ESM1-2-HR/ssp585/r1i1p1f1/3hr/tas/gn/v20190710/"
julia
julia> g = open_dataset(zopen(store, consolidated=true))
YAXArray Dataset
+Shared Axes:
+None
+Variables: 
+height
+
+Variables with additional axes:
+  Additional Axes: 
+  (lon Sampled{Float64} 0.0:0.9375:359.0625 ForwardOrdered Regular Points,
+lat Sampled{Float64} [-89.28422753251364, -88.35700351866494, …, 88.35700351866494, 89.28422753251364] ForwardOrdered Irregular Points,
+Ti  Sampled{DateTime} [2015-01-01T03:00:00, …, 2101-01-01T00:00:00] ForwardOrdered Irregular Points)
+  Variables: 
+  tas
+
+Properties: Dict{String, Any}("initialization_index" => 1, "realm" => "atmos", "variable_id" => "tas", "external_variables" => "areacella", "branch_time_in_child" => 60265.0, "data_specs_version" => "01.00.30", "history" => "2019-07-21T06:26:13Z ; CMOR rewrote data to be consistent with CMIP6, CF-1.7 CMIP-6.2 and CF standards.", "forcing_index" => 1, "parent_variant_label" => "r1i1p1f1", "table_id" => "3hr"…)
julia
julia> c = g["tas"];

Subset, first time step

julia
julia> ct1_slice = c[Ti = Near(Date("2015-01-01"))];

use lookup to get axis values

julia
lon = lookup(ct1_slice, :lon)
+lat = lookup(ct1_slice, :lat)
+data = ct1_slice.data[:,:];

Heatmap plot

julia
GLMakie.activate!()
+
+fig, ax, plt = heatmap(ct1_slice; colormap = :seaborn_icefire_gradient,
+    axis = (; aspect=DataAspect()),
+    figure = (; size = (1200,600), fontsize=24))
+fig

Wintri Projection

Some transformations

julia
δlon = (lon[2]-lon[1])/2
+nlon = lon .- 180 .+ δlon
+ndata = circshift(data, (192,1))

and add Coastlines with GeoMakie.coastlines(),

julia
fig = Figure(;size=(1200,600))
+ax = GeoAxis(fig[1,1])
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

Moll projection

julia
fig = Figure(; size=(1200,600))
+ax = GeoAxis(fig[1,1]; dest = "+proj=moll")
+surface!(ax, nlon, lat, ndata; colormap = :seaborn_icefire_gradient, shading=false)
+cl=lines!(ax, GeoMakie.coastlines(), color = :white, linewidth=0.85)
+translate!(cl, 0, 0, 1000)
+fig

3D sphere plot

julia
using Bonito, WGLMakie
+Page(exportable=true, offline=true)
+
+WGLMakie.activate!()
+Makie.inline!(true) # Make sure to inline plots into Documenter output!
+
+ds = replace(ndata, missing =>NaN)
+sphere = uv_normal_mesh(Tesselation(Sphere(Point3f(0), 1), 128))
+
+fig = Figure(backgroundcolor=:grey25, size=(500,500))
+ax = LScene(fig[1,1], show_axis=false)
+mesh!(ax, sphere; color = ds'[end:-1:1,:], shading=false,
+    colormap = :seaborn_icefire_gradient)
+zoom!(ax.scene, cameracontrols(ax.scene), 0.5)
+rotate!(ax.scene, 2.5)
+fig
+ + + + \ No newline at end of file