diff --git a/previews/PR807/404.html b/previews/PR807/404.html new file mode 100644 index 00000000..27cb2f94 --- /dev/null +++ b/previews/PR807/404.html @@ -0,0 +1,22 @@ + + + + + + 404 | Rasters.jl + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/previews/PR807/api.html b/previews/PR807/api.html new file mode 100644 index 00000000..960b9fe4 --- /dev/null +++ b/previews/PR807/api.html @@ -0,0 +1,410 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Index

Reference - Exported functions

Rasters.Rasters Module

source

Rasters.AbstractRaster Type
julia
AbstractRaster <: DimensionalData.AbstractDimArray

Abstract supertype for objects that wrap an array (or location of an array) and metadata about its contents. It may be memory or hold a FileArray, which holds the filename, and is only opened when required.

AbstractRasters inherit from AbstractDimArray from DimensionalData.jl. They can be indexed as regular Julia arrays or with DimensionalData.jl Dimensions. They will plot as a heatmap in Plots.jl with correct coordinates and labels, even after slicing with getindex or view. getindex on a AbstractRaster will always return a memory-backed Raster.

source

Rasters.AbstractRasterSeries Type
julia
AbstractRasterSeries <: DimensionalData.AbstractDimensionalArray

Abstract supertype for high-level DimensionalArray that hold RasterStacks, Rasters, or the paths they can be loaded from. RasterSeries are indexed with dimensions as with a AbstractRaster. This is useful when you have multiple files containing rasters or stacks of rasters spread over dimensions like time and elevation.

As much as possible, implementations should facilitate loading entire directories and detecting the dimensions from metadata.

This allows syntax like below for a series of stacks of arrays:

julia
RasterSeries[Time(Near(DateTime(2001, 1))][:temp][Y(Between(70, 150)), X(Between(-20,20))] |> plot`

RasterSeries is the concrete implementation.

source

Rasters.AbstractRasterStack Type
julia
AbstractRasterStack

Abstract supertype for objects that hold multiple AbstractRasters that share spatial dimensions.

They are NamedTuple-like structures that may either contain NamedTuple of AbstractRasters, string paths that will load AbstractRasters, or a single path that points to a file containing multiple layers, like NetCDF or HDF5. Use and syntax is similar or identical for all cases.

AbstractRasterStack can hold layers that share some or all of their dimensions. They cannot have the same dimension with different length or spatial extent as another layer.

getindex on an AbstractRasterStack generally returns a memory backed standard Raster. raster[:somelayer] |> plot plots the layers array, while raster[:somelayer, X(1:100), Band(2)] |> plot will plot the subset without loading the whole array.

getindex on an AbstractRasterStack with a key returns another stack with getindex applied to all the arrays in the stack.

source

Rasters.Band Type
julia
Band <: Dimension
+
+Band(val=:)

Band Dimension for multi-band rasters.

Example:

julia
banddim = Band(10:10:100)
+# Or
+val = A[Band(1)]
+# Or
+mean(A; dims=Band)

source

Rasters.Mapped Type
julia
Mapped <: AbstractProjected
+
+Mapped(order, span, sampling, crs, mappedcrs)
+Mapped(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs=nothing, mappedcrs)

An AbstractSampled Lookup, where the dimension index has been mapped to another projection, usually lat/lon or EPSG(4326). Mapped matches the dimension format commonly used in netcdf files.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

The mapped dimension index will be used as for Sampled, but to save in another format the underlying crs may be used to convert it.

source

Rasters.Projected Type
julia
Projected <: AbstractProjected
+
+Projected(order, span, sampling, crs, mappedcrs)
+Projected(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs, mappedcrs=nothing)

An AbstractSampled Lookup with projections attached.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

If both crs and mappedcrs fields contain CRS data (in a GeoFormat wrapper from GeoFormatTypes.jl) the selector inputs and plot axes will be converted from and to the specified mappedcrs projection automatically. A common use case would be to pass mappedcrs=EPSG(4326) to the constructor when loading eg. a GDALarray:

julia
GDALarray(filename; mappedcrs=EPSG(4326))

The underlying crs will be detected by GDAL.

If mappedcrs is not supplied (ie. mappedcrs=nothing), the base index will be shown on plots, and selectors will need to use whatever format it is in.

source

Rasters.Raster Type
julia
Raster <: AbstractRaster
+
+Raster(filepath::String; kw...)
+Raster(A::AbstractDimArray; kw...)
+Raster(A::AbstractArray, dims; kw...)

A generic AbstractRaster for spatial/raster array data. It can hold either memory-backed arrays or, if lazy=true, a FileArray, which stores the String path to an unopened file.

If lazy=true, the file will only be opened lazily when it is indexed with getindex or when read(A) is called. Broadcasting, taking a view, reversing, and most other methods will not load data from disk; they will be applied later, lazily.

Arguments

  • dims: Tuple of Dimensions needed when an AbstractArray is used.

Keywords

  • name: a Symbol name for the array, which will also retrieve the, alphabetically first, named layer if Raster is used on a multi-layered file like a NetCDF. If instead RasterStack is used to read the multi-layered file, by default, all variables will be added to the stack.

  • group: the group in the dataset where name can be found. Only needed for nested datasets. A String or Symbol will select a single group. Pairs can also used to access groups at any nested depth, i.e group=:group1 => :group2 => :group3.

  • missingval: value reprsenting missing data, normally detected from the file. Set manually when you know the value is not specified or is incorrect. This will not change any values in the raster, it simply assigns which value is treated as missing. To replace all of the missing values in the raster, use replace_missing.

  • metadata: Dict or Metadata object for the array, or NoMetadata().

  • crs: the coordinate reference system of the objects XDim/YDim dimensions. Only set this if you know the detected crs is incorrect, or it is not present in the file. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed mode GeoFormat object, like EPSG(4326).

  • mappedcrs: the mapped coordinate reference system of the objects XDim/YDim dimensions. for Mapped lookups these are the actual values of the index. For Projected lookups this can be used to index in eg. EPSG(4326) lat/lon values, having it converted automatically. Only set this if the detected mappedcrs in incorrect, or the file does not have a mappedcrs, e.g. a tiff. The mappedcrs is expected to be a GeoFormatTypes.jl CRS or Mixed mode GeoFormat type.

  • refdims: Tuple of position Dimensions the array was sliced from, defaulting to (). Usually not needed.

When a filepath String is used:

  • dropband: drop single band dimensions when creating stacks from filenames. true by default.

  • lazy: A Bool specifying if to load data lazily from disk. false by default.

  • replace_missing: replace missingval with missing. This is done lazily if lazy=true. Note that currently for NetCDF and GRIB files replace_missing is always true. In future replace_missing=false will also work for these data sources.

  • source: Usually automatically detected from filepath extension. To manually force, a Symbol can be passed :gdal, :netcdf, :grd, :grib. The internal Rasters.Source objects, such as Rasters.GDALsource(), Rasters.GRIBsource() or Rasters.NCDsource() can also be used.

  • write: defines the default write keyword value when calling open on the Raster. false by default. Only makes sense to use when lazy=true.

When A is an AbstractDimArray:

  • data: can replace the data in an existing AbstractRaster

source

Rasters.RasterSeries Type
julia
RasterSeries <: AbstractRasterSeries
+
+RasterSeries(rasters::AbstractArray{<:AbstractRaster}, dims; [refdims])
+RasterSeries(stacks::AbstractArray{<:AbstractRasterStack}, dims; [refdims]) 
+
+RasterSeries(paths::AbstractArray{<:AbstractString}, dims; child, duplicate_first, kw...)
+RasterSeries(path:::AbstractString, dims; ext, separator, child, duplicate_first, kw...)

Concrete implementation of AbstractRasterSeries.

A RasterSeries is an array of Rasters or RasterStacks, along some dimension(s).

Existing Raster RasterStack can be wrapped in a RasterSeries, or new files can be loaded from an array of String or from a single String.

A single String can refer to a whole directory, or the name of a series of files in a directory, sharing a common stem. The differnce between the filenames can be used as the lookup for the series.

For example, with some tifs at these paths :

"series_dir/myseries_2001-01-01T00:00:00.tif"
+"series_dir/myseries_2002-01-01T00:00:00.tif"

We can load a RasterSeries with a DateTime lookup:

julia
julia> ser = RasterSeries("series_dir/myseries.tif", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

The DateTime suffix is parsed from the filenames. Using Ti(Int) would try to parse integers instead.

Just using the directory will also work, unless there are other files mixed in it:

julia
julia> ser = RasterSeries("series_dir", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

Arguments

  • dims: series dimension/s.

Keywords

When loading a series from a Vector of String paths or a single String path:

  • child: constructor of child objects for use when filenames are passed in, can be Raster or RasterStack. Defaults to Raster.

  • duplicate_first::Bool: wether to duplicate the dimensions and metadata of the first file with all other files. This can save load time with a large series where dimensions are identical. false by default.

  • lazy: A Bool specifying if to load data lazily from disk. false by default.

  • kw: keywords passed to the child constructor Raster or RasterStack.

When loading a series from a single String path:

  • separator: separator used to split lookup elements from the rest of a filename. '_' by default.

Others:

  • refdims: existing reference dimension/s, normally not required.

source

Rasters.RasterStack Type
julia
RasterStack <: AbstrackRasterStack
+
+RasterStack(data...; name, kw...)
+RasterStack(data::Union{Vector,Tuple}; name, kw...)
+RasterStack(data::NamedTuple; kw...))
+RasterStack(data::RasterStack; kw...)
+RasterStack(data::Raster; layersfrom=Band, kw...)
+RasterStack(filepath::AbstractString; kw...)

Load a file path or a NamedTuple of paths as a RasterStack, or convert arguments, a Vector or NamedTuple of Rasters to RasterStack.

Arguments

  • data: A NamedTuple of Rasters or String, or a Vector, Tuple or splatted arguments of Raster. The latter options must pass a name keyword argument.

  • filepath: A file (such as netcdf or tif) to be loaded as a stack, or a directory path containing multiple files.

Keywords

  • name: Used as stack layer names when a Tuple, Vector or splat of Raster is passed in. Has no effect when NameTuple is used - the NamedTuple keys are the layer names.

  • group: the group in the dataset where name can be found. Only needed for nested datasets. A String or Symbol will select a single group. Pairs can also used to access groups at any nested depth, i.e group=:group1 => :group2 => :group3.

  • metadata: A Dict or DimensionalData.Metadata object.

  • missingval: a single value for all layers or a NamedTuple of missingval for each layer. nothing specifies no missing value.

  • crs: the coordinate reference system of the objects XDim/YDim dimensions. Only set this if you know the detected crs is incorrect, or it is not present in the file. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed mode GeoFormat object, like EPSG(4326).

  • mappedcrs: the mapped coordinate reference system of the objects XDim/YDim dimensions. for Mapped lookups these are the actual values of the index. For Projected lookups this can be used to index in eg. EPSG(4326) lat/lon values, having it converted automatically. Only set this if the detected mappedcrs in incorrect, or the file does not have a mappedcrs, e.g. a tiff. The mappedcrs is expected to be a GeoFormatTypes.jl CRS or Mixed mode GeoFormat type.

  • refdims: Tuple of Dimension that the stack was sliced from.

For when one or multiple filepaths are used:

  • dropband: drop single band dimensions when creating stacks from filenames. true by default.

  • lazy: A Bool specifying if to load data lazily from disk. false by default.

  • replace_missing: replace missingval with missing. This is done lazily if lazy=true. Note that currently for NetCDF and GRIB files replace_missing is always true. In future replace_missing=false will also work for these data sources.

  • source: Usually automatically detected from filepath extension. To manually force, a Symbol can be passed :gdal, :netcdf, :grd, :grib. The internal Rasters.Source objects, such as Rasters.GDALsource(), Rasters.GRIBsource() or Rasters.NCDsource() can also be used.

For when a single Raster is used:

  • layersfrom: Dimension to source stack layers from if the file is not already multi-layered. nothing is default, so that a single RasterStack(raster) is a single layered stack. RasterStack(raster; layersfrom=Band) will use the bands as layers.
julia
files = (temp="temp.tif", pressure="pressure.tif", relhum="relhum.tif")
+stack = RasterStack(files; mappedcrs=EPSG(4326))
+stack[:relhum][Lat(Contains(-37), Lon(Contains(144))

source

DimensionalData.modify Method
julia
modify(f, series::AbstractRasterSeries)

Apply function f to the data of the child object. If the child is an AbstractRasterStack the function will be passed on to its child AbstractRasters.

f must return an identically sized array.

This method triggers a complete rebuild of all objects, and disk based objects will be transferred to memory.

An example of the usefulnesss of this is for swapping out array backend for an entire series to CuArray from CUDA.jl to copy data to a GPU.

source

GeoInterface.crs Method
julia
crs(x::Raster)

Get the projected coordinate reference system of a Y or X Dimension, or of the Y/X dims of an AbstractRaster.

For Mapped lookup this may be nothing as there may be no projected coordinate reference system at all. See setcrs to set it manually.

source

Rasters.aggregate Function
julia
aggregate(method, object, scale; filename, progress, skipmissing)

Aggregate a Raster, or all arrays in a RasterStack or RasterSeries, by scale using method.

Arguments

  • method: a function such as mean or sum that can combine the value of multiple cells to generate the aggregated cell, or a Locus like Start() or Center() that specifies where to sample from in the interval.

  • object: Object to aggregate, like AbstractRasterSeries, AbstractStack, AbstractRaster or Dimension.

  • scale: the aggregation factor, which can be an integer, a tuple of integers for each dimension, or any Dimension, Selector or Int combination you can usually use in getindex. Using a Selector will determine the scale by the distance from the start of the index.

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

  • skipmissingval: if true, any missingval will be skipped during aggregation, so that only areas of all missing values will be aggregated to missingval. If false, any aggregated area containing a missingval will be assigned missingval.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

  • progress: show a progress bar, true by default, false to hide.

Example

julia
using Rasters, RasterDataSources, Statistics, Plots
+import ArchGDAL
+using Rasters: Center
+st = read(RasterStack(WorldClim{Climate}; month=1))
+ag = aggregate(Center(), st, (Y(20), X(20)); skipmissingval=true, progress=false)
+plot(ag)
+savefig("build/aggregate_example.png"); nothing
+# output

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

Rasters.aggregate! Method
julia
aggregate!(method, dst::AbstractRaster, src::AbstractRaster, scale; skipmissingval=false)

Aggregate array src to array dst by scale, using method.

Arguments

  • method: a function such as mean or sum that can combine the value of multiple cells to generate the aggregated cell, or a Locus like Start() or Center() that species where to sample from in the interval.

  • scale: the aggregation factor, which can be an integer, a tuple of integers for each dimension, or any Dimension, Selector or Int combination you can usually use in getindex. Using a Selector will determine the scale by the distance from the start of the index in the src array.

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

  • progress: show a progress bar.

  • skipmissingval: if true, any missingval will be skipped during aggregation, so that only areas of all missing values will be aggregated to missingval. If false, any aggregated area containing a missingval will be assigned missingval.

Note: currently it is much faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

Rasters.boolmask Function
julia
boolmask(obj::Raster; [missingval])
+boolmask(obj; [to, res, size])
+boolmask(obj::RasterStack; alllayers=true, kw...)

Create a mask array of Bool values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted.

The array returned from calling boolmask on a AbstractRaster is a Raster with the same dimensions as the original array and a missingval of false.

Arguments

  • a Raster or one or multiple geometries. Geometries can be a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Raster / RasterStack Keywords

  • invert: invert the mask, so that areas no missing in with are masked, and areas missing in with are masked.

  • missingval: The missing value of the source array, with default missingval(raster).

Keywords

  • alllayers: if true a mask is taken for all layers, otherwise only the first layer is used. Defaults to true

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from the geometries, Additionally, when no to object or an Extent is passed for to, the size or res keyword must also be used.

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

  • shape: Force data to be treated as :polygon, :line or :point geometries. using points or lines as polygons may have unexpected results.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the polygon :touches the pixel, or that are completely :inside the polygon. The default is :center.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

  • threaded: run operations in parallel, false by default. In some circumstances threaded can give large speedups over single-threaded operation. This can be true for complicated geometries written into low-resolution rasters, but may not be for simple geometries with high-resolution rasters. With very large rasters threading may be counter productive due to excessive memory use. Caution should also be used: threaded should not be used in in-place functions writing to BitArray or other arrays where race conditions can occur.

  • progress: show a progress bar, true by default, false to hide.

And specifically for shape=:polygon:

  • boundary: include pixels where the :center is inside the polygon, where the line :touches the pixel, or that are completely :inside inside the polygon. The default is :center.

For tabular data, feature collections and other iterables

  • collapse: if true, collapse all geometry masks into a single mask. Otherwise return a Raster with an additional geometry dimension, so that each slice along this axis is the mask of the geometry opbject of each row of the table, feature in the feature collection, or just each geometry in the iterable.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+boolmask(wc) |> plot
+
+savefig("build/boolmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.cellarea Method
julia
cellarea([method], x)

Gives the approximate area of each gridcell of x. By assuming the earth is a sphere, it approximates the true size to about 0.1%, depending on latitude.

Run using ArchGDAL to make this method fully available.

method can be Spherical(; radius) (the default) or Planar().

  • Spherical will compute cell area on the sphere, by transforming all points back to long-lat. You can specify the radius by the radius keyword argument here. By default, this is 6371008.8, the mean radius of the Earth.

  • Planar will compute cell area in the plane of the CRS you have chosen. Be warned that this will likely be incorrect for non-equal-area projections.

Example

julia
using Rasters, ArchGDAL, Rasters.Lookups
+xdim = X(Projected(90.0:10.0:120; sampling=Intervals(Start()), crs=EPSG(4326)))
+ydim = Y(Projected(0.0:10.0:50; sampling=Intervals(Start()), crs=EPSG(4326)))
+myraster = rand(xdim, ydim)
+cs = cellarea(myraster)
+
+# output
+╭───────────────────────╮
+4×6 Raster{Float64,2} │
+├───────────────────────┴─────────────────────────────────────────────────── dims ┐
+ X Projected{Float64} 90.0:10.0:120.0 ForwardOrdered Regular Intervals{Start},
+ Y Projected{Float64} 0.0:10.0:50.0 ForwardOrdered Regular Intervals{Start}
+├───────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (90.0, 130.0), Y = (0.0, 60.0))
+
+  crs: EPSG:4326
+└─────────────────────────────────────────────────────────────────────────────────┘
+  0.0        10.0        20.0        30.0            40.0      50.0
+  90.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 100.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 110.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 120.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.classify Function
julia
classify(x, pairs; lower=(>=), upper=(<), others=nothing)
+classify(x, pairs...; lower, upper, others)

Create a new array with values in x classified by the values in pairs.

pairs can hold tuples fo values (2, 3), a Fix2 function e.g. <=(1), a Tuple of Fix2 e.g. (>=(4), <(7)), or an IntervalSets.jl interval, e.g. 3..9 or OpenInterval(10, 12). pairs can also be a n * 3 matrix where each row is lower bounds, upper bounds, replacement.

If tuples or a Matrix are used, the lower and upper keywords define how the lower and upper boundaries are chosen.

If others is set other values not covered in pairs will be set to that values.

Arguments

  • x: a Raster or RasterStack

  • pairs: each pair contains a value and a replacement, a tuple of lower and upper range and a replacement, or a Tuple of Fix2 like (>(x), <(y).

Keywords

  • lower: Which comparison (< or <=) to use for lower values, if Fix2 are not used.

  • upper: Which comparison (> or >=) to use for upper values, if Fix2 are not used.

  • others: A value to assign to all values not included in pairs. Passing nothing (the default) will leave them unchanged.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :tavg; month=1)
+classes = <=(15) => 10,
+          15..25 => 20,
+          25..35 => 30,
+          >(35) => 40
+classified = classify(A, classes; others=0, missingval=0)
+plot(classified; c=:magma)
+
+savefig("build/classify_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.classify! Method
julia
classify!(x, pairs...; lower, upper, others)
+classify!(x, pairs; lower, upper, others)

Classify the values of x in-place, by the values in pairs.

If Fix2 is not used, the lower and upper keywords

If others is set other values not covered in pairs will be set to that values.

Arguments

  • x: a Raster or RasterStack

  • pairs: each pair contains a value and a replacement, a tuple of lower and upper range and a replacement, or a Tuple of Fix2 like (>(x), <(y).

Keywords

  • lower: Which comparison (< or <=) to use for lower values, if Fix2 are not used.

  • upper: Which comparison (> or >=) to use for upper values, if Fix2 are not used.

  • others: A value to assign to all values not included in pairs. Passing nothing (the default) will leave them unchanged.

Example

classify! to disk, with key steps:

  • copying a tempory file so we don't write over the RasterDataSources.jl version.

  • use open with write=true to open the file with disk-write permissions.

  • use Float32 like 10.0f0 for all our replacement values and other, because the file is stored as Float32. Attempting to write some other type will fail.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+# Download and copy the file
+filename = getraster(WorldClim{Climate}, :tavg; month=6)
+tempfile = tempname() * ".tif"
+cp(filename, tempfile)
+# Define classes
+classes = (5, 15) => 10,
+          (15, 25) => 20,
+          (25, 35) => 30,
+          >=(35) => 40
+# Open the file with write permission
+open(Raster(tempfile); write=true) do A
+    classify!(A, classes; others=0)
+end
+# Open it again to plot the changes
+plot(Raster(tempfile); c=:magma)
+
+savefig("build/classify_bang_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.combine Method
julia
combine(A::AbstracRasterSeries; [dims], [lazy]) => Raster

Combine a RasterSeries along some dimension/s, creating a new Raster or RasterStack, depending on the contents of the series.

If dims are passed, only the specified dimensions will be combined with a RasterSeries returned, unless dims is all the dims in the series.

If lazy, concatenate lazily. The default is to concatenate lazily for lazy Rasters and eagerly otherwise.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.convertlookup Method
julia
convertlookup(dstlookup::Type{<:Lookup}, x)

Convert the dimension lookup between Projected and Mapped. Other dimension lookups pass through unchanged.

This is used to e.g. save a netcdf file to GeoTiff.

source

Rasters.coverage! Method
julia
coverage!(A, geom; [mode, scale])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

  • mode: method for combining multiple geometries - union or sum.

    • union (the default) gives the areas covered by all geometries. Usefull in spatial coverage where overlapping regions should not be counted twice. The returned raster will contain Float64 values between 0.0 and 1.0.

    • sum gives the summed total of the areas covered by all geometries, as in taking the sum of running coverage separately on all geometries. The returned values are positive Float64.

    For a single geometry, the mode keyword has no effect - the result is the same.

  • scale: Integer scale of pixel subdivision. The default of 10 means each pixel has 10 x 10 or 100 points that contribute to coverage. Using 100 means 10,000 points contribute. Performance will decline as scale increases. Memory use will grow by scale^2 when mode=:union.

  • threaded: run operations in parallel, false by default. In some circumstances threaded can give large speedups over single-threaded operation. This can be true for complicated geometries written into low-resolution rasters, but may not be for simple geometries with high-resolution rasters. With very large rasters threading may be counter productive due to excessive memory use. Caution should also be used: threaded should not be used in in-place functions writing to BitArray or other arrays where race conditions can occur.

  • progress: show a progress bar, true by default, false to hide.

  • vebose: whether to print messages about potential problems. true by default.

source

Rasters.coverage Method
julia
coverage(mode, geom; [to, res, size, scale, verbose, progress])
+coverage(geom; [to, mode, res, size, scale, verbose, progress])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

  • mode: method for combining multiple geometries - union or sum.

    • union (the default) gives the areas covered by all geometries. Usefull in spatial coverage where overlapping regions should not be counted twice. The returned raster will contain Float64 values between 0.0 and 1.0.

    • sum gives the summed total of the areas covered by all geometries, as in taking the sum of running coverage separately on all geometries. The returned values are positive Float64.

    For a single geometry, the mode keyword has no effect - the result is the same.

  • scale: Integer scale of pixel subdivision. The default of 10 means each pixel has 10 x 10 or 100 points that contribute to coverage. Using 100 means 10,000 points contribute. Performance will decline as scale increases. Memory use will grow by scale^2 when mode=:union.

  • threaded: run operations in parallel, false by default. In some circumstances threaded can give large speedups over single-threaded operation. This can be true for complicated geometries written into low-resolution rasters, but may not be for simple geometries with high-resolution rasters. With very large rasters threading may be counter productive due to excessive memory use. Caution should also be used: threaded should not be used in in-place functions writing to BitArray or other arrays where race conditions can occur.

  • progress: show a progress bar, true by default, false to hide.

  • vebose: whether to print messages about potential problems. true by default.

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from the geometries, Additionally, when no to object or an Extent is passed for to, the size or res keyword must also be used.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

source

Rasters.crop Function
julia
crop(x; to, touches=false, [geometrycolumn])
+crop(xs...; to)

Crop one or multiple AbstractRaster or AbstractRasterStack x to match the size of the object to, or smallest of any dimensions that are shared.

crop is lazy, using a view into the object rather than allocating new memory.

Keywords

  • to: the object to crop to. This can be a Raster or one or multiple geometries. Geometries can be a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified. If no to keyword is passed, the smallest shared area of all xs is used.

  • touches: true or false. Whether to use Touches wraper on the object extent. When lines need to be included in e.g. zonal statistics, true should be used.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

As crop is lazy, filename and suffix keywords are not used.

Example

Crop to another raster:

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out New Zealand from the evenness raster
+nz_bounds = X(165 .. 180), Y(-50 .. -32)
+nz_evenness = evenness[nz_bounds...]
+
+# Crop range to match evenness
+nz_range = crop(rnge; to=nz_evenness)
+plot(nz_range)
+
+savefig("build/nz_crop_example.png")
+nothing
+
+# output

Crop to a polygon:

julia
using Rasters, RasterDataSources, Plots, Dates, Shapefile, Downloads
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+shp = Shapefile.Handle(shapefile_name).shapes[6]
+
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+argentina_evenness = crop(evenness; to=shp)
+plot(argentina_evenness)
+
+savefig("build/argentina_crop_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.disaggregate Function
julia
disaggregate(method, object, scale; filename, progress, keys)

Disaggregate array, or all arrays in a stack or series, by some scale.

Arguments

  • method: a function such as mean or sum that can combine the value of multiple cells to generate the aggregated cell, or a Locus like Start() or Center() that species where to sample from in the interval.

  • object: Object to aggregate, like AbstractRasterSeries, AbstractStack, AbstractRaster or a Dimension.

  • scale: the aggregation factor, which can be an integer, a tuple of integers for each dimension, or any Dimension, Selector or Int combination you can usually use in getindex. Using a Selector will determine the scale by the distance from the start of the index.

Keywords

  • progress: show a progress bar.

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

Rasters.disaggregate! Method
julia
disaggregate!(method, dst::AbstractRaster, src::AbstractRaster, filename, scale)

Disaggregate array src to array dst by some scale, using method.

  • method: a function such as mean or sum that can combine the value of multiple cells to generate the aggregated cell, or a Locus like Start() or Center() that species where to sample from in the interval.

  • scale: the aggregation factor, which can be an integer, a tuple of integers for each dimension, or any Dimension, Selector or Int combination you can usually use in getindex. Using a Selector will determine the scale by the distance from the start of the index in the src array.

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

Rasters.extend Function
julia
extend(xs...; [to])
+extend(xs; [to])
+extend(x::Union{AbstractRaster,AbstractRasterStack}; to, kw...)

Extend one or multiple AbstractRaster to match the area covered by all xs, or by the keyword argument to.

Keywords

  • to: the Raster or dims to extend to. If no to keyword is passed, the largest shared area of all xs is used.

  • touches: true or false. Whether to use Touches wrapper on the object extent. When lines need to be included in e.g. zonal statistics, true shoudle be used.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out South America
+sa_bounds = X(-88 .. -32), Y(-57 .. 13)
+sa_evenness = evenness[sa_bounds...]
+
+# Extend range to match the whole-world raster
+sa_range = extend(sa_evenness; to=rnge)
+plot(sa_range)
+
+savefig("build/extend_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.extract Function
julia
extract(x, data; kw...)

Extracts the value of Raster or RasterStack at given points, returning an iterable of NamedTuple with properties for :geometry and raster or stack layer values.

Note that if objects have more dimensions than the length of the point tuples, sliced arrays or stacks will be returned instead of single values.

Arguments

  • x: a Raster or RasterStack to extract values from.

  • data: a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Keywords

  • geometry: include :geometry in returned NamedTuple, true by default.

  • index: include :index of the CartesianIndex in returned NamedTuple, false by default.

  • name: a Symbol or Tuple of Symbol corresponding to layer/s of a RasterStack to extract. All layers by default.

  • skipmissing: skip missing points automatically.

  • atol: a tolerance for floating point lookup values for when the Lookup contains Points. atol is ignored for Intervals.

geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

Example

Here we extract points matching the occurrence of the Mountain Pygmy Possum, Burramis parvus. This could be used to fit a species distribution model.

julia
using Rasters, RasterDataSources, ArchGDAL, GBIF2, CSV
+
+# Get a stack of BioClim layers, and replace missing values with `missing`
+st = RasterStack(WorldClim{BioClim}, (1, 3, 5, 7, 12)) |> replace_missing
+
+# Download some occurrence data
+obs = GBIF2.occurrence_search("Burramys parvus"; limit=5, year="2009")
+
+# use `extract` to get values for all layers at each observation point.
+# We `collect` to get a `Vector` from the lazy iterator.
+extract(st, obs; skipmissing=true)
+
+# output
+5-element Vector{NamedTuple{(:geometry, :bio1, :bio3, :bio5, :bio7, :bio12)}}:
+ (geometry = (0.21, 40.07), bio1 = 17.077084f0, bio3 = 41.20417f0, bio5 = 30.1f0, bio7 = 24.775f0, bio12 = 446.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.52, 40.37), bio1 = missing, bio3 = missing, bio5 = missing, bio7 = missing, bio12 = missing)
+ (geometry = (0.32, 40.24), bio1 = 16.321388f0, bio3 = 41.659454f0, bio5 = 30.029825f0, bio7 = 25.544561f0, bio12 = 480.0f0)

Note: passing in arrays, geometry collections or feature collections containing a mix of points and other geometries has undefined results.

source

Rasters.mappedbounds Function
julia
mappedbounds(x)

Get the bounds converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular bounds.

source

Rasters.mappedcrs Function
julia
mappedcrs(x)

Get the mapped coordinate reference system for the Y/X dims of an array.

In Projected lookup this is used to convert Selector values form the mappedcrs defined projection to the underlying projection, and to show plot axes in the mapped projection.

In Mapped lookup this is the coordinate reference system of the index values. See setmappedcrs to set it manually.

source

Rasters.mappedindex Function
julia
mappedindex(x)

Get the index value of a dimension converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular dim value.

source

Rasters.mask! Function
julia
mask!(x; with, missingval=missingval(A))

Mask A by the missing values of with, or by all values outside with if it is a polygon.

If with is a polygon, creates a new array where points falling outside the polygon have been replaced by missingval(A).

Return a new array with values of A masked by the missing values of with, or by a polygon.

Arguments

  • x: a Raster or RasterStack.

Keywords

  • with: another AbstractRaster, a AbstractVector of Tuple points, or any GeoInterface.jl AbstractGeometry. The coordinate reference system of the point must match crs(A).

  • invert: invert the mask, so that areas no missing in with are masked, and areas missing in with are masked.

  • missingval: the missing value to write to A in masked areas, by default missingval(A).

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask to match the size and projection.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(RasterStack(AWAP, (:tmin, :tmax); date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45), c=:imola)
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+mask!(awap; with=wc_mask)
+b = plot(awap; clims=(10, 45))
+
+savefig(a, "build/mask_bang_example_before.png");
+savefig(b, "build/mask_bang_example_after.png"); nothing
+
+# output

Before mask!:

After mask!:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.mask Method
julia
mask(A:AbstractRaster; with, missingval=missingval(A))
+mask(x; with)

Return a new array with values of A masked by the missing values of with, or by the shape of with, if with is a geometric object.

Arguments

  • x: a Raster or RasterStack

Keywords

  • with: an AbstractRaster, or any GeoInterface.jl compatible objects or table. The coordinate reference system of the point must match crs(A).

  • invert: invert the mask, so that areas no missing in with are masked, and areas missing in with are masked.

  • missingval: the missing value to use in the returned file.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

Geometry keywords

These can be used when with is a GeoInterface.jl compatible object:

  • shape: Force data to be treated as :polygon, :line or :point geometries. using points or lines as polygons may have unexpected results.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the polygon :touches the pixel, or that are completely :inside the polygon. The default is :center.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(Raster(AWAP, :tmax; date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45))
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+awap_masked = mask(awap; with=wc_mask)
+b = plot(awap_masked; clims=(10, 45))
+
+savefig(a, "build/mask_example_before.png");
+savefig(b, "build/mask_example_after.png"); nothing
+# output

Before mask:

After mask:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.missingmask Method
julia
missingmask(obj::Raster; kw...)
+missingmask(obj; [to, res, size, collapse])
+missingmask(obj::RasterStack; alllayers = true, kw...)

Create a mask array of missing and true values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted-

For AbstractRaster the default missingval is missingval(A), but others can be chosen manually.

The array returned from calling missingmask on a AbstractRaster is a Raster with the same size and fields as the original array.

Arguments

  • obj: a Raster or one or multiple geometries. Geometries can be a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Keywords

  • alllayers: if true a mask is taken for all layers, otherwise only the first layer is used. Defaults to true

  • invert: invert the mask, so that areas no missing in with are masked, and areas missing in with are masked.

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from the geometries, Additionally, when no to object or an Extent is passed for to, the size or res keyword must also be used.

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

  • shape: Force data to be treated as :polygon, :line or :point geometries. using points or lines as polygons may have unexpected results.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the polygon :touches the pixel, or that are completely :inside the polygon. The default is :center.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+missingmask(wc) |> plot
+
+savefig("build/missingmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.missingval Function
julia
missingval(x)

Returns the value representing missing data in the dataset

source

Rasters.mosaic! Method
julia
mosaic!(f, x, regions...; missingval, atol)
+mosaic!(f, x, regions::Tuple; missingval, atol)

Combine regions in x using the function f.

Arguments

  • f a function (e.g. mean, sum, first or last) that is applied to values where regions overlap.

  • x: A Raster or RasterStack. May be a an opened disk-based Raster, the result will be written to disk. With the current algorithm, the read speed is slow.

  • regions: source objects to be joined. These should be memory-backed (use read first), or may experience poor performance. If all objects have the same extent, mosaic is simply a merge.

Keywords

  • missingval: Fills empty areas, and defualts to the `missingval/ of the first layer.

  • atol: Absolute tolerance for comparison between index values. This is often required due to minor differences in range values due to floating point error. It is not applied to non-float dimensions. A tuple of tolerances may be passed, matching the dimension order.

Example

Cut out Australia and Africa stacks, then combined them into a single stack.

julia
using Rasters, RasterDataSources, ArchGDAL, Statistics, Plots
+st = read(RasterStack(WorldClim{Climate}; month=1))
+aus = st[X=100.0 .. 160.0, Y=-50.0 .. -10.0]
+africa = st[X=-20.0 .. 60.0, Y=-40.0 .. 35.0]
+mosaic!(first, st, aus, africa)
+plot(st)
+savefig("build/mosaic_bang_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.mosaic Method
julia
mosaic(f, regions...; missingval, atol)
+mosaic(f, regions; missingval, atol)

Combine regions into a single raster.

Arguments

  • f: A reducing function (mean, sum, first, last etc.) for values where regions overlap.

  • regions: Iterable or splatted Raster or RasterStack.

Keywords

  • missingval: Fills empty areas, and defualts to the missingval of the first region.

  • atol: Absolute tolerance for comparison between index values. This is often required due to minor differences in range values due to floating point error. It is not applied to non-float dimensions. A tuple of tolerances may be passed, matching the dimension order.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

If your mosaic has has apparent line errors, increase the atol value.

Example

Here we cut out Australia and Africa from a stack, and join them with mosaic.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+st = RasterStack(WorldClim{Climate}; month=1);
+
+africa = st[X(-20.0 .. 60.0), Y(-40.0 .. 35.0)]
+a = plot(africa)
+
+aus = st[X(100.0 .. 160.0), Y(-50.0 .. -10.0)]
+b = plot(aus)
+
+# Combine with mosaic
+mos = mosaic(first, aus, africa)
+c = plot(mos)
+
+savefig(a, "build/mosaic_example_africa.png")
+savefig(b, "build/mosaic_example_aus.png")
+savefig(c, "build/mosaic_example_combined.png")
+nothing
+# output

Individual continents

Mosaic of continents

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.points Method
julia
points(A::AbstractRaster; dims=(YDim, XDim), ignore_missing) => Array{Tuple}

Returns a generator of the points in A for dimensions in dims, where points are a tuple of the values in each specified dimension index.

Keywords

  • dims the dimensions to return points from. The first slice of other layers will be used.

  • ignore_missing: wether to ignore missing values in the array when considering points. If true, all points in the dimensions will be returned, if false only the points that are not === missingval(A) will be returned.

The order of dims determines the order of the points.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.rasterize Function
julia
rasterize([reducer], data; geometrycolumn, kw...)

Rasterize a GeoInterface.jl compatable geometry or feature, or a Tables.jl table with a :geometry column of GeoInterface.jl objects, or points columns specified by geometrycolumn

Arguments

  • reducer: a reducing function to reduce the fill value for all geometries that cover or touch a pixel down to a single value. The default is last. Any that takes an iterable and returns a single value will work, including custom functions. However, there are optimisations for built-in methods including sum, first, last, minimum, maximum, extrema and Statistics.mean. These may be an order of magnitude or more faster than count is a special-cased as it does not need a fill value.

  • data: a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Keywords

These are detected automatically from data where possible.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from the geometries, Additionally, when no to object or an Extent is passed for to, the size or res keyword must also be used.

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

  • shape: Force data to be treated as :polygon, :line or :point geometries. using points or lines as polygons may have unexpected results.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the polygon :touches the pixel, or that are completely :inside the polygon. The default is :center.

  • fill: the value or values to fill a polygon with. A Symbol or tuple of Symbol will be used to retrieve properties from features or column values from table rows. An array or other iterable will be used for each geometry, in order. fill can also be a function of the current value, e.g. x -> x + 1.

  • op: A reducing function that accepts two values and returns one, like min to minimum. For common methods this will be assigned for you, or is not required. But you can use it instead of a reducer as it will usually be faster.

  • shape: force data to be treated as :polygon, :line or :point, where possible Points can't be treated as lines or polygons, and lines may not work as polygons, but an attempt will be made.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

  • progress: show a progress bar, true by default, false to hide..

  • verbose: print information and warnings when there are problems with the rasterisation. true by default.

  • threaded: run operations in parallel, false by default. In some circumstances threaded can give large speedups over single-threaded operation. This can be true for complicated geometries written into low-resolution rasters, but may not be for simple geometries with high-resolution rasters. With very large rasters threading may be counter productive due to excessive memory use. Caution should also be used: threaded should not be used in in-place functions writing to BitArray or other arrays where race conditions can occur.

  • threadsafe: specify that custom reducer and/or op functions are thread-safe, in that the order of operation or blocking does not matter. For example, sum and maximum are thread-safe, because the answer is approximately (besides floating point error) the same after running on nested blocks, or on all the data. In contrast, median or last are not, because the blocking (median) or order (last) matters.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

Note on threading. Performance may be much better with threaded=false if reducer/op are not threadsafe. sum, prod, maximum, minimum count and mean (by combining sum and count) are threadsafe. If you know your algorithm is threadsafe, use threadsafe=true to allow all optimisations. Functions passed to fill are always threadsafe, and ignore the threadsafe argument.

Example

Rasterize a shapefile for China and plot, with a border.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for china
+china_border = Shapefile.Handle(shapefile_name).shapes[10]
+
+# Rasterize the border polygon
+china = rasterize(last, china_border; res=0.1, missingval=0, fill=1, boundary=:touches, progress=false)
+
+# And plot
+p = plot(china; color=:spring, legend=false)
+plot!(p, china_border; fillalpha=0, linewidth=0.6)
+
+savefig("build/china_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.rasterize! Function
julia
rasterize!([reducer], dest, data; kw...)

Rasterize the geometries in data into the Raster or RasterStack dest, using the values specified by fill.

Arguments

  • dest: a Raster or RasterStack to rasterize into.

  • reducer: a reducing function to reduce the fill value for all geometries that cover or touch a pixel down to a single value. The default is last. Any that takes an iterable and returns a single value will work, including custom functions. However, there are optimisations for built-in methods including sum, first, last, minimum, maximum, extrema and Statistics.mean. These may be an order of magnitude or more faster than count is a special-cased as it does not need a fill value.

  • data: a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Keywords

These are detected automatically from A and data where possible.

  • fill: the value or values to fill a polygon with. A Symbol or tuple of Symbol will be used to retrieve properties from features or column values from table rows. An array or other iterable will be used for each geometry, in order. fill can also be a function of the current value, e.g. x -> x + 1.

  • op: A reducing function that accepts two values and returns one, like min to minimum. For common methods this will be assigned for you, or is not required. But you can use it instead of a reducer as it will usually be faster.

  • shape: force data to be treated as :polygon, :line or :point, where possible Points can't be treated as lines or polygons, and lines may not work as polygons, but an attempt will be made.

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

  • progress: show a progress bar, true by default, false to hide..

  • verbose: print information and warnings when there are problems with the rasterisation. true by default.

  • threaded: run operations in parallel, false by default. In some circumstances threaded can give large speedups over single-threaded operation. This can be true for complicated geometries written into low-resolution rasters, but may not be for simple geometries with high-resolution rasters. With very large rasters threading may be counter productive due to excessive memory use. Caution should also be used: threaded should not be used in in-place functions writing to BitArray or other arrays where race conditions can occur.

  • threadsafe: specify that custom reducer and/or op functions are thread-safe, in that the order of operation or blocking does not matter. For example, sum and maximum are thread-safe, because the answer is approximately (besides floating point error) the same after running on nested blocks, or on all the data. In contrast, median or last are not, because the blocking (median) or order (last) matters.

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from the geometries, Additionally, when no to object or an Extent is passed for to, the size or res keyword must also be used.

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

  • shape: Force data to be treated as :polygon, :line or :point geometries. using points or lines as polygons may have unexpected results.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the polygon :touches the pixel, or that are completely :inside the polygon. The default is :center.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, GeoInterface, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for indonesia
+indonesia_border = Shapefile.Handle(shapefile_name).shapes[1]
+
+# Make an empty EPSG 4326 projected Raster of the area of Indonesia
+dimz = X(Projected(90.0:0.1:145; sampling=Intervals(), crs=EPSG(4326))),
+       Y(Projected(-15.0:0.1:10.9; sampling=Intervals(), crs=EPSG(4326)))
+
+A = zeros(UInt32, dimz; missingval=UInt32(0))
+
+# Rasterize each indonesian island with a different number. The islands are
+# rings of a multi-polygon, so we use `GI.getring` to get them all separately.
+islands = collect(GeoInterface.getring(indonesia_border))
+rasterize!(last, A, islands; fill=1:length(islands), progress=false)
+
+# And plot
+p = plot(Rasters.trim(A); color=:spring)
+plot!(p, indonesia_border; fillalpha=0, linewidth=0.7)
+
+savefig("build/indonesia_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.replace_missing Method
julia
replace_missing(a::AbstractRaster, newmissingval)
+replace_missing(a::AbstractRasterStack, newmissingval)

Replace missing values in the array or stack with a new missing value, also updating the missingval field/s.

Keywords

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

Example

julia
using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{Climate}, :prec; month=1) |> replace_missing
+missingval(A)
+# output
+missing

source

Rasters.reproject Method
julia
reproject(source::GeoFormat, target::GeoFormat, dim::Dimension, val)

reproject uses ArchGDAL.reproject, but implemented for a reprojecting a value array of values, a single dimension at a time.

source

Rasters.reproject Method
julia
reproject(obj; crs)

Reproject the lookups of obj to a different crs.

This is a lossless operation for the raster data, as only the lookup values change. This is only possible when the axes of source and destination projections are aligned: the change is usually from a Regular and an Irregular lookup spans.

For converting between projections that are rotated, skewed or warped in any way, use resample.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are silently returned without modification.

Arguments

  • obj: a Lookup, Dimension, Tuple of Dimension, Raster or RasterStack.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

source

Rasters.resample Method
julia
resample(x; kw...)
+resample(xs...; to=first(xs), kw...)

resample uses warp (which uses GDALs gdalwarp) to resample a Raster or RasterStack to a new resolution and optionally new crs, or to snap to the bounds, resolution and crs of the object to.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are iteratively resampled with GDAL and joined back into a single array.

If projections can be converted for each axis independently, it may be faster and more accurate to use reproject.

Run using ArchGDAL to make this method available.

Arguments

  • x: the object/s to resample.

Keywords

  • to: a Raster, RasterStack, Tuple of Dimension or Extents.Extent. If no to object is provided the extent will be calculated from x,

  • res: the resolution of the dimensions (often in meters or degrees), a Real or Tuple{<:Real,<:Real}. Only required when to is not used or is an Extents.Extent, and size is not used.

  • size: the size of the output array, as a Tuple{Int,Int} or single Int for a square. Only required when to is not used or is an Extents.Extent, and res is not used.

  • crs: a crs which will be attached to the resulting raster when to not passed or is an Extent. Otherwise the crs from to is used.

  • method: A Symbol or String specifying the method to use for resampling. From the docs for gdalwarp:

    • :near: nearest neighbour resampling (default, fastest algorithm, worst interpolation quality).

    • :bilinear: bilinear resampling.

    • :cubic: cubic resampling.

    • :cubicspline: cubic spline resampling.

    • :lanczos: Lanczos windowed sinc resampling.

    • :average: average resampling, computes the weighted average of all non-NODATA contributing pixels. rms root mean square / quadratic mean of all non-NODATA contributing pixels (GDAL >= 3.3)

    • :mode: mode resampling, selects the value which appears most often of all the sampled points.

    • :max: maximum resampling, selects the maximum value from all non-NODATA contributing pixels.

    • :min: minimum resampling, selects the minimum value from all non-NODATA contributing pixels.

    • :med: median resampling, selects the median value of all non-NODATA contributing pixels.

    • :q1: first quartile resampling, selects the first quartile value of all non-NODATA contributing pixels.

    • :q3: third quartile resampling, selects the third quartile value of all non-NODATA contributing pixels.

    • :sum: compute the weighted sum of all non-NODATA contributing pixels (since GDAL 3.1)

    Where NODATA values are set to missingval.

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

Note:

  • GDAL may cause some unexpected changes in the raster, such as changing the crs type from EPSG to WellKnownText (it will represent the same CRS).

Example

Resample a WorldClim layer to match an EarthEnv layer:

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+B = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+
+a = plot(A)
+b = plot(resample(A; to=B))
+
+savefig(a, "build/resample_example_before.png");
+savefig(b, "build/resample_example_after.png"); nothing
+
+# output

Before resample:

After resample:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.setcrs Method
julia
setcrs(x, crs)

Set the crs of a Raster, RasterStack, Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

Rasters.setmappedcrs Method
julia
setmappedcrs(x, crs)

Set the mapped crs of a Raster, a RasterStack, a Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

Rasters.slice Method
julia
slice(A::Union{AbstractRaster,AbstractRasterStack,AbstracRasterSeries}, dims) => RasterSeries

Slice views along some dimension/s to obtain a RasterSeries of the slices.

For a Raster or RasterStack this will return a RasterSeries of Raster or RasterStack that are slices along the specified dimensions.

For a RasterSeries, the output is another series where the child objects are sliced and the series dimensions index is now of the child dimensions combined. slice on a RasterSeries with no dimensions will slice along the dimensions shared by both the series and child object.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.trim Method
julia
trim(x; dims::Tuple, pad::Int)

Trim missingval(x) from x for axes in dims, returning a view of x.

Arguments

  • x: A Raster or RasterStack. For stacks, all layers must having missing values for a pixel for it to be trimmed.

Keywords

  • dims: By default dims=(XDim, YDim), so that trimming keeps the area of X and Y that contains non-missing values along all other dimensions.

  • pad: The trimmed size will be padded by pad on all sides, although padding will not be added beyond the original extent of the array.

As trim is lazy, filename and suffix keywords are not used.

Example

Create trimmed layers of Australian habitat heterogeneity.

julia
using Rasters, RasterDataSources, Plots
+layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+
+# Roughly cut out australia
+ausbounds = X(100 .. 160), Y(-50 .. -10)
+aus = st[ausbounds...]
+a = plot(aus)
+
+# Trim missing values and plot
+b = plot(trim(aus))
+
+savefig(a, "build/trim_example_before.png");
+savefig(b, "build/trim_example_after.png"); nothing
+
+# output

Before trim:

After trim:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.warp Method
julia
warp(A::AbstractRaster, flags::Dict; kw...)

Gives access to the GDALs gdalwarp method given a Dict of flag => value arguments that can be converted to strings, or vectors where multiple space-separated arguments are required.

Arrays with additional dimensions not handled by GDAL (other than X, Y, Band) are sliced, warped, and then combined to match the original array dimensions. These slices will not be written to disk and loaded lazily at this stage - you will need to do that manually if required.

See the gdalwarp docs for a list of arguments.

Run using ArchGDAL to make this method available.

Keywords

  • filename: a filename to write to directly, useful for large files.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

Any additional keywords are passed to ArchGDAL.Dataset.

Example

This simply resamples the array with the :tr (output file resolution) and :r flags, giving us a pixelated version:

julia
using Rasters, RasterDataSources, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+a = plot(A)
+
+flags = Dict(
+    :tr => [2.0, 2.0],
+    :r => :near,
+)
+b = plot(warp(A, flags))
+
+savefig(a, "build/warp_example_before.png");
+savefig(b, "build/warp_example_after.png"); nothing
+
+# output

Before warp:

After warp:

In practise, prefer resample for this. But warp may be more flexible.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

Rasters.zonal Method
julia
zonal(f, x::Union{Raster,RasterStack}; of, kw...)

Calculate zonal statistics for the the zone of a Raster or RasterStack covered by the of object/s.

Arguments

  • f: any function that reduces an iterable to a single value, such as sum or Statistics.mean

  • x: A Raster or RasterStack

  • of: A DimTuple, Extent, a Raster or one or multiple geometries. Geometries can be a GeoInterface.jl AbstractGeometry, a nested Vector of AbstractGeometry, or a Tables.jl compatible object containing a :geometry column or points and values columns, in which case geometrycolumn must be specified.

Keywords

  • geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

These can be used when of is or contains (a) GeoInterface.jl compatible object(s):

  • shape: Force data to be treated as :polygon, :line or :point, where possible.

  • boundary: for polygons, include pixels where the :center is inside the polygon, where the line :touches the pixel, or that are completely :inside inside the polygon. The default is :center.

  • progress: show a progress bar, true by default, false to hide..

  • skipmissing: wether to apply f to the result of skipmissing(A) or not. If true f will be passed an iterator over the values, which loses all spatial information. if false f will be passes a masked Raster or RasterStack, and will be responsible for handling missing values itself. The default value is true.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Shapefile, DataFrames, Downloads, Statistics, Dates
+
+# Download a borders shapefile
+ne_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries"
+shp_url, dbf_url  = ne_url * ".shp", ne_url * ".dbf"
+shp_name, dbf_name = "country_borders.shp", "country_borders.dbf"
+isfile(shp_name) || Downloads.download(shp_url, shp_name)
+isfile(dbf_url) || Downloads.download(dbf_url, dbf_name)
+
+# Download and read a raster stack from WorldClim
+st = RasterStack(WorldClim{Climate}; month=Jan, lazy=false)
+
+# Load the shapes for world countries
+countries = Shapefile.Table(shp_name) |> DataFrame
+
+# Calculate the january mean of all climate variables for all countries
+january_stats = zonal(mean, st; of=countries, boundary=:touches, progress=false) |> DataFrame
+
+# Add the country name column (natural earth has some string errors it seems)
+insertcols!(january_stats, 1, :country => first.(split.(countries.ADMIN, r"[^A-Za-z ]")))
+
+# output
+258×8 DataFrame
+ Row │ country                       tmin       tmax       tavg       prec     
+     │ SubStrin                     Float32    Float32    Float32    Float64  
+─────┼──────────────────────────────────────────────────────────────────────────
+   1 │ Indonesia                      21.5447    29.1864    25.3656   271.063
+   2 │ Malaysia                       21.3087    28.4291    24.8688   273.381
+   3 │ Chile                           7.24534   17.9263    12.5858    78.1287
+   4 │ Bolivia                        17.2065    27.7454    22.4759   192.542
+   5 │ Peru                           15.0273    25.5504    20.2888   180.007
+   6 │ Argentina                      13.6751    27.6715    20.6732    67.1837
+   7 │ Dhekelia Sovereign Base Area    5.87126   15.8991    10.8868    76.25
+   8 │ Cyprus                          5.65921   14.6665    10.1622    97.4474
+
+ 252 │ Spratly Islands                25.0       29.2       27.05      70.5
+ 253 │ Clipperton Island              21.5       33.2727    27.4        6.0
+ 254 │ Macao S                        11.6694    17.7288    14.6988    28.0
+ 255 │ Ashmore and Cartier Islands   NaN        NaN        NaN        NaN
+ 256 │ Bajo Nuevo Bank               NaN        NaN        NaN        NaN
+ 257 │ Serranilla Bank               NaN        NaN        NaN        NaN
+ 258 │ Scarborough Reef              NaN        NaN        NaN        NaN
+                                                  3 columns and 243 rows omitted

source

Reference - Internal functions

Rasters.AbstractProjected Type
julia
AbstractProjected <: AbstractSampled

Abstract supertype for projected index lookups.

source

Rasters.FileArray Type
julia
FileArray{S} <: DiskArrays.AbstractDiskArray

Filearray is a DiskArrays.jl AbstractDiskArray. Instead of holding an open object, it just holds a filename string that is opened lazily when it needs to be read.

source

Rasters.FileStack Type
julia
FileStack{S,Na}
+
+FileStack{S,Na}(filename, types, sizes, eachchunk, haschunks, write)

A wrapper object that holds file pointer and size/chunking metadata for a multi-layered stack stored in a single file, typically netcdf or hdf5.

S is a backend type like NCDsource, and Na is a tuple of Symbol keys.

source

Rasters.OpenStack Type
julia
OpenStack{X,K}
+
+OpenStack{X,K}(dataset)

A wrapper for any stack-like opened dataset that can be indexed with Symbol keys to retrieve AbstractArray layers.

OpenStack is usually hidden from users, wrapped in a regular RasterStack passed as the function argument in open(stack) when the stack is contained in a single file.

X is a backend type like NCDsource, and K is a tuple of Symbol keys.

source

Rasters.RasterDiskArray Type
julia
RasterDiskArray <: DiskArrays.AbstractDiskArray

A basic DiskArrays.jl wrapper for objects that don't have one defined yet. When we open a FileArray it is replaced with a RasterDiskArray.

source

Base.open Method
julia
open(f, A::AbstractRaster; write=false)

open is used to open any lazy=true AbstractRaster and do multiple operations on it in a safe way. The write keyword opens the file in write lookup so that it can be altered on disk using e.g. a broadcast.

f is a method that accepts a single argument - an Raster object which is just an AbstractRaster that holds an open disk-based object. Often it will be a do block:

lazy=false (in-memory) rasters will ignore open and pass themselves to f.

julia
# A is an `Raster` wrapping the opened disk-based object.
+open(Raster(filepath); write=true) do A
+    mask!(A; with=maskfile)
+    A[I...] .*= 2
+    # ...  other things you need to do with the open file
+end

By using a do block to open files we ensure they are always closed again after we finish working with them.

source

Base.read! Method
julia
read!(src::Union{AbstractString,AbstractRaster}, dst::AbstractRaster)
+read!(src::Union{AbstractString,AbstractRasterStack}, dst::AbstractRasterStack)
+read!(scr::AbstractRasterSeries, dst::AbstractRasterSeries)

read! will copy the data from src to the object dst.

src can be an object or a file-path String.

source

Base.read Method
julia
read(A::AbstractRaster)
+read(A::AbstractRasterStack)
+read(A::AbstractRasterSeries)

read will move a Rasters.jl object completely to memory.

Keywords

  • checkmemory: If true (the default), check if there is enough memory for the operation. false will ignore memory needs.

source

Base.skipmissing Method
julia
skipmissing(itr::Raster)

Returns an iterable over the elements in a Raster object, skipping any values equal to either the missingval or missing.

source

Base.write Method
julia
Base.write(filepath::AbstractString, s::AbstractRasterSeries; kw...)

Write any AbstractRasterSeries to multiple files, guessing the backend from the file extension.

The lookup values of the series will be appended to the filepath (before the extension), separated by underscores.

All keywords are passed through to these Raster and RasterStack methods.

Keywords

  • chunks: a NTuple{N,Int} specifying the chunk size for each dimension. To specify only specific dimensions, a Tuple of Dimension wrapping Int or a NamedTuple of Int can be used. Other dimensions will have a chunk size of 1. true can be used to mean: use the original chunk size of the lazy Raster being written or X and Y of 256 by 256. false means don't use chunks at all.

  • ext: filename extension such as ".tiff" or ".nc". Used to specify specific files if only a directory path is used.

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

  • missingval: set the missing value (i.e. FillValue / nodataval) of the written raster, as Julias missing cannot be stored. If not passed in, missingval will be detected from metadata or a default will be chosen. For series with RasterStack child objects, this may be a NamedTuple, one for each layer.

  • source: Usually automatically detected from filepath extension. To manually force, a Symbol can be passed :gdal, :netcdf, :grd, :grib. The internal Rasters.Source objects, such as Rasters.GDALsource(), Rasters.GRIBsource() or Rasters.NCDsource() can also be used.

  • vebose: whether to print messages about potential problems. true by default.

source

Base.write Method
julia
Base.write(filename::AbstractString, s::AbstractRasterStack; kw...)

Write any AbstractRasterStack to one or multiple files, depending on the backend. Backend is guessed from the filename extension or forced with the source keyword.

If the source can't be saved as a stack-like object, individual array layers will be saved.

Keywords

  • chunks: a NTuple{N,Int} specifying the chunk size for each dimension. To specify only specific dimensions, a Tuple of Dimension wrapping Int or a NamedTuple of Int can be used. Other dimensions will have a chunk size of 1. true can be used to mean: use the original chunk size of the lazy Raster being written or X and Y of 256 by 256. false means don't use chunks at all.

  • ext: filename extension such as ".tiff" or ".nc". Used to specify specific files if only a directory path is used.

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

  • missingval: set the missing value (i.e. FillValue / nodataval) of the written raster, as Julias missing cannot be stored. If not passed in, missingval will be detected from metadata or a default will be chosen. For RasterStack this may be a NamedTuple, one for each layer.

  • source: Usually automatically detected from filepath extension. To manually force, a Symbol can be passed :gdal, :netcdf, :grd, :grib. The internal Rasters.Source objects, such as Rasters.GDALsource(), Rasters.GRIBsource() or Rasters.NCDsource() can also be used.

  • suffix: a string or value to append to the filename. A tuple of suffix will be applied to stack layers. keys(stack) are the default.

  • vebose: whether to print messages about potential problems. true by default.

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

  • driver: A GDAL driver name String or a GDAL driver retrieved via ArchGDAL.getdriver(drivername). By default driver is guessed from the filename extension.

  • options::Dict{String,String}: A dictionary containing the dataset creation options passed to the driver. For example: Dict("COMPRESS" => "DEFLATE").

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

source

Base.write Method
julia
Base.write(filename::AbstractString, A::AbstractRaster; [source], kw...)

Write an AbstractRaster to file, guessing the backend from the file extension or using the source keyword.

Keywords

  • chunks: a NTuple{N,Int} specifying the chunk size for each dimension. To specify only specific dimensions, a Tuple of Dimension wrapping Int or a NamedTuple of Int can be used. Other dimensions will have a chunk size of 1. true can be used to mean: use the original chunk size of the lazy Raster being written or X and Y of 256 by 256. false means don't use chunks at all.

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

  • missingval: set the missing value (i.e. FillValue / nodataval) of the written raster, as Julias missing cannot be stored. If not passed in, missingval will be detected from metadata or a default will be chosen.

  • source: Usually automatically detected from filepath extension. To manually force, a Symbol can be passed :gdal, :netcdf, :grd, :grib. The internal Rasters.Source objects, such as Rasters.GDALsource(), Rasters.GRIBsource() or Rasters.NCDsource() can also be used.

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

  • driver: A GDAL driver name String or a GDAL driver retrieved via ArchGDAL.getdriver(drivername). By default driver is guessed from the filename extension.

  • options::Dict{String,String}: A dictionary containing the dataset creation options passed to the driver. For example: Dict("COMPRESS" => "DEFLATE").

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

Returns filename.

source

Base.write Method
julia
Base.write(filename::AbstractString, ::Type{GRDsource}, s::AbstractRaster; kw...)

Write a Raster to a .grd file with a .gri header file.

This method is called automatically if you write a Raster with a .grd or .gri extension.

Keywords

  • force: false by default. If true it force writing to a file destructively, even if it already exists.

If this method is called directly the extension of filename will be ignored.

Returns the base of filename with a .grd extension.

source

Rasters.checkmem! Method
julia
checkmem!(x::Bool)

Set checkmem to true or false.

In some architectures memory reporting may be wrong and you may wish to disable memory checks.

This setting can be overridden with the checkmem keyword, where applicable.

source

Rasters.rplot Method
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

  • plottype = Makie.Heatmap: The type of plot. Can be any Makie plot type which accepts a Raster; in practice, Heatmap, Contour, Contourf and Surface are the best bets.

  • axistype = Makie.Axis: The type of axis. This can be an Axis, Axis3, LScene, or even a GeoAxis from GeoMakie.jl.

  • X = XDim: The X dimension of the raster.

  • Y = YDim: The Y dimension of the raster.

  • Z = YDim: The Y dimension of the raster.

  • draw_colorbar = true: Whether to draw a colorbar for the axis or not.

  • colorbar_position = Makie.Right(): Indicates which side of the axis the colorbar should be placed on. Can be Makie.Top(), Makie.Bottom(), Makie.Left(), or Makie.Right().

  • colorbar_padding = Makie.automatic: The amount of padding between the colorbar and its axis. If automatic, then this is set to the width of the colorbar.

  • title = Makie.automatic: The titles of each plot. If automatic, these are set to the name of the band.

  • xlabel = Makie.automatic: The x-label for the axis. If automatic, set to the dimension name of the X-dimension of the raster.

  • ylabel = Makie.automatic: The y-label for the axis. If automatic, set to the dimension name of the Y-dimension of the raster.

  • colorbarlabel = "": Usually nothing, but here if you need it. Sets the label on the colorbar.

  • colormap = nothing: The colormap for the heatmap. This can be set to a vector of colormaps (symbols, strings, cgrads) if plotting a 3D raster or RasterStack.

  • colorrange = Makie.automatic: The colormap for the heatmap. This can be set to a vector of (low, high) if plotting a 3D raster or RasterStack.

  • nan_color = :transparent: The color which NaN values should take. Default to transparent.

source

+ + + + \ No newline at end of file diff --git a/previews/PR807/array_operations.html b/previews/PR807/array_operations.html new file mode 100644 index 00000000..d1e41b9d --- /dev/null +++ b/previews/PR807/array_operations.html @@ -0,0 +1,165 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Most base methods work as for regular julia Arrays, such as reverse and rotations like rotl90. Base, statistics and linear algebra methods like mean that take a dims argument can also use the dimension name.

Mean over the time dimension:

julia
using Rasters, Statistics, RasterDataSources
+
+A = Raster(WorldClim{BioClim}, 5)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

Then we do the mean over the X dimension

julia
mean(A, dims=X) # Ti if time were available would also be possible
╭───────────────────────────────╮
+│ 1×1080 Raster{Float32,2} bio5 │
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} -180.0:360.0:-180.0 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 180.0), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →   89.8333   89.6667   89.5   89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0  -Inf      -Inf      -Inf   -Inf         -23.0768  -22.9373  -22.0094

broadcast works lazily from disk when lazy=true, and is only applied when data is directly indexed. Adding a dot to any function will use broadcast over a Raster just like an Array.

Broadcasting

For a disk-based array A, this will only be applied when indexing occurs or when we read the array.

julia
A .*= 2
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →     89.8333   89.6667   89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -Inf      -Inf      -Inf      -30.798   -27.61    -28.092
+    ⋮                                 ⋱                        ⋮
+  179.833  -Inf      -Inf      -Inf   …  -34.2955  -30.8485  -31.402

To broadcast directly to disk, we need to open the file in write mode:

julia
open(Raster(filename); write=true) do O
+   O .*= 2
+end

To broadcast over a RasterStack use map, which applies a function to the raster layers of the stack.

julia
newstack = map(stack) do raster
+   raster .* 2
+end

Modifying object properties

rebuild can be used to modify the fields of an object, generating a new object (but possibly holding the same arrays or files).

If you know that a file had an incorrectly specified missing value, you can do:

rebuild

julia
A = Raster(WorldClim{BioClim}, 5)
+rebuild(A; missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

(replace_missing will actually replace the current values).

Or if you need to change the name of the layer:

Then use rebuild as

julia
B = rebuild(A; name=:temperature)
+B.name
:temperature

replace_missing

julia
replace_missing(A, missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →       89.8333     89.6667     89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -9999.0     -9999.0     -9999.0     -15.399   -13.805   -14.046
+    ⋮                                       ⋱                        ⋮
+  179.833  -9999.0     -9999.0     -9999.0  …  -17.1478  -15.4243  -15.701

set

set can be used to modify the nested properties of an objects dimensions, that are more difficult to change with rebuild. set works on the principle that dimension properties can only be in one specific field, so we generally don't have to specify which one it is. set will also try to update anything affected by a change you make.

This will set the X axis to specify points, instead of intervals:

julia
using Rasters: Points
+set(A, X => Points)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Points,
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.83333333333331), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

We can also reassign dimensions, here X becomes Z:

julia
set(A, X => Z)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Z Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(Z = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

setcrs(A, crs) and setmappedcrs(A, crs) will set the crs value/s of an object to any GeoFormat from GeoFormatTypes.jl.

+ + + + \ No newline at end of file diff --git a/previews/PR807/assets/aggregate_example.vPDkaGne.png b/previews/PR807/assets/aggregate_example.vPDkaGne.png new file mode 100644 index 00000000..a4235bf7 Binary files /dev/null and b/previews/PR807/assets/aggregate_example.vPDkaGne.png differ diff --git a/previews/PR807/assets/api.md.OKz0SH8-.js b/previews/PR807/assets/api.md.OKz0SH8-.js new file mode 100644 index 00000000..32b94faf --- /dev/null +++ b/previews/PR807/assets/api.md.OKz0SH8-.js @@ -0,0 +1,386 @@ +import{_ as l,c as p,a5 as t,j as i,a as e,G as n,B as o,o as r}from"./chunks/framework.Cl7EIXwS.js";const h="/Rasters.jl/previews/PR807/assets/aggregate_example.vPDkaGne.png",d="/Rasters.jl/previews/PR807/assets/boolmask_example.B6nOyO_A.png",k="/Rasters.jl/previews/PR807/assets/classify_example.CA_6ItEA.png",c="/Rasters.jl/previews/PR807/assets/classify_bang_example.Ch0DZvbI.png",g="/Rasters.jl/previews/PR807/assets/nz_crop_example.CeBIxUDy.png",y="/Rasters.jl/previews/PR807/assets/argentina_crop_example.DlKBBk5m.png",E="/Rasters.jl/previews/PR807/assets/extend_example.DNJ4wwKN.png",u="/Rasters.jl/previews/PR807/assets/boolmask_example.B6nOyO_A.png",m="/Rasters.jl/previews/PR807/assets/mosaic_bang_example.ptHNiUCT.png",b="/Rasters.jl/previews/PR807/assets/mosaic_example_africa.Dpr9JnNl.png",F="/Rasters.jl/previews/PR807/assets/mosaic_example_aus.3EfcKnQU.png",f="/Rasters.jl/previews/PR807/assets/mosaic_example_combined.XY5Q_nfP.png",C="/Rasters.jl/previews/PR807/assets/china_rasterized.kM95Jnlf.png",A="/Rasters.jl/previews/PR807/assets/indonesia_rasterized.CAASrLmh.png",R="/Rasters.jl/previews/PR807/assets/warp_example_before.DrW8As6m.png",v="/Rasters.jl/previews/PR807/assets/resample_example_after.C_gavhhT.png",D="/Rasters.jl/previews/PR807/assets/trim_example_before.B583SoP8.png",j="/Rasters.jl/previews/PR807/assets/trim_example_after.CsDpPakV.png",B="/Rasters.jl/previews/PR807/assets/warp_example_before.DrW8As6m.png",w="/Rasters.jl/previews/PR807/assets/warp_example_after.rgHHAHxc.png",Ys=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"api.md","filePath":"api.md","lastUpdated":null}'),x={name:"api.md"},T={class:"jldocstring custom-block",open:""},S={class:"jldocstring custom-block",open:""},q={class:"jldocstring custom-block",open:""},L={class:"jldocstring custom-block",open:""},I={class:"jldocstring custom-block",open:""},z={class:"jldocstring custom-block",open:""},P={class:"jldocstring custom-block",open:""},G={class:"jldocstring custom-block",open:""},N={class:"jldocstring custom-block",open:""},O={class:"jldocstring custom-block",open:""},M={class:"jldocstring custom-block",open:""},_={class:"jldocstring custom-block",open:""},U={class:"jldocstring custom-block",open:""},W={class:"jldocstring custom-block",open:""},K={class:"jldocstring custom-block",open:""},V={class:"jldocstring custom-block",open:""},X={class:"jldocstring custom-block",open:""},Y={class:"jldocstring custom-block",open:""},H={class:"jldocstring custom-block",open:""},J={class:"jldocstring custom-block",open:""},Z={class:"jldocstring custom-block",open:""},$={class:"jldocstring custom-block",open:""},Q={class:"jldocstring custom-block",open:""},ss={class:"jldocstring custom-block",open:""},is={class:"jldocstring custom-block",open:""},es={class:"jldocstring custom-block",open:""},as={class:"jldocstring custom-block",open:""},ts={class:"jldocstring custom-block",open:""},ns={class:"jldocstring custom-block",open:""},ls={class:"jldocstring custom-block",open:""},ps={class:"jldocstring custom-block",open:""},os={class:"jldocstring custom-block",open:""},rs={class:"jldocstring custom-block",open:""},hs={class:"jldocstring custom-block",open:""},ds={class:"jldocstring custom-block",open:""},ks={class:"jldocstring custom-block",open:""},cs={class:"jldocstring custom-block",open:""},gs={class:"jldocstring custom-block",open:""},ys={class:"jldocstring custom-block",open:""},Es={class:"jldocstring custom-block",open:""},us={class:"jldocstring custom-block",open:""},ms={class:"jldocstring custom-block",open:""},bs={class:"jldocstring custom-block",open:""},Fs={class:"jldocstring custom-block",open:""},fs={class:"jldocstring custom-block",open:""},Cs={class:"jldocstring custom-block",open:""},As={class:"jldocstring custom-block",open:""},Rs={class:"jldocstring custom-block",open:""},vs={class:"jldocstring custom-block",open:""},Ds={class:"jldocstring custom-block",open:""},js={class:"jldocstring custom-block",open:""},Bs={class:"jldocstring custom-block",open:""},ws={class:"jldocstring custom-block",open:""},xs={class:"jldocstring custom-block",open:""},Ts={class:"jldocstring custom-block",open:""},Ss={class:"jldocstring custom-block",open:""},qs={class:"jldocstring custom-block",open:""},Ls={class:"jldocstring custom-block",open:""},Is={class:"jldocstring custom-block",open:""},zs={class:"jldocstring custom-block",open:""},Ps={class:"jldocstring custom-block",open:""},Gs={class:"jldocstring custom-block",open:""},Ns={class:"jldocstring custom-block",open:""},Os={class:"jldocstring custom-block",open:""};function Ms(_s,s,Us,Ws,Ks,Vs){const a=o("Badge");return r(),p("div",null,[s[192]||(s[192]=t('

Index

Reference - Exported functions

',3)),i("details",T,[i("summary",null,[s[0]||(s[0]=i("a",{id:"Rasters.Rasters",href:"#Rasters.Rasters"},[i("span",{class:"jlbinding"},"Rasters.Rasters")],-1)),s[1]||(s[1]=e()),n(a,{type:"info",class:"jlObjectType jlModule",text:"Module"})]),s[2]||(s[2]=i("p",null,[i("a",{href:"https://github.com/rafaqz/Rasters.jl/blob/9a1be0473d9caebb8381ce8e9079c4f4349d94ce/src/Rasters.jl#L4",target:"_blank",rel:"noreferrer"},"source")],-1))]),i("details",S,[i("summary",null,[s[3]||(s[3]=i("a",{id:"Rasters.AbstractRaster",href:"#Rasters.AbstractRaster"},[i("span",{class:"jlbinding"},"Rasters.AbstractRaster")],-1)),s[4]||(s[4]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[5]||(s[5]=t('
julia
AbstractRaster <: DimensionalData.AbstractDimArray

Abstract supertype for objects that wrap an array (or location of an array) and metadata about its contents. It may be memory or hold a FileArray, which holds the filename, and is only opened when required.

AbstractRasters inherit from AbstractDimArray from DimensionalData.jl. They can be indexed as regular Julia arrays or with DimensionalData.jl Dimensions. They will plot as a heatmap in Plots.jl with correct coordinates and labels, even after slicing with getindex or view. getindex on a AbstractRaster will always return a memory-backed Raster.

source

',4))]),i("details",q,[i("summary",null,[s[6]||(s[6]=i("a",{id:"Rasters.AbstractRasterSeries",href:"#Rasters.AbstractRasterSeries"},[i("span",{class:"jlbinding"},"Rasters.AbstractRasterSeries")],-1)),s[7]||(s[7]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[8]||(s[8]=t('
julia
AbstractRasterSeries <: DimensionalData.AbstractDimensionalArray

Abstract supertype for high-level DimensionalArray that hold RasterStacks, Rasters, or the paths they can be loaded from. RasterSeries are indexed with dimensions as with a AbstractRaster. This is useful when you have multiple files containing rasters or stacks of rasters spread over dimensions like time and elevation.

As much as possible, implementations should facilitate loading entire directories and detecting the dimensions from metadata.

This allows syntax like below for a series of stacks of arrays:

julia
RasterSeries[Time(Near(DateTime(2001, 1))][:temp][Y(Between(70, 150)), X(Between(-20,20))] |> plot`

RasterSeries is the concrete implementation.

source

',7))]),i("details",L,[i("summary",null,[s[9]||(s[9]=i("a",{id:"Rasters.AbstractRasterStack",href:"#Rasters.AbstractRasterStack"},[i("span",{class:"jlbinding"},"Rasters.AbstractRasterStack")],-1)),s[10]||(s[10]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[11]||(s[11]=t('
julia
AbstractRasterStack

Abstract supertype for objects that hold multiple AbstractRasters that share spatial dimensions.

They are NamedTuple-like structures that may either contain NamedTuple of AbstractRasters, string paths that will load AbstractRasters, or a single path that points to a file containing multiple layers, like NetCDF or HDF5. Use and syntax is similar or identical for all cases.

AbstractRasterStack can hold layers that share some or all of their dimensions. They cannot have the same dimension with different length or spatial extent as another layer.

getindex on an AbstractRasterStack generally returns a memory backed standard Raster. raster[:somelayer] |> plot plots the layers array, while raster[:somelayer, X(1:100), Band(2)] |> plot will plot the subset without loading the whole array.

getindex on an AbstractRasterStack with a key returns another stack with getindex applied to all the arrays in the stack.

source

',7))]),i("details",I,[i("summary",null,[s[12]||(s[12]=i("a",{id:"Rasters.Band",href:"#Rasters.Band"},[i("span",{class:"jlbinding"},"Rasters.Band")],-1)),s[13]||(s[13]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[14]||(s[14]=t(`
julia
Band <: Dimension
+
+Band(val=:)

Band Dimension for multi-band rasters.

Example:

julia
banddim = Band(10:10:100)
+# Or
+val = A[Band(1)]
+# Or
+mean(A; dims=Band)

source

`,5))]),i("details",z,[i("summary",null,[s[15]||(s[15]=i("a",{id:"Rasters.Mapped",href:"#Rasters.Mapped"},[i("span",{class:"jlbinding"},"Rasters.Mapped")],-1)),s[16]||(s[16]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[17]||(s[17]=t(`
julia
Mapped <: AbstractProjected
+
+Mapped(order, span, sampling, crs, mappedcrs)
+Mapped(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs=nothing, mappedcrs)

An AbstractSampled Lookup, where the dimension index has been mapped to another projection, usually lat/lon or EPSG(4326). Mapped matches the dimension format commonly used in netcdf files.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

The mapped dimension index will be used as for Sampled, but to save in another format the underlying crs may be used to convert it.

source

`,5))]),i("details",P,[i("summary",null,[s[18]||(s[18]=i("a",{id:"Rasters.Projected",href:"#Rasters.Projected"},[i("span",{class:"jlbinding"},"Rasters.Projected")],-1)),s[19]||(s[19]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[20]||(s[20]=t(`
julia
Projected <: AbstractProjected
+
+Projected(order, span, sampling, crs, mappedcrs)
+Projected(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs, mappedcrs=nothing)

An AbstractSampled Lookup with projections attached.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

If both crs and mappedcrs fields contain CRS data (in a GeoFormat wrapper from GeoFormatTypes.jl) the selector inputs and plot axes will be converted from and to the specified mappedcrs projection automatically. A common use case would be to pass mappedcrs=EPSG(4326) to the constructor when loading eg. a GDALarray:

julia
GDALarray(filename; mappedcrs=EPSG(4326))

The underlying crs will be detected by GDAL.

If mappedcrs is not supplied (ie. mappedcrs=nothing), the base index will be shown on plots, and selectors will need to use whatever format it is in.

source

`,8))]),i("details",G,[i("summary",null,[s[21]||(s[21]=i("a",{id:"Rasters.Raster",href:"#Rasters.Raster"},[i("span",{class:"jlbinding"},"Rasters.Raster")],-1)),s[22]||(s[22]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[23]||(s[23]=t(`
julia
Raster <: AbstractRaster
+
+Raster(filepath::String; kw...)
+Raster(A::AbstractDimArray; kw...)
+Raster(A::AbstractArray, dims; kw...)

A generic AbstractRaster for spatial/raster array data. It can hold either memory-backed arrays or, if lazy=true, a FileArray, which stores the String path to an unopened file.

If lazy=true, the file will only be opened lazily when it is indexed with getindex or when read(A) is called. Broadcasting, taking a view, reversing, and most other methods will not load data from disk; they will be applied later, lazily.

Arguments

Keywords

When a filepath String is used:

When A is an AbstractDimArray:

source

`,12))]),i("details",N,[i("summary",null,[s[24]||(s[24]=i("a",{id:"Rasters.RasterSeries",href:"#Rasters.RasterSeries"},[i("span",{class:"jlbinding"},"Rasters.RasterSeries")],-1)),s[25]||(s[25]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[26]||(s[26]=t(`
julia
RasterSeries <: AbstractRasterSeries
+
+RasterSeries(rasters::AbstractArray{<:AbstractRaster}, dims; [refdims])
+RasterSeries(stacks::AbstractArray{<:AbstractRasterStack}, dims; [refdims]) 
+
+RasterSeries(paths::AbstractArray{<:AbstractString}, dims; child, duplicate_first, kw...)
+RasterSeries(path:::AbstractString, dims; ext, separator, child, duplicate_first, kw...)

Concrete implementation of AbstractRasterSeries.

A RasterSeries is an array of Rasters or RasterStacks, along some dimension(s).

Existing Raster RasterStack can be wrapped in a RasterSeries, or new files can be loaded from an array of String or from a single String.

A single String can refer to a whole directory, or the name of a series of files in a directory, sharing a common stem. The differnce between the filenames can be used as the lookup for the series.

For example, with some tifs at these paths :

"series_dir/myseries_2001-01-01T00:00:00.tif"
+"series_dir/myseries_2002-01-01T00:00:00.tif"

We can load a RasterSeries with a DateTime lookup:

julia
julia> ser = RasterSeries("series_dir/myseries.tif", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

The DateTime suffix is parsed from the filenames. Using Ti(Int) would try to parse integers instead.

Just using the directory will also work, unless there are other files mixed in it:

julia
julia> ser = RasterSeries("series_dir", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

Arguments

Keywords

When loading a series from a Vector of String paths or a single String path:

When loading a series from a single String path:

Others:

source

`,22))]),i("details",O,[i("summary",null,[s[27]||(s[27]=i("a",{id:"Rasters.RasterStack",href:"#Rasters.RasterStack"},[i("span",{class:"jlbinding"},"Rasters.RasterStack")],-1)),s[28]||(s[28]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[29]||(s[29]=t(`
julia
RasterStack <: AbstrackRasterStack
+
+RasterStack(data...; name, kw...)
+RasterStack(data::Union{Vector,Tuple}; name, kw...)
+RasterStack(data::NamedTuple; kw...))
+RasterStack(data::RasterStack; kw...)
+RasterStack(data::Raster; layersfrom=Band, kw...)
+RasterStack(filepath::AbstractString; kw...)

Load a file path or a NamedTuple of paths as a RasterStack, or convert arguments, a Vector or NamedTuple of Rasters to RasterStack.

Arguments

Keywords

For when one or multiple filepaths are used:

For when a single Raster is used:

julia
files = (temp="temp.tif", pressure="pressure.tif", relhum="relhum.tif")
+stack = RasterStack(files; mappedcrs=EPSG(4326))
+stack[:relhum][Lat(Contains(-37), Lon(Contains(144))

source

`,12))]),i("details",M,[i("summary",null,[s[30]||(s[30]=i("a",{id:"DimensionalData.modify-Tuple{Any, AbstractRasterSeries}",href:"#DimensionalData.modify-Tuple{Any, AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"DimensionalData.modify")],-1)),s[31]||(s[31]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[32]||(s[32]=t('
julia
modify(f, series::AbstractRasterSeries)

Apply function f to the data of the child object. If the child is an AbstractRasterStack the function will be passed on to its child AbstractRasters.

f must return an identically sized array.

This method triggers a complete rebuild of all objects, and disk based objects will be transferred to memory.

An example of the usefulnesss of this is for swapping out array backend for an entire series to CuArray from CUDA.jl to copy data to a GPU.

source

',6))]),i("details",_,[i("summary",null,[s[33]||(s[33]=i("a",{id:"GeoInterface.crs-Tuple{Union{Tuple{Dimension, Vararg{Dimension}}, AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}",href:"#GeoInterface.crs-Tuple{Union{Tuple{Dimension, Vararg{Dimension}}, AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"GeoInterface.crs")],-1)),s[34]||(s[34]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[35]||(s[35]=t('
julia
crs(x::Raster)

Get the projected coordinate reference system of a Y or X Dimension, or of the Y/X dims of an AbstractRaster.

For Mapped lookup this may be nothing as there may be no projected coordinate reference system at all. See setcrs to set it manually.

source

',4))]),i("details",U,[i("summary",null,[s[36]||(s[36]=i("a",{id:"Rasters.aggregate",href:"#Rasters.aggregate"},[i("span",{class:"jlbinding"},"Rasters.aggregate")],-1)),s[37]||(s[37]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[38]||(s[38]=t(`
julia
aggregate(method, object, scale; filename, progress, skipmissing)

Aggregate a Raster, or all arrays in a RasterStack or RasterSeries, by scale using method.

Arguments

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

Example

julia
using Rasters, RasterDataSources, Statistics, Plots
+import ArchGDAL
+using Rasters: Center
+st = read(RasterStack(WorldClim{Climate}; month=1))
+ag = aggregate(Center(), st, (Y(20), X(20)); skipmissingval=true, progress=false)
+plot(ag)
+savefig("build/aggregate_example.png"); nothing
+# output

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',12))]),i("details",W,[i("summary",null,[s[39]||(s[39]=i("a",{id:"Rasters.aggregate!-Tuple{Locus, AbstractRaster, Any, Any}",href:"#Rasters.aggregate!-Tuple{Locus, AbstractRaster, Any, Any}"},[i("span",{class:"jlbinding"},"Rasters.aggregate!")],-1)),s[40]||(s[40]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[41]||(s[41]=t('
julia
aggregate!(method, dst::AbstractRaster, src::AbstractRaster, scale; skipmissingval=false)

Aggregate array src to array dst by scale, using method.

Arguments

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

Note: currently it is much faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',9))]),i("details",K,[i("summary",null,[s[42]||(s[42]=i("a",{id:"Rasters.boolmask",href:"#Rasters.boolmask"},[i("span",{class:"jlbinding"},"Rasters.boolmask")],-1)),s[43]||(s[43]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[44]||(s[44]=t(`
julia
boolmask(obj::Raster; [missingval])
+boolmask(obj; [to, res, size])
+boolmask(obj::RasterStack; alllayers=true, kw...)

Create a mask array of Bool values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted.

The array returned from calling boolmask on a AbstractRaster is a Raster with the same dimensions as the original array and a missingval of false.

Arguments

Raster / RasterStack Keywords

Keywords

And specifically for shape=:polygon:

For tabular data, feature collections and other iterables

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+boolmask(wc) |> plot
+
+savefig("build/boolmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',18))]),i("details",V,[i("summary",null,[s[45]||(s[45]=i("a",{id:"Rasters.cellarea-Tuple{Any}",href:"#Rasters.cellarea-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.cellarea")],-1)),s[46]||(s[46]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[47]||(s[47]=t(`
julia
cellarea([method], x)

Gives the approximate area of each gridcell of x. By assuming the earth is a sphere, it approximates the true size to about 0.1%, depending on latitude.

Run using ArchGDAL to make this method fully available.

method can be Spherical(; radius) (the default) or Planar().

Example

julia
using Rasters, ArchGDAL, Rasters.Lookups
+xdim = X(Projected(90.0:10.0:120; sampling=Intervals(Start()), crs=EPSG(4326)))
+ydim = Y(Projected(0.0:10.0:50; sampling=Intervals(Start()), crs=EPSG(4326)))
+myraster = rand(xdim, ydim)
+cs = cellarea(myraster)
+
+# output
+╭───────────────────────╮
+4×6 Raster{Float64,2} │
+├───────────────────────┴─────────────────────────────────────────────────── dims ┐
+ X Projected{Float64} 90.0:10.0:120.0 ForwardOrdered Regular Intervals{Start},
+ Y Projected{Float64} 0.0:10.0:50.0 ForwardOrdered Regular Intervals{Start}
+├───────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (90.0, 130.0), Y = (0.0, 60.0))
+
+  crs: EPSG:4326
+└─────────────────────────────────────────────────────────────────────────────────┘
+  0.0        10.0        20.0        30.0            40.0      50.0
+  90.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 100.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 110.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 120.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,9))]),i("details",X,[i("summary",null,[s[48]||(s[48]=i("a",{id:"Rasters.classify",href:"#Rasters.classify"},[i("span",{class:"jlbinding"},"Rasters.classify")],-1)),s[49]||(s[49]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[50]||(s[50]=t(`
julia
classify(x, pairs; lower=(>=), upper=(<), others=nothing)
+classify(x, pairs...; lower, upper, others)

Create a new array with values in x classified by the values in pairs.

pairs can hold tuples fo values (2, 3), a Fix2 function e.g. <=(1), a Tuple of Fix2 e.g. (>=(4), <(7)), or an IntervalSets.jl interval, e.g. 3..9 or OpenInterval(10, 12). pairs can also be a n * 3 matrix where each row is lower bounds, upper bounds, replacement.

If tuples or a Matrix are used, the lower and upper keywords define how the lower and upper boundaries are chosen.

If others is set other values not covered in pairs will be set to that values.

Arguments

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :tavg; month=1)
+classes = <=(15) => 10,
+          15..25 => 20,
+          25..35 => 30,
+          >(35) => 40
+classified = classify(A, classes; others=0, missingval=0)
+plot(classified; c=:magma)
+
+savefig("build/classify_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',14))]),i("details",Y,[i("summary",null,[s[51]||(s[51]=i("a",{id:"Rasters.classify!-Tuple{AbstractRaster, Pair, Vararg{Pair}}",href:"#Rasters.classify!-Tuple{AbstractRaster, Pair, Vararg{Pair}}"},[i("span",{class:"jlbinding"},"Rasters.classify!")],-1)),s[52]||(s[52]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[53]||(s[53]=t(`
julia
classify!(x, pairs...; lower, upper, others)
+classify!(x, pairs; lower, upper, others)

Classify the values of x in-place, by the values in pairs.

If Fix2 is not used, the lower and upper keywords

If others is set other values not covered in pairs will be set to that values.

Arguments

Keywords

Example

classify! to disk, with key steps:

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+# Download and copy the file
+filename = getraster(WorldClim{Climate}, :tavg; month=6)
+tempfile = tempname() * ".tif"
+cp(filename, tempfile)
+# Define classes
+classes = (5, 15) => 10,
+          (15, 25) => 20,
+          (25, 35) => 30,
+          >=(35) => 40
+# Open the file with write permission
+open(Raster(tempfile); write=true) do A
+    classify!(A, classes; others=0)
+end
+# Open it again to plot the changes
+plot(Raster(tempfile); c=:magma)
+
+savefig("build/classify_bang_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',15))]),i("details",H,[i("summary",null,[s[54]||(s[54]=i("a",{id:"Rasters.combine-Tuple{AbstractRasterSeries}",href:"#Rasters.combine-Tuple{AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"Rasters.combine")],-1)),s[55]||(s[55]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[56]||(s[56]=t('
julia
combine(A::AbstracRasterSeries; [dims], [lazy]) => Raster

Combine a RasterSeries along some dimension/s, creating a new Raster or RasterStack, depending on the contents of the series.

If dims are passed, only the specified dimensions will be combined with a RasterSeries returned, unless dims is all the dims in the series.

If lazy, concatenate lazily. The default is to concatenate lazily for lazy Rasters and eagerly otherwise.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',6))]),i("details",J,[i("summary",null,[s[57]||(s[57]=i("a",{id:"Rasters.convertlookup-Tuple{Type{<:Lookup}, AbstractDimArray}",href:"#Rasters.convertlookup-Tuple{Type{<:Lookup}, AbstractDimArray}"},[i("span",{class:"jlbinding"},"Rasters.convertlookup")],-1)),s[58]||(s[58]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[59]||(s[59]=t('
julia
convertlookup(dstlookup::Type{<:Lookup}, x)

Convert the dimension lookup between Projected and Mapped. Other dimension lookups pass through unchanged.

This is used to e.g. save a netcdf file to GeoTiff.

source

',4))]),i("details",Z,[i("summary",null,[s[60]||(s[60]=i("a",{id:"Rasters.coverage!-Tuple{Union{typeof(sum), typeof(union)}, AbstractRaster, Any}",href:"#Rasters.coverage!-Tuple{Union{typeof(sum), typeof(union)}, AbstractRaster, Any}"},[i("span",{class:"jlbinding"},"Rasters.coverage!")],-1)),s[61]||(s[61]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[62]||(s[62]=t('
julia
coverage!(A, geom; [mode, scale])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

source

',8))]),i("details",$,[i("summary",null,[s[63]||(s[63]=i("a",{id:"Rasters.coverage-Tuple{Any}",href:"#Rasters.coverage-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.coverage")],-1)),s[64]||(s[64]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[65]||(s[65]=t(`
julia
coverage(mode, geom; [to, res, size, scale, verbose, progress])
+coverage(geom; [to, mode, res, size, scale, verbose, progress])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

source

`,8))]),i("details",Q,[i("summary",null,[s[66]||(s[66]=i("a",{id:"Rasters.crop",href:"#Rasters.crop"},[i("span",{class:"jlbinding"},"Rasters.crop")],-1)),s[67]||(s[67]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[68]||(s[68]=t(`
julia
crop(x; to, touches=false, [geometrycolumn])
+crop(xs...; to)

Crop one or multiple AbstractRaster or AbstractRasterStack x to match the size of the object to, or smallest of any dimensions that are shared.

crop is lazy, using a view into the object rather than allocating new memory.

Keywords

As crop is lazy, filename and suffix keywords are not used.

Example

Crop to another raster:

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out New Zealand from the evenness raster
+nz_bounds = X(165 .. 180), Y(-50 .. -32)
+nz_evenness = evenness[nz_bounds...]
+
+# Crop range to match evenness
+nz_range = crop(rnge; to=nz_evenness)
+plot(nz_range)
+
+savefig("build/nz_crop_example.png")
+nothing
+
+# output

Crop to a polygon:

julia
using Rasters, RasterDataSources, Plots, Dates, Shapefile, Downloads
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+shp = Shapefile.Handle(shapefile_name).shapes[6]
+
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+argentina_evenness = crop(evenness; to=shp)
+plot(argentina_evenness)
+
+savefig("build/argentina_crop_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',15))]),i("details",ss,[i("summary",null,[s[69]||(s[69]=i("a",{id:"Rasters.disaggregate",href:"#Rasters.disaggregate"},[i("span",{class:"jlbinding"},"Rasters.disaggregate")],-1)),s[70]||(s[70]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[71]||(s[71]=t('
julia
disaggregate(method, object, scale; filename, progress, keys)

Disaggregate array, or all arrays in a stack or series, by some scale.

Arguments

Keywords

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',8))]),i("details",is,[i("summary",null,[s[72]||(s[72]=i("a",{id:"Rasters.disaggregate!-Tuple{Locus, AbstractRaster, Any, Any}",href:"#Rasters.disaggregate!-Tuple{Locus, AbstractRaster, Any, Any}"},[i("span",{class:"jlbinding"},"Rasters.disaggregate!")],-1)),s[73]||(s[73]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[74]||(s[74]=t('
julia
disaggregate!(method, dst::AbstractRaster, src::AbstractRaster, filename, scale)

Disaggregate array src to array dst by some scale, using method.

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',5))]),i("details",es,[i("summary",null,[s[75]||(s[75]=i("a",{id:"Rasters.extend",href:"#Rasters.extend"},[i("span",{class:"jlbinding"},"Rasters.extend")],-1)),s[76]||(s[76]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[77]||(s[77]=t(`
julia
extend(xs...; [to])
+extend(xs; [to])
+extend(x::Union{AbstractRaster,AbstractRasterStack}; to, kw...)

Extend one or multiple AbstractRaster to match the area covered by all xs, or by the keyword argument to.

Keywords

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out South America
+sa_bounds = X(-88 .. -32), Y(-57 .. 13)
+sa_evenness = evenness[sa_bounds...]
+
+# Extend range to match the whole-world raster
+sa_range = extend(sa_evenness; to=rnge)
+plot(sa_range)
+
+savefig("build/extend_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',8))]),i("details",as,[i("summary",null,[s[78]||(s[78]=i("a",{id:"Rasters.extract",href:"#Rasters.extract"},[i("span",{class:"jlbinding"},"Rasters.extract")],-1)),s[79]||(s[79]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[80]||(s[80]=t(`
julia
extract(x, data; kw...)

Extracts the value of Raster or RasterStack at given points, returning an iterable of NamedTuple with properties for :geometry and raster or stack layer values.

Note that if objects have more dimensions than the length of the point tuples, sliced arrays or stacks will be returned instead of single values.

Arguments

Keywords

geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

Example

Here we extract points matching the occurrence of the Mountain Pygmy Possum, Burramis parvus. This could be used to fit a species distribution model.

julia
using Rasters, RasterDataSources, ArchGDAL, GBIF2, CSV
+
+# Get a stack of BioClim layers, and replace missing values with \`missing\`
+st = RasterStack(WorldClim{BioClim}, (1, 3, 5, 7, 12)) |> replace_missing
+
+# Download some occurrence data
+obs = GBIF2.occurrence_search("Burramys parvus"; limit=5, year="2009")
+
+# use \`extract\` to get values for all layers at each observation point.
+# We \`collect\` to get a \`Vector\` from the lazy iterator.
+extract(st, obs; skipmissing=true)
+
+# output
+5-element Vector{NamedTuple{(:geometry, :bio1, :bio3, :bio5, :bio7, :bio12)}}:
+ (geometry = (0.21, 40.07), bio1 = 17.077084f0, bio3 = 41.20417f0, bio5 = 30.1f0, bio7 = 24.775f0, bio12 = 446.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.52, 40.37), bio1 = missing, bio3 = missing, bio5 = missing, bio7 = missing, bio12 = missing)
+ (geometry = (0.32, 40.24), bio1 = 16.321388f0, bio3 = 41.659454f0, bio5 = 30.029825f0, bio7 = 25.544561f0, bio12 = 480.0f0)

Note: passing in arrays, geometry collections or feature collections containing a mix of points and other geometries has undefined results.

source

`,13))]),i("details",ts,[i("summary",null,[s[81]||(s[81]=i("a",{id:"Rasters.mappedbounds",href:"#Rasters.mappedbounds"},[i("span",{class:"jlbinding"},"Rasters.mappedbounds")],-1)),s[82]||(s[82]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[83]||(s[83]=t('
julia
mappedbounds(x)

Get the bounds converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular bounds.

source

',4))]),i("details",ns,[i("summary",null,[s[84]||(s[84]=i("a",{id:"Rasters.mappedcrs",href:"#Rasters.mappedcrs"},[i("span",{class:"jlbinding"},"Rasters.mappedcrs")],-1)),s[85]||(s[85]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[86]||(s[86]=t('
julia
mappedcrs(x)

Get the mapped coordinate reference system for the Y/X dims of an array.

In Projected lookup this is used to convert Selector values form the mappedcrs defined projection to the underlying projection, and to show plot axes in the mapped projection.

In Mapped lookup this is the coordinate reference system of the index values. See setmappedcrs to set it manually.

source

',5))]),i("details",ls,[i("summary",null,[s[87]||(s[87]=i("a",{id:"Rasters.mappedindex",href:"#Rasters.mappedindex"},[i("span",{class:"jlbinding"},"Rasters.mappedindex")],-1)),s[88]||(s[88]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[89]||(s[89]=t('
julia
mappedindex(x)

Get the index value of a dimension converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular dim value.

source

',4))]),i("details",ps,[i("summary",null,[s[90]||(s[90]=i("a",{id:"Rasters.mask!",href:"#Rasters.mask!"},[i("span",{class:"jlbinding"},"Rasters.mask!")],-1)),s[91]||(s[91]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[92]||(s[92]=t(`
julia
mask!(x; with, missingval=missingval(A))

Mask A by the missing values of with, or by all values outside with if it is a polygon.

If with is a polygon, creates a new array where points falling outside the polygon have been replaced by missingval(A).

Return a new array with values of A masked by the missing values of with, or by a polygon.

Arguments

Keywords

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask to match the size and projection.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(RasterStack(AWAP, (:tmin, :tmax); date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45), c=:imola)
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+mask!(awap; with=wc_mask)
+b = plot(awap; clims=(10, 45))
+
+savefig(a, "build/mask_bang_example_before.png");
+savefig(b, "build/mask_bang_example_after.png"); nothing
+
+# output

Before mask!:

After mask!:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,15))]),i("details",os,[i("summary",null,[s[93]||(s[93]=i("a",{id:"Rasters.mask-Tuple{Any}",href:"#Rasters.mask-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.mask")],-1)),s[94]||(s[94]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[95]||(s[95]=t(`
julia
mask(A:AbstractRaster; with, missingval=missingval(A))
+mask(x; with)

Return a new array with values of A masked by the missing values of with, or by the shape of with, if with is a geometric object.

Arguments

Keywords

Geometry keywords

These can be used when with is a GeoInterface.jl compatible object:

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(Raster(AWAP, :tmax; date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45))
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+awap_masked = mask(awap; with=wc_mask)
+b = plot(awap_masked; clims=(10, 45))
+
+savefig(a, "build/mask_example_before.png");
+savefig(b, "build/mask_example_after.png"); nothing
+# output

Before mask:

After mask:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,16))]),i("details",rs,[i("summary",null,[s[96]||(s[96]=i("a",{id:"Rasters.missingmask-Tuple{Any}",href:"#Rasters.missingmask-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.missingmask")],-1)),s[97]||(s[97]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[98]||(s[98]=t(`
julia
missingmask(obj::Raster; kw...)
+missingmask(obj; [to, res, size, collapse])
+missingmask(obj::RasterStack; alllayers = true, kw...)

Create a mask array of missing and true values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted-

For AbstractRaster the default missingval is missingval(A), but others can be chosen manually.

The array returned from calling missingmask on a AbstractRaster is a Raster with the same size and fields as the original array.

Arguments

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+missingmask(wc) |> plot
+
+savefig("build/missingmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',13))]),i("details",hs,[i("summary",null,[s[99]||(s[99]=i("a",{id:"Rasters.missingval",href:"#Rasters.missingval"},[i("span",{class:"jlbinding"},"Rasters.missingval")],-1)),s[100]||(s[100]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[101]||(s[101]=t('
julia
missingval(x)

Returns the value representing missing data in the dataset

source

',3))]),i("details",ds,[i("summary",null,[s[102]||(s[102]=i("a",{id:"Rasters.mosaic!-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}",href:"#Rasters.mosaic!-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}"},[i("span",{class:"jlbinding"},"Rasters.mosaic!")],-1)),s[103]||(s[103]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[104]||(s[104]=t(`
julia
mosaic!(f, x, regions...; missingval, atol)
+mosaic!(f, x, regions::Tuple; missingval, atol)

Combine regions in x using the function f.

Arguments

Keywords

Example

Cut out Australia and Africa stacks, then combined them into a single stack.

julia
using Rasters, RasterDataSources, ArchGDAL, Statistics, Plots
+st = read(RasterStack(WorldClim{Climate}; month=1))
+aus = st[X=100.0 .. 160.0, Y=-50.0 .. -10.0]
+africa = st[X=-20.0 .. 60.0, Y=-40.0 .. 35.0]
+mosaic!(first, st, aus, africa)
+plot(st)
+savefig("build/mosaic_bang_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',12))]),i("details",ks,[i("summary",null,[s[105]||(s[105]=i("a",{id:"Rasters.mosaic-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}",href:"#Rasters.mosaic-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}"},[i("span",{class:"jlbinding"},"Rasters.mosaic")],-1)),s[106]||(s[106]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[107]||(s[107]=t(`
julia
mosaic(f, regions...; missingval, atol)
+mosaic(f, regions; missingval, atol)

Combine regions into a single raster.

Arguments

Keywords

If your mosaic has has apparent line errors, increase the atol value.

Example

Here we cut out Australia and Africa from a stack, and join them with mosaic.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+st = RasterStack(WorldClim{Climate}; month=1);
+
+africa = st[X(-20.0 .. 60.0), Y(-40.0 .. 35.0)]
+a = plot(africa)
+
+aus = st[X(100.0 .. 160.0), Y(-50.0 .. -10.0)]
+b = plot(aus)
+
+# Combine with mosaic
+mos = mosaic(first, aus, africa)
+c = plot(mos)
+
+savefig(a, "build/mosaic_example_africa.png")
+savefig(b, "build/mosaic_example_aus.png")
+savefig(c, "build/mosaic_example_combined.png")
+nothing
+# output

Individual continents

Mosaic of continents

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',17))]),i("details",cs,[i("summary",null,[s[108]||(s[108]=i("a",{id:"Rasters.points-Tuple{AbstractRaster}",href:"#Rasters.points-Tuple{AbstractRaster}"},[i("span",{class:"jlbinding"},"Rasters.points")],-1)),s[109]||(s[109]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[110]||(s[110]=t('
julia
points(A::AbstractRaster; dims=(YDim, XDim), ignore_missing) => Array{Tuple}

Returns a generator of the points in A for dimensions in dims, where points are a tuple of the values in each specified dimension index.

Keywords

The order of dims determines the order of the points.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',7))]),i("details",gs,[i("summary",null,[s[111]||(s[111]=i("a",{id:"Rasters.rasterize",href:"#Rasters.rasterize"},[i("span",{class:"jlbinding"},"Rasters.rasterize")],-1)),s[112]||(s[112]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[113]||(s[113]=t(`
julia
rasterize([reducer], data; geometrycolumn, kw...)

Rasterize a GeoInterface.jl compatable geometry or feature, or a Tables.jl table with a :geometry column of GeoInterface.jl objects, or points columns specified by geometrycolumn

Arguments

Keywords

These are detected automatically from data where possible.

Note on threading. Performance may be much better with threaded=false if reducer/op are not threadsafe. sum, prod, maximum, minimum count and mean (by combining sum and count) are threadsafe. If you know your algorithm is threadsafe, use threadsafe=true to allow all optimisations. Functions passed to fill are always threadsafe, and ignore the threadsafe argument.

Example

Rasterize a shapefile for China and plot, with a border.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for china
+china_border = Shapefile.Handle(shapefile_name).shapes[10]
+
+# Rasterize the border polygon
+china = rasterize(last, china_border; res=0.1, missingval=0, fill=1, boundary=:touches, progress=false)
+
+# And plot
+p = plot(china; color=:spring, legend=false)
+plot!(p, china_border; fillalpha=0, linewidth=0.6)
+
+savefig("build/china_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',14))]),i("details",ys,[i("summary",null,[s[114]||(s[114]=i("a",{id:"Rasters.rasterize!",href:"#Rasters.rasterize!"},[i("span",{class:"jlbinding"},"Rasters.rasterize!")],-1)),s[115]||(s[115]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[116]||(s[116]=t(`
julia
rasterize!([reducer], dest, data; kw...)

Rasterize the geometries in data into the Raster or RasterStack dest, using the values specified by fill.

Arguments

Keywords

These are detected automatically from A and data where possible.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, GeoInterface, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for indonesia
+indonesia_border = Shapefile.Handle(shapefile_name).shapes[1]
+
+# Make an empty EPSG 4326 projected Raster of the area of Indonesia
+dimz = X(Projected(90.0:0.1:145; sampling=Intervals(), crs=EPSG(4326))),
+       Y(Projected(-15.0:0.1:10.9; sampling=Intervals(), crs=EPSG(4326)))
+
+A = zeros(UInt32, dimz; missingval=UInt32(0))
+
+# Rasterize each indonesian island with a different number. The islands are
+# rings of a multi-polygon, so we use \`GI.getring\` to get them all separately.
+islands = collect(GeoInterface.getring(indonesia_border))
+rasterize!(last, A, islands; fill=1:length(islands), progress=false)
+
+# And plot
+p = plot(Rasters.trim(A); color=:spring)
+plot!(p, indonesia_border; fillalpha=0, linewidth=0.7)
+
+savefig("build/indonesia_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',12))]),i("details",Es,[i("summary",null,[s[117]||(s[117]=i("a",{id:"Rasters.replace_missing-Tuple{Any}",href:"#Rasters.replace_missing-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.replace_missing")],-1)),s[118]||(s[118]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[119]||(s[119]=t(`
julia
replace_missing(a::AbstractRaster, newmissingval)
+replace_missing(a::AbstractRasterStack, newmissingval)

Replace missing values in the array or stack with a new missing value, also updating the missingval field/s.

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{Climate}, :prec; month=1) |> replace_missing
+missingval(A)
+# output
+missing

source

`,7))]),i("details",us,[i("summary",null,[s[120]||(s[120]=i("a",{id:"Rasters.reproject-NTuple{4, Any}",href:"#Rasters.reproject-NTuple{4, Any}"},[i("span",{class:"jlbinding"},"Rasters.reproject")],-1)),s[121]||(s[121]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[122]||(s[122]=t('
julia
reproject(source::GeoFormat, target::GeoFormat, dim::Dimension, val)

reproject uses ArchGDAL.reproject, but implemented for a reprojecting a value array of values, a single dimension at a time.

source

',3))]),i("details",ms,[i("summary",null,[s[123]||(s[123]=i("a",{id:"Rasters.reproject-Tuple{Any}",href:"#Rasters.reproject-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.reproject")],-1)),s[124]||(s[124]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[125]||(s[125]=t('
julia
reproject(obj; crs)

Reproject the lookups of obj to a different crs.

This is a lossless operation for the raster data, as only the lookup values change. This is only possible when the axes of source and destination projections are aligned: the change is usually from a Regular and an Irregular lookup spans.

For converting between projections that are rotated, skewed or warped in any way, use resample.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are silently returned without modification.

Arguments

source

',8))]),i("details",bs,[i("summary",null,[s[126]||(s[126]=i("a",{id:"Rasters.resample-Tuple",href:"#Rasters.resample-Tuple"},[i("span",{class:"jlbinding"},"Rasters.resample")],-1)),s[127]||(s[127]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[128]||(s[128]=t(`
julia
resample(x; kw...)
+resample(xs...; to=first(xs), kw...)

resample uses warp (which uses GDALs gdalwarp) to resample a Raster or RasterStack to a new resolution and optionally new crs, or to snap to the bounds, resolution and crs of the object to.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are iteratively resampled with GDAL and joined back into a single array.

If projections can be converted for each axis independently, it may be faster and more accurate to use reproject.

Run using ArchGDAL to make this method available.

Arguments

Keywords

Note:

Example

Resample a WorldClim layer to match an EarthEnv layer:

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+B = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+
+a = plot(A)
+b = plot(resample(A; to=B))
+
+savefig(a, "build/resample_example_before.png");
+savefig(b, "build/resample_example_after.png"); nothing
+
+# output

Before resample:

After resample:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',20))]),i("details",Fs,[i("summary",null,[s[129]||(s[129]=i("a",{id:"Rasters.setcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.setcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.setcrs")],-1)),s[130]||(s[130]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[131]||(s[131]=t('
julia
setcrs(x, crs)

Set the crs of a Raster, RasterStack, Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

',3))]),i("details",fs,[i("summary",null,[s[132]||(s[132]=i("a",{id:"Rasters.setmappedcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.setmappedcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.setmappedcrs")],-1)),s[133]||(s[133]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[134]||(s[134]=t('
julia
setmappedcrs(x, crs)

Set the mapped crs of a Raster, a RasterStack, a Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

',3))]),i("details",Cs,[i("summary",null,[s[135]||(s[135]=i("a",{id:"Rasters.slice-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.slice-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.slice")],-1)),s[136]||(s[136]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[137]||(s[137]=t('
julia
slice(A::Union{AbstractRaster,AbstractRasterStack,AbstracRasterSeries}, dims) => RasterSeries

Slice views along some dimension/s to obtain a RasterSeries of the slices.

For a Raster or RasterStack this will return a RasterSeries of Raster or RasterStack that are slices along the specified dimensions.

For a RasterSeries, the output is another series where the child objects are sliced and the series dimensions index is now of the child dimensions combined. slice on a RasterSeries with no dimensions will slice along the dimensions shared by both the series and child object.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',6))]),i("details",As,[i("summary",null,[s[138]||(s[138]=i("a",{id:"Rasters.trim-Tuple{Union{AbstractRaster, AbstractRasterStack}}",href:"#Rasters.trim-Tuple{Union{AbstractRaster, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Rasters.trim")],-1)),s[139]||(s[139]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[140]||(s[140]=t(`
julia
trim(x; dims::Tuple, pad::Int)

Trim missingval(x) from x for axes in dims, returning a view of x.

Arguments

Keywords

As trim is lazy, filename and suffix keywords are not used.

Example

Create trimmed layers of Australian habitat heterogeneity.

julia
using Rasters, RasterDataSources, Plots
+layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+
+# Roughly cut out australia
+ausbounds = X(100 .. 160), Y(-50 .. -10)
+aus = st[ausbounds...]
+a = plot(aus)
+
+# Trim missing values and plot
+b = plot(trim(aus))
+
+savefig(a, "build/trim_example_before.png");
+savefig(b, "build/trim_example_after.png"); nothing
+
+# output

Before trim:

After trim:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',16))]),i("details",Rs,[i("summary",null,[s[141]||(s[141]=i("a",{id:"Rasters.warp-Tuple",href:"#Rasters.warp-Tuple"},[i("span",{class:"jlbinding"},"Rasters.warp")],-1)),s[142]||(s[142]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[143]||(s[143]=t(`
julia
warp(A::AbstractRaster, flags::Dict; kw...)

Gives access to the GDALs gdalwarp method given a Dict of flag => value arguments that can be converted to strings, or vectors where multiple space-separated arguments are required.

Arrays with additional dimensions not handled by GDAL (other than X, Y, Band) are sliced, warped, and then combined to match the original array dimensions. These slices will not be written to disk and loaded lazily at this stage - you will need to do that manually if required.

See the gdalwarp docs for a list of arguments.

Run using ArchGDAL to make this method available.

Keywords

Any additional keywords are passed to ArchGDAL.Dataset.

Example

This simply resamples the array with the :tr (output file resolution) and :r flags, giving us a pixelated version:

julia
using Rasters, RasterDataSources, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+a = plot(A)
+
+flags = Dict(
+    :tr => [2.0, 2.0],
+    :r => :near,
+)
+b = plot(warp(A, flags))
+
+savefig(a, "build/warp_example_before.png");
+savefig(b, "build/warp_example_after.png"); nothing
+
+# output

Before warp:

After warp:

In practise, prefer resample for this. But warp may be more flexible.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',18))]),i("details",vs,[i("summary",null,[s[144]||(s[144]=i("a",{id:"Rasters.zonal-Tuple{Any, Union{AbstractRaster, AbstractRasterStack}}",href:"#Rasters.zonal-Tuple{Any, Union{AbstractRaster, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Rasters.zonal")],-1)),s[145]||(s[145]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[146]||(s[146]=t(`
julia
zonal(f, x::Union{Raster,RasterStack}; of, kw...)

Calculate zonal statistics for the the zone of a Raster or RasterStack covered by the of object/s.

Arguments

Keywords

These can be used when of is or contains (a) GeoInterface.jl compatible object(s):

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Shapefile, DataFrames, Downloads, Statistics, Dates
+
+# Download a borders shapefile
+ne_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries"
+shp_url, dbf_url  = ne_url * ".shp", ne_url * ".dbf"
+shp_name, dbf_name = "country_borders.shp", "country_borders.dbf"
+isfile(shp_name) || Downloads.download(shp_url, shp_name)
+isfile(dbf_url) || Downloads.download(dbf_url, dbf_name)
+
+# Download and read a raster stack from WorldClim
+st = RasterStack(WorldClim{Climate}; month=Jan, lazy=false)
+
+# Load the shapes for world countries
+countries = Shapefile.Table(shp_name) |> DataFrame
+
+# Calculate the january mean of all climate variables for all countries
+january_stats = zonal(mean, st; of=countries, boundary=:touches, progress=false) |> DataFrame
+
+# Add the country name column (natural earth has some string errors it seems)
+insertcols!(january_stats, 1, :country => first.(split.(countries.ADMIN, r"[^A-Za-z ]")))
+
+# output
+258×8 DataFrame
+ Row │ country                       tmin       tmax       tavg       prec     
+     │ SubStrin                     Float32    Float32    Float32    Float64  
+─────┼──────────────────────────────────────────────────────────────────────────
+   1 │ Indonesia                      21.5447    29.1864    25.3656   271.063
+   2 │ Malaysia                       21.3087    28.4291    24.8688   273.381
+   3 │ Chile                           7.24534   17.9263    12.5858    78.1287
+   4 │ Bolivia                        17.2065    27.7454    22.4759   192.542
+   5 │ Peru                           15.0273    25.5504    20.2888   180.007
+   6 │ Argentina                      13.6751    27.6715    20.6732    67.1837
+   7 │ Dhekelia Sovereign Base Area    5.87126   15.8991    10.8868    76.25
+   8 │ Cyprus                          5.65921   14.6665    10.1622    97.4474
+
+ 252 │ Spratly Islands                25.0       29.2       27.05      70.5
+ 253 │ Clipperton Island              21.5       33.2727    27.4        6.0
+ 254 │ Macao S                        11.6694    17.7288    14.6988    28.0
+ 255 │ Ashmore and Cartier Islands   NaN        NaN        NaN        NaN
+ 256 │ Bajo Nuevo Bank               NaN        NaN        NaN        NaN
+ 257 │ Serranilla Bank               NaN        NaN        NaN        NaN
+ 258 │ Scarborough Reef              NaN        NaN        NaN        NaN
+                                                  3 columns and 243 rows omitted

source

`,11))]),s[193]||(s[193]=i("h2",{id:"Reference-Internal-functions",tabindex:"-1"},[e("Reference - Internal functions "),i("a",{class:"header-anchor",href:"#Reference-Internal-functions","aria-label":'Permalink to "Reference - Internal functions {#Reference-Internal-functions}"'},"​")],-1)),i("details",Ds,[i("summary",null,[s[147]||(s[147]=i("a",{id:"Rasters.AbstractProjected",href:"#Rasters.AbstractProjected"},[i("span",{class:"jlbinding"},"Rasters.AbstractProjected")],-1)),s[148]||(s[148]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[149]||(s[149]=t('
julia
AbstractProjected <: AbstractSampled

Abstract supertype for projected index lookups.

source

',3))]),i("details",js,[i("summary",null,[s[150]||(s[150]=i("a",{id:"Rasters.FileArray",href:"#Rasters.FileArray"},[i("span",{class:"jlbinding"},"Rasters.FileArray")],-1)),s[151]||(s[151]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[152]||(s[152]=t('
julia
FileArray{S} <: DiskArrays.AbstractDiskArray

Filearray is a DiskArrays.jl AbstractDiskArray. Instead of holding an open object, it just holds a filename string that is opened lazily when it needs to be read.

source

',3))]),i("details",Bs,[i("summary",null,[s[153]||(s[153]=i("a",{id:"Rasters.FileStack",href:"#Rasters.FileStack"},[i("span",{class:"jlbinding"},"Rasters.FileStack")],-1)),s[154]||(s[154]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[155]||(s[155]=t(`
julia
FileStack{S,Na}
+
+FileStack{S,Na}(filename, types, sizes, eachchunk, haschunks, write)

A wrapper object that holds file pointer and size/chunking metadata for a multi-layered stack stored in a single file, typically netcdf or hdf5.

S is a backend type like NCDsource, and Na is a tuple of Symbol keys.

source

`,4))]),i("details",ws,[i("summary",null,[s[156]||(s[156]=i("a",{id:"Rasters.OpenStack",href:"#Rasters.OpenStack"},[i("span",{class:"jlbinding"},"Rasters.OpenStack")],-1)),s[157]||(s[157]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[158]||(s[158]=t(`
julia
OpenStack{X,K}
+
+OpenStack{X,K}(dataset)

A wrapper for any stack-like opened dataset that can be indexed with Symbol keys to retrieve AbstractArray layers.

OpenStack is usually hidden from users, wrapped in a regular RasterStack passed as the function argument in open(stack) when the stack is contained in a single file.

X is a backend type like NCDsource, and K is a tuple of Symbol keys.

source

`,5))]),i("details",xs,[i("summary",null,[s[159]||(s[159]=i("a",{id:"Rasters.RasterDiskArray",href:"#Rasters.RasterDiskArray"},[i("span",{class:"jlbinding"},"Rasters.RasterDiskArray")],-1)),s[160]||(s[160]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[161]||(s[161]=t('
julia
RasterDiskArray <: DiskArrays.AbstractDiskArray

A basic DiskArrays.jl wrapper for objects that don't have one defined yet. When we open a FileArray it is replaced with a RasterDiskArray.

source

',3))]),i("details",Ts,[i("summary",null,[s[162]||(s[162]=i("a",{id:"Base.open-Tuple{Function, AbstractRaster}",href:"#Base.open-Tuple{Function, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.open")],-1)),s[163]||(s[163]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[164]||(s[164]=t(`
julia
open(f, A::AbstractRaster; write=false)

open is used to open any lazy=true AbstractRaster and do multiple operations on it in a safe way. The write keyword opens the file in write lookup so that it can be altered on disk using e.g. a broadcast.

f is a method that accepts a single argument - an Raster object which is just an AbstractRaster that holds an open disk-based object. Often it will be a do block:

lazy=false (in-memory) rasters will ignore open and pass themselves to f.

julia
# A is an \`Raster\` wrapping the opened disk-based object.
+open(Raster(filepath); write=true) do A
+    mask!(A; with=maskfile)
+    A[I...] .*= 2
+    # ...  other things you need to do with the open file
+end

By using a do block to open files we ensure they are always closed again after we finish working with them.

source

`,7))]),i("details",Ss,[i("summary",null,[s[165]||(s[165]=i("a",{id:"Base.read!-Tuple{AbstractRaster, AbstractArray}",href:"#Base.read!-Tuple{AbstractRaster, AbstractArray}"},[i("span",{class:"jlbinding"},"Base.read!")],-1)),s[166]||(s[166]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[167]||(s[167]=t(`
julia
read!(src::Union{AbstractString,AbstractRaster}, dst::AbstractRaster)
+read!(src::Union{AbstractString,AbstractRasterStack}, dst::AbstractRasterStack)
+read!(scr::AbstractRasterSeries, dst::AbstractRasterSeries)

read! will copy the data from src to the object dst.

src can be an object or a file-path String.

source

`,4))]),i("details",qs,[i("summary",null,[s[168]||(s[168]=i("a",{id:"Base.read-Tuple{Union{AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}",href:"#Base.read-Tuple{Union{AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Base.read")],-1)),s[169]||(s[169]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[170]||(s[170]=t(`
julia
read(A::AbstractRaster)
+read(A::AbstractRasterStack)
+read(A::AbstractRasterSeries)

read will move a Rasters.jl object completely to memory.

Keywords

source

`,5))]),i("details",Ls,[i("summary",null,[s[171]||(s[171]=i("a",{id:"Base.skipmissing-Tuple{Raster}",href:"#Base.skipmissing-Tuple{Raster}"},[i("span",{class:"jlbinding"},"Base.skipmissing")],-1)),s[172]||(s[172]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[173]||(s[173]=t('
julia
skipmissing(itr::Raster)

Returns an iterable over the elements in a Raster object, skipping any values equal to either the missingval or missing.

source

',3))]),i("details",Is,[i("summary",null,[s[174]||(s[174]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRasterSeries}",href:"#Base.write-Tuple{AbstractString, AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[175]||(s[175]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[176]||(s[176]=t('
julia
Base.write(filepath::AbstractString, s::AbstractRasterSeries; kw...)

Write any AbstractRasterSeries to multiple files, guessing the backend from the file extension.

The lookup values of the series will be appended to the filepath (before the extension), separated by underscores.

All keywords are passed through to these Raster and RasterStack methods.

Keywords

source

',7))]),i("details",zs,[i("summary",null,[s[177]||(s[177]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRasterStack}",href:"#Base.write-Tuple{AbstractString, AbstractRasterStack}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[178]||(s[178]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[179]||(s[179]=t('
julia
Base.write(filename::AbstractString, s::AbstractRasterStack; kw...)

Write any AbstractRasterStack to one or multiple files, depending on the backend. Backend is guessed from the filename extension or forced with the source keyword.

If the source can't be saved as a stack-like object, individual array layers will be saved.

Keywords

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

source

',17))]),i("details",Ps,[i("summary",null,[s[180]||(s[180]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRaster}",href:"#Base.write-Tuple{AbstractString, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[181]||(s[181]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[182]||(s[182]=t('
julia
Base.write(filename::AbstractString, A::AbstractRaster; [source], kw...)

Write an AbstractRaster to file, guessing the backend from the file extension or using the source keyword.

Keywords

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

Returns filename.

source

',17))]),i("details",Gs,[i("summary",null,[s[183]||(s[183]=i("a",{id:"Base.write-Tuple{String, Rasters.GRDsource, AbstractRaster}",href:"#Base.write-Tuple{String, Rasters.GRDsource, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[184]||(s[184]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[185]||(s[185]=t('
julia
Base.write(filename::AbstractString, ::Type{GRDsource}, s::AbstractRaster; kw...)

Write a Raster to a .grd file with a .gri header file.

This method is called automatically if you write a Raster with a .grd or .gri extension.

Keywords

If this method is called directly the extension of filename will be ignored.

Returns the base of filename with a .grd extension.

source

',8))]),i("details",Ns,[i("summary",null,[s[186]||(s[186]=i("a",{id:"Rasters.checkmem!-Tuple{Bool}",href:"#Rasters.checkmem!-Tuple{Bool}"},[i("span",{class:"jlbinding"},"Rasters.checkmem!")],-1)),s[187]||(s[187]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[188]||(s[188]=t('
julia
checkmem!(x::Bool)

Set checkmem to true or false.

In some architectures memory reporting may be wrong and you may wish to disable memory checks.

This setting can be overridden with the checkmem keyword, where applicable.

source

',5))]),i("details",Os,[i("summary",null,[s[189]||(s[189]=i("a",{id:"Rasters.rplot-Tuple",href:"#Rasters.rplot-Tuple"},[i("span",{class:"jlbinding"},"Rasters.rplot")],-1)),s[190]||(s[190]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[191]||(s[191]=t('
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

source

',5))])])}const Hs=l(x,[["render",Ms]]);export{Ys as __pageData,Hs as default}; diff --git a/previews/PR807/assets/api.md.OKz0SH8-.lean.js b/previews/PR807/assets/api.md.OKz0SH8-.lean.js new file mode 100644 index 00000000..32b94faf --- /dev/null +++ b/previews/PR807/assets/api.md.OKz0SH8-.lean.js @@ -0,0 +1,386 @@ +import{_ as l,c as p,a5 as t,j as i,a as e,G as n,B as o,o as r}from"./chunks/framework.Cl7EIXwS.js";const h="/Rasters.jl/previews/PR807/assets/aggregate_example.vPDkaGne.png",d="/Rasters.jl/previews/PR807/assets/boolmask_example.B6nOyO_A.png",k="/Rasters.jl/previews/PR807/assets/classify_example.CA_6ItEA.png",c="/Rasters.jl/previews/PR807/assets/classify_bang_example.Ch0DZvbI.png",g="/Rasters.jl/previews/PR807/assets/nz_crop_example.CeBIxUDy.png",y="/Rasters.jl/previews/PR807/assets/argentina_crop_example.DlKBBk5m.png",E="/Rasters.jl/previews/PR807/assets/extend_example.DNJ4wwKN.png",u="/Rasters.jl/previews/PR807/assets/boolmask_example.B6nOyO_A.png",m="/Rasters.jl/previews/PR807/assets/mosaic_bang_example.ptHNiUCT.png",b="/Rasters.jl/previews/PR807/assets/mosaic_example_africa.Dpr9JnNl.png",F="/Rasters.jl/previews/PR807/assets/mosaic_example_aus.3EfcKnQU.png",f="/Rasters.jl/previews/PR807/assets/mosaic_example_combined.XY5Q_nfP.png",C="/Rasters.jl/previews/PR807/assets/china_rasterized.kM95Jnlf.png",A="/Rasters.jl/previews/PR807/assets/indonesia_rasterized.CAASrLmh.png",R="/Rasters.jl/previews/PR807/assets/warp_example_before.DrW8As6m.png",v="/Rasters.jl/previews/PR807/assets/resample_example_after.C_gavhhT.png",D="/Rasters.jl/previews/PR807/assets/trim_example_before.B583SoP8.png",j="/Rasters.jl/previews/PR807/assets/trim_example_after.CsDpPakV.png",B="/Rasters.jl/previews/PR807/assets/warp_example_before.DrW8As6m.png",w="/Rasters.jl/previews/PR807/assets/warp_example_after.rgHHAHxc.png",Ys=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"api.md","filePath":"api.md","lastUpdated":null}'),x={name:"api.md"},T={class:"jldocstring custom-block",open:""},S={class:"jldocstring custom-block",open:""},q={class:"jldocstring custom-block",open:""},L={class:"jldocstring custom-block",open:""},I={class:"jldocstring custom-block",open:""},z={class:"jldocstring custom-block",open:""},P={class:"jldocstring custom-block",open:""},G={class:"jldocstring custom-block",open:""},N={class:"jldocstring custom-block",open:""},O={class:"jldocstring custom-block",open:""},M={class:"jldocstring custom-block",open:""},_={class:"jldocstring custom-block",open:""},U={class:"jldocstring custom-block",open:""},W={class:"jldocstring custom-block",open:""},K={class:"jldocstring custom-block",open:""},V={class:"jldocstring custom-block",open:""},X={class:"jldocstring custom-block",open:""},Y={class:"jldocstring custom-block",open:""},H={class:"jldocstring custom-block",open:""},J={class:"jldocstring custom-block",open:""},Z={class:"jldocstring custom-block",open:""},$={class:"jldocstring custom-block",open:""},Q={class:"jldocstring custom-block",open:""},ss={class:"jldocstring custom-block",open:""},is={class:"jldocstring custom-block",open:""},es={class:"jldocstring custom-block",open:""},as={class:"jldocstring custom-block",open:""},ts={class:"jldocstring custom-block",open:""},ns={class:"jldocstring custom-block",open:""},ls={class:"jldocstring custom-block",open:""},ps={class:"jldocstring custom-block",open:""},os={class:"jldocstring custom-block",open:""},rs={class:"jldocstring custom-block",open:""},hs={class:"jldocstring custom-block",open:""},ds={class:"jldocstring custom-block",open:""},ks={class:"jldocstring custom-block",open:""},cs={class:"jldocstring custom-block",open:""},gs={class:"jldocstring custom-block",open:""},ys={class:"jldocstring custom-block",open:""},Es={class:"jldocstring custom-block",open:""},us={class:"jldocstring custom-block",open:""},ms={class:"jldocstring custom-block",open:""},bs={class:"jldocstring custom-block",open:""},Fs={class:"jldocstring custom-block",open:""},fs={class:"jldocstring custom-block",open:""},Cs={class:"jldocstring custom-block",open:""},As={class:"jldocstring custom-block",open:""},Rs={class:"jldocstring custom-block",open:""},vs={class:"jldocstring custom-block",open:""},Ds={class:"jldocstring custom-block",open:""},js={class:"jldocstring custom-block",open:""},Bs={class:"jldocstring custom-block",open:""},ws={class:"jldocstring custom-block",open:""},xs={class:"jldocstring custom-block",open:""},Ts={class:"jldocstring custom-block",open:""},Ss={class:"jldocstring custom-block",open:""},qs={class:"jldocstring custom-block",open:""},Ls={class:"jldocstring custom-block",open:""},Is={class:"jldocstring custom-block",open:""},zs={class:"jldocstring custom-block",open:""},Ps={class:"jldocstring custom-block",open:""},Gs={class:"jldocstring custom-block",open:""},Ns={class:"jldocstring custom-block",open:""},Os={class:"jldocstring custom-block",open:""};function Ms(_s,s,Us,Ws,Ks,Vs){const a=o("Badge");return r(),p("div",null,[s[192]||(s[192]=t('

Index

Reference - Exported functions

',3)),i("details",T,[i("summary",null,[s[0]||(s[0]=i("a",{id:"Rasters.Rasters",href:"#Rasters.Rasters"},[i("span",{class:"jlbinding"},"Rasters.Rasters")],-1)),s[1]||(s[1]=e()),n(a,{type:"info",class:"jlObjectType jlModule",text:"Module"})]),s[2]||(s[2]=i("p",null,[i("a",{href:"https://github.com/rafaqz/Rasters.jl/blob/9a1be0473d9caebb8381ce8e9079c4f4349d94ce/src/Rasters.jl#L4",target:"_blank",rel:"noreferrer"},"source")],-1))]),i("details",S,[i("summary",null,[s[3]||(s[3]=i("a",{id:"Rasters.AbstractRaster",href:"#Rasters.AbstractRaster"},[i("span",{class:"jlbinding"},"Rasters.AbstractRaster")],-1)),s[4]||(s[4]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[5]||(s[5]=t('
julia
AbstractRaster <: DimensionalData.AbstractDimArray

Abstract supertype for objects that wrap an array (or location of an array) and metadata about its contents. It may be memory or hold a FileArray, which holds the filename, and is only opened when required.

AbstractRasters inherit from AbstractDimArray from DimensionalData.jl. They can be indexed as regular Julia arrays or with DimensionalData.jl Dimensions. They will plot as a heatmap in Plots.jl with correct coordinates and labels, even after slicing with getindex or view. getindex on a AbstractRaster will always return a memory-backed Raster.

source

',4))]),i("details",q,[i("summary",null,[s[6]||(s[6]=i("a",{id:"Rasters.AbstractRasterSeries",href:"#Rasters.AbstractRasterSeries"},[i("span",{class:"jlbinding"},"Rasters.AbstractRasterSeries")],-1)),s[7]||(s[7]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[8]||(s[8]=t('
julia
AbstractRasterSeries <: DimensionalData.AbstractDimensionalArray

Abstract supertype for high-level DimensionalArray that hold RasterStacks, Rasters, or the paths they can be loaded from. RasterSeries are indexed with dimensions as with a AbstractRaster. This is useful when you have multiple files containing rasters or stacks of rasters spread over dimensions like time and elevation.

As much as possible, implementations should facilitate loading entire directories and detecting the dimensions from metadata.

This allows syntax like below for a series of stacks of arrays:

julia
RasterSeries[Time(Near(DateTime(2001, 1))][:temp][Y(Between(70, 150)), X(Between(-20,20))] |> plot`

RasterSeries is the concrete implementation.

source

',7))]),i("details",L,[i("summary",null,[s[9]||(s[9]=i("a",{id:"Rasters.AbstractRasterStack",href:"#Rasters.AbstractRasterStack"},[i("span",{class:"jlbinding"},"Rasters.AbstractRasterStack")],-1)),s[10]||(s[10]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[11]||(s[11]=t('
julia
AbstractRasterStack

Abstract supertype for objects that hold multiple AbstractRasters that share spatial dimensions.

They are NamedTuple-like structures that may either contain NamedTuple of AbstractRasters, string paths that will load AbstractRasters, or a single path that points to a file containing multiple layers, like NetCDF or HDF5. Use and syntax is similar or identical for all cases.

AbstractRasterStack can hold layers that share some or all of their dimensions. They cannot have the same dimension with different length or spatial extent as another layer.

getindex on an AbstractRasterStack generally returns a memory backed standard Raster. raster[:somelayer] |> plot plots the layers array, while raster[:somelayer, X(1:100), Band(2)] |> plot will plot the subset without loading the whole array.

getindex on an AbstractRasterStack with a key returns another stack with getindex applied to all the arrays in the stack.

source

',7))]),i("details",I,[i("summary",null,[s[12]||(s[12]=i("a",{id:"Rasters.Band",href:"#Rasters.Band"},[i("span",{class:"jlbinding"},"Rasters.Band")],-1)),s[13]||(s[13]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[14]||(s[14]=t(`
julia
Band <: Dimension
+
+Band(val=:)

Band Dimension for multi-band rasters.

Example:

julia
banddim = Band(10:10:100)
+# Or
+val = A[Band(1)]
+# Or
+mean(A; dims=Band)

source

`,5))]),i("details",z,[i("summary",null,[s[15]||(s[15]=i("a",{id:"Rasters.Mapped",href:"#Rasters.Mapped"},[i("span",{class:"jlbinding"},"Rasters.Mapped")],-1)),s[16]||(s[16]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[17]||(s[17]=t(`
julia
Mapped <: AbstractProjected
+
+Mapped(order, span, sampling, crs, mappedcrs)
+Mapped(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs=nothing, mappedcrs)

An AbstractSampled Lookup, where the dimension index has been mapped to another projection, usually lat/lon or EPSG(4326). Mapped matches the dimension format commonly used in netcdf files.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

The mapped dimension index will be used as for Sampled, but to save in another format the underlying crs may be used to convert it.

source

`,5))]),i("details",P,[i("summary",null,[s[18]||(s[18]=i("a",{id:"Rasters.Projected",href:"#Rasters.Projected"},[i("span",{class:"jlbinding"},"Rasters.Projected")],-1)),s[19]||(s[19]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[20]||(s[20]=t(`
julia
Projected <: AbstractProjected
+
+Projected(order, span, sampling, crs, mappedcrs)
+Projected(; order=AutoOrder(), span=AutoSpan(), sampling=AutoSampling(), crs, mappedcrs=nothing)

An AbstractSampled Lookup with projections attached.

Fields and behaviours are identical to Sampled with the addition of crs and mappedcrs fields.

If both crs and mappedcrs fields contain CRS data (in a GeoFormat wrapper from GeoFormatTypes.jl) the selector inputs and plot axes will be converted from and to the specified mappedcrs projection automatically. A common use case would be to pass mappedcrs=EPSG(4326) to the constructor when loading eg. a GDALarray:

julia
GDALarray(filename; mappedcrs=EPSG(4326))

The underlying crs will be detected by GDAL.

If mappedcrs is not supplied (ie. mappedcrs=nothing), the base index will be shown on plots, and selectors will need to use whatever format it is in.

source

`,8))]),i("details",G,[i("summary",null,[s[21]||(s[21]=i("a",{id:"Rasters.Raster",href:"#Rasters.Raster"},[i("span",{class:"jlbinding"},"Rasters.Raster")],-1)),s[22]||(s[22]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[23]||(s[23]=t(`
julia
Raster <: AbstractRaster
+
+Raster(filepath::String; kw...)
+Raster(A::AbstractDimArray; kw...)
+Raster(A::AbstractArray, dims; kw...)

A generic AbstractRaster for spatial/raster array data. It can hold either memory-backed arrays or, if lazy=true, a FileArray, which stores the String path to an unopened file.

If lazy=true, the file will only be opened lazily when it is indexed with getindex or when read(A) is called. Broadcasting, taking a view, reversing, and most other methods will not load data from disk; they will be applied later, lazily.

Arguments

Keywords

When a filepath String is used:

When A is an AbstractDimArray:

source

`,12))]),i("details",N,[i("summary",null,[s[24]||(s[24]=i("a",{id:"Rasters.RasterSeries",href:"#Rasters.RasterSeries"},[i("span",{class:"jlbinding"},"Rasters.RasterSeries")],-1)),s[25]||(s[25]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[26]||(s[26]=t(`
julia
RasterSeries <: AbstractRasterSeries
+
+RasterSeries(rasters::AbstractArray{<:AbstractRaster}, dims; [refdims])
+RasterSeries(stacks::AbstractArray{<:AbstractRasterStack}, dims; [refdims]) 
+
+RasterSeries(paths::AbstractArray{<:AbstractString}, dims; child, duplicate_first, kw...)
+RasterSeries(path:::AbstractString, dims; ext, separator, child, duplicate_first, kw...)

Concrete implementation of AbstractRasterSeries.

A RasterSeries is an array of Rasters or RasterStacks, along some dimension(s).

Existing Raster RasterStack can be wrapped in a RasterSeries, or new files can be loaded from an array of String or from a single String.

A single String can refer to a whole directory, or the name of a series of files in a directory, sharing a common stem. The differnce between the filenames can be used as the lookup for the series.

For example, with some tifs at these paths :

"series_dir/myseries_2001-01-01T00:00:00.tif"
+"series_dir/myseries_2002-01-01T00:00:00.tif"

We can load a RasterSeries with a DateTime lookup:

julia
julia> ser = RasterSeries("series_dir/myseries.tif", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

The DateTime suffix is parsed from the filenames. Using Ti(Int) would try to parse integers instead.

Just using the directory will also work, unless there are other files mixed in it:

julia
julia> ser = RasterSeries("series_dir", Ti(DateTime))
+2-element RasterSeries{Raster,1} with dimensions: 
+  Ti Sampled{DateTime} DateTime[DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")] ForwardOrdered Irregular Points

Arguments

Keywords

When loading a series from a Vector of String paths or a single String path:

When loading a series from a single String path:

Others:

source

`,22))]),i("details",O,[i("summary",null,[s[27]||(s[27]=i("a",{id:"Rasters.RasterStack",href:"#Rasters.RasterStack"},[i("span",{class:"jlbinding"},"Rasters.RasterStack")],-1)),s[28]||(s[28]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[29]||(s[29]=t(`
julia
RasterStack <: AbstrackRasterStack
+
+RasterStack(data...; name, kw...)
+RasterStack(data::Union{Vector,Tuple}; name, kw...)
+RasterStack(data::NamedTuple; kw...))
+RasterStack(data::RasterStack; kw...)
+RasterStack(data::Raster; layersfrom=Band, kw...)
+RasterStack(filepath::AbstractString; kw...)

Load a file path or a NamedTuple of paths as a RasterStack, or convert arguments, a Vector or NamedTuple of Rasters to RasterStack.

Arguments

Keywords

For when one or multiple filepaths are used:

For when a single Raster is used:

julia
files = (temp="temp.tif", pressure="pressure.tif", relhum="relhum.tif")
+stack = RasterStack(files; mappedcrs=EPSG(4326))
+stack[:relhum][Lat(Contains(-37), Lon(Contains(144))

source

`,12))]),i("details",M,[i("summary",null,[s[30]||(s[30]=i("a",{id:"DimensionalData.modify-Tuple{Any, AbstractRasterSeries}",href:"#DimensionalData.modify-Tuple{Any, AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"DimensionalData.modify")],-1)),s[31]||(s[31]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[32]||(s[32]=t('
julia
modify(f, series::AbstractRasterSeries)

Apply function f to the data of the child object. If the child is an AbstractRasterStack the function will be passed on to its child AbstractRasters.

f must return an identically sized array.

This method triggers a complete rebuild of all objects, and disk based objects will be transferred to memory.

An example of the usefulnesss of this is for swapping out array backend for an entire series to CuArray from CUDA.jl to copy data to a GPU.

source

',6))]),i("details",_,[i("summary",null,[s[33]||(s[33]=i("a",{id:"GeoInterface.crs-Tuple{Union{Tuple{Dimension, Vararg{Dimension}}, AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}",href:"#GeoInterface.crs-Tuple{Union{Tuple{Dimension, Vararg{Dimension}}, AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"GeoInterface.crs")],-1)),s[34]||(s[34]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[35]||(s[35]=t('
julia
crs(x::Raster)

Get the projected coordinate reference system of a Y or X Dimension, or of the Y/X dims of an AbstractRaster.

For Mapped lookup this may be nothing as there may be no projected coordinate reference system at all. See setcrs to set it manually.

source

',4))]),i("details",U,[i("summary",null,[s[36]||(s[36]=i("a",{id:"Rasters.aggregate",href:"#Rasters.aggregate"},[i("span",{class:"jlbinding"},"Rasters.aggregate")],-1)),s[37]||(s[37]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[38]||(s[38]=t(`
julia
aggregate(method, object, scale; filename, progress, skipmissing)

Aggregate a Raster, or all arrays in a RasterStack or RasterSeries, by scale using method.

Arguments

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

Example

julia
using Rasters, RasterDataSources, Statistics, Plots
+import ArchGDAL
+using Rasters: Center
+st = read(RasterStack(WorldClim{Climate}; month=1))
+ag = aggregate(Center(), st, (Y(20), X(20)); skipmissingval=true, progress=false)
+plot(ag)
+savefig("build/aggregate_example.png"); nothing
+# output

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',12))]),i("details",W,[i("summary",null,[s[39]||(s[39]=i("a",{id:"Rasters.aggregate!-Tuple{Locus, AbstractRaster, Any, Any}",href:"#Rasters.aggregate!-Tuple{Locus, AbstractRaster, Any, Any}"},[i("span",{class:"jlbinding"},"Rasters.aggregate!")],-1)),s[40]||(s[40]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[41]||(s[41]=t('
julia
aggregate!(method, dst::AbstractRaster, src::AbstractRaster, scale; skipmissingval=false)

Aggregate array src to array dst by scale, using method.

Arguments

When the aggregation scale of is larger than the array axis, the length of the axis is used.

Keywords

Note: currently it is much faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',9))]),i("details",K,[i("summary",null,[s[42]||(s[42]=i("a",{id:"Rasters.boolmask",href:"#Rasters.boolmask"},[i("span",{class:"jlbinding"},"Rasters.boolmask")],-1)),s[43]||(s[43]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[44]||(s[44]=t(`
julia
boolmask(obj::Raster; [missingval])
+boolmask(obj; [to, res, size])
+boolmask(obj::RasterStack; alllayers=true, kw...)

Create a mask array of Bool values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted.

The array returned from calling boolmask on a AbstractRaster is a Raster with the same dimensions as the original array and a missingval of false.

Arguments

Raster / RasterStack Keywords

Keywords

And specifically for shape=:polygon:

For tabular data, feature collections and other iterables

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+boolmask(wc) |> plot
+
+savefig("build/boolmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',18))]),i("details",V,[i("summary",null,[s[45]||(s[45]=i("a",{id:"Rasters.cellarea-Tuple{Any}",href:"#Rasters.cellarea-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.cellarea")],-1)),s[46]||(s[46]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[47]||(s[47]=t(`
julia
cellarea([method], x)

Gives the approximate area of each gridcell of x. By assuming the earth is a sphere, it approximates the true size to about 0.1%, depending on latitude.

Run using ArchGDAL to make this method fully available.

method can be Spherical(; radius) (the default) or Planar().

Example

julia
using Rasters, ArchGDAL, Rasters.Lookups
+xdim = X(Projected(90.0:10.0:120; sampling=Intervals(Start()), crs=EPSG(4326)))
+ydim = Y(Projected(0.0:10.0:50; sampling=Intervals(Start()), crs=EPSG(4326)))
+myraster = rand(xdim, ydim)
+cs = cellarea(myraster)
+
+# output
+╭───────────────────────╮
+4×6 Raster{Float64,2} │
+├───────────────────────┴─────────────────────────────────────────────────── dims ┐
+ X Projected{Float64} 90.0:10.0:120.0 ForwardOrdered Regular Intervals{Start},
+ Y Projected{Float64} 0.0:10.0:50.0 ForwardOrdered Regular Intervals{Start}
+├───────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (90.0, 130.0), Y = (0.0, 60.0))
+
+  crs: EPSG:4326
+└─────────────────────────────────────────────────────────────────────────────────┘
+  0.0        10.0        20.0        30.0            40.0      50.0
+  90.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 100.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 110.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0
+ 120.0  1.23017e6   1.19279e6   1.11917e6   1.01154e6  873182.0  708290.0

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,9))]),i("details",X,[i("summary",null,[s[48]||(s[48]=i("a",{id:"Rasters.classify",href:"#Rasters.classify"},[i("span",{class:"jlbinding"},"Rasters.classify")],-1)),s[49]||(s[49]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[50]||(s[50]=t(`
julia
classify(x, pairs; lower=(>=), upper=(<), others=nothing)
+classify(x, pairs...; lower, upper, others)

Create a new array with values in x classified by the values in pairs.

pairs can hold tuples fo values (2, 3), a Fix2 function e.g. <=(1), a Tuple of Fix2 e.g. (>=(4), <(7)), or an IntervalSets.jl interval, e.g. 3..9 or OpenInterval(10, 12). pairs can also be a n * 3 matrix where each row is lower bounds, upper bounds, replacement.

If tuples or a Matrix are used, the lower and upper keywords define how the lower and upper boundaries are chosen.

If others is set other values not covered in pairs will be set to that values.

Arguments

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :tavg; month=1)
+classes = <=(15) => 10,
+          15..25 => 20,
+          25..35 => 30,
+          >(35) => 40
+classified = classify(A, classes; others=0, missingval=0)
+plot(classified; c=:magma)
+
+savefig("build/classify_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',14))]),i("details",Y,[i("summary",null,[s[51]||(s[51]=i("a",{id:"Rasters.classify!-Tuple{AbstractRaster, Pair, Vararg{Pair}}",href:"#Rasters.classify!-Tuple{AbstractRaster, Pair, Vararg{Pair}}"},[i("span",{class:"jlbinding"},"Rasters.classify!")],-1)),s[52]||(s[52]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[53]||(s[53]=t(`
julia
classify!(x, pairs...; lower, upper, others)
+classify!(x, pairs; lower, upper, others)

Classify the values of x in-place, by the values in pairs.

If Fix2 is not used, the lower and upper keywords

If others is set other values not covered in pairs will be set to that values.

Arguments

Keywords

Example

classify! to disk, with key steps:

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+# Download and copy the file
+filename = getraster(WorldClim{Climate}, :tavg; month=6)
+tempfile = tempname() * ".tif"
+cp(filename, tempfile)
+# Define classes
+classes = (5, 15) => 10,
+          (15, 25) => 20,
+          (25, 35) => 30,
+          >=(35) => 40
+# Open the file with write permission
+open(Raster(tempfile); write=true) do A
+    classify!(A, classes; others=0)
+end
+# Open it again to plot the changes
+plot(Raster(tempfile); c=:magma)
+
+savefig("build/classify_bang_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',15))]),i("details",H,[i("summary",null,[s[54]||(s[54]=i("a",{id:"Rasters.combine-Tuple{AbstractRasterSeries}",href:"#Rasters.combine-Tuple{AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"Rasters.combine")],-1)),s[55]||(s[55]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[56]||(s[56]=t('
julia
combine(A::AbstracRasterSeries; [dims], [lazy]) => Raster

Combine a RasterSeries along some dimension/s, creating a new Raster or RasterStack, depending on the contents of the series.

If dims are passed, only the specified dimensions will be combined with a RasterSeries returned, unless dims is all the dims in the series.

If lazy, concatenate lazily. The default is to concatenate lazily for lazy Rasters and eagerly otherwise.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',6))]),i("details",J,[i("summary",null,[s[57]||(s[57]=i("a",{id:"Rasters.convertlookup-Tuple{Type{<:Lookup}, AbstractDimArray}",href:"#Rasters.convertlookup-Tuple{Type{<:Lookup}, AbstractDimArray}"},[i("span",{class:"jlbinding"},"Rasters.convertlookup")],-1)),s[58]||(s[58]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[59]||(s[59]=t('
julia
convertlookup(dstlookup::Type{<:Lookup}, x)

Convert the dimension lookup between Projected and Mapped. Other dimension lookups pass through unchanged.

This is used to e.g. save a netcdf file to GeoTiff.

source

',4))]),i("details",Z,[i("summary",null,[s[60]||(s[60]=i("a",{id:"Rasters.coverage!-Tuple{Union{typeof(sum), typeof(union)}, AbstractRaster, Any}",href:"#Rasters.coverage!-Tuple{Union{typeof(sum), typeof(union)}, AbstractRaster, Any}"},[i("span",{class:"jlbinding"},"Rasters.coverage!")],-1)),s[61]||(s[61]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[62]||(s[62]=t('
julia
coverage!(A, geom; [mode, scale])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

source

',8))]),i("details",$,[i("summary",null,[s[63]||(s[63]=i("a",{id:"Rasters.coverage-Tuple{Any}",href:"#Rasters.coverage-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.coverage")],-1)),s[64]||(s[64]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[65]||(s[65]=t(`
julia
coverage(mode, geom; [to, res, size, scale, verbose, progress])
+coverage(geom; [to, mode, res, size, scale, verbose, progress])

Calculate the area of a raster covered by GeoInterface.jl compatible geometry geom, as a fraction.

Each pixel is assigned a grid of points (by default 10 x 10) that are each checked to be inside the geometry. The sum divided by the number of points to give coverage.

In practice, most pixel coverage is not calculated this way - shortcuts that produce the same result are taken wherever possible.

If geom is an AbstractVector or table, the mode keyword will determine how coverage is combined.

Keywords

source

`,8))]),i("details",Q,[i("summary",null,[s[66]||(s[66]=i("a",{id:"Rasters.crop",href:"#Rasters.crop"},[i("span",{class:"jlbinding"},"Rasters.crop")],-1)),s[67]||(s[67]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[68]||(s[68]=t(`
julia
crop(x; to, touches=false, [geometrycolumn])
+crop(xs...; to)

Crop one or multiple AbstractRaster or AbstractRasterStack x to match the size of the object to, or smallest of any dimensions that are shared.

crop is lazy, using a view into the object rather than allocating new memory.

Keywords

As crop is lazy, filename and suffix keywords are not used.

Example

Crop to another raster:

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out New Zealand from the evenness raster
+nz_bounds = X(165 .. 180), Y(-50 .. -32)
+nz_evenness = evenness[nz_bounds...]
+
+# Crop range to match evenness
+nz_range = crop(rnge; to=nz_evenness)
+plot(nz_range)
+
+savefig("build/nz_crop_example.png")
+nothing
+
+# output

Crop to a polygon:

julia
using Rasters, RasterDataSources, Plots, Dates, Shapefile, Downloads
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+shp = Shapefile.Handle(shapefile_name).shapes[6]
+
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+argentina_evenness = crop(evenness; to=shp)
+plot(argentina_evenness)
+
+savefig("build/argentina_crop_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',15))]),i("details",ss,[i("summary",null,[s[69]||(s[69]=i("a",{id:"Rasters.disaggregate",href:"#Rasters.disaggregate"},[i("span",{class:"jlbinding"},"Rasters.disaggregate")],-1)),s[70]||(s[70]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[71]||(s[71]=t('
julia
disaggregate(method, object, scale; filename, progress, keys)

Disaggregate array, or all arrays in a stack or series, by some scale.

Arguments

Keywords

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',8))]),i("details",is,[i("summary",null,[s[72]||(s[72]=i("a",{id:"Rasters.disaggregate!-Tuple{Locus, AbstractRaster, Any, Any}",href:"#Rasters.disaggregate!-Tuple{Locus, AbstractRaster, Any, Any}"},[i("span",{class:"jlbinding"},"Rasters.disaggregate!")],-1)),s[73]||(s[73]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[74]||(s[74]=t('
julia
disaggregate!(method, dst::AbstractRaster, src::AbstractRaster, filename, scale)

Disaggregate array src to array dst by some scale, using method.

Note: currently it is faster to aggregate over memory-backed arrays. Use read on src before use where required.

source

',5))]),i("details",es,[i("summary",null,[s[75]||(s[75]=i("a",{id:"Rasters.extend",href:"#Rasters.extend"},[i("span",{class:"jlbinding"},"Rasters.extend")],-1)),s[76]||(s[76]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[77]||(s[77]=t(`
julia
extend(xs...; [to])
+extend(xs; [to])
+extend(x::Union{AbstractRaster,AbstractRasterStack}; to, kw...)

Extend one or multiple AbstractRaster to match the area covered by all xs, or by the keyword argument to.

Keywords

julia
using Rasters, RasterDataSources, Plots
+evenness = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+rnge = Raster(EarthEnv{HabitatHeterogeneity}, :range)
+
+# Roughly cut out South America
+sa_bounds = X(-88 .. -32), Y(-57 .. 13)
+sa_evenness = evenness[sa_bounds...]
+
+# Extend range to match the whole-world raster
+sa_range = extend(sa_evenness; to=rnge)
+plot(sa_range)
+
+savefig("build/extend_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',8))]),i("details",as,[i("summary",null,[s[78]||(s[78]=i("a",{id:"Rasters.extract",href:"#Rasters.extract"},[i("span",{class:"jlbinding"},"Rasters.extract")],-1)),s[79]||(s[79]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[80]||(s[80]=t(`
julia
extract(x, data; kw...)

Extracts the value of Raster or RasterStack at given points, returning an iterable of NamedTuple with properties for :geometry and raster or stack layer values.

Note that if objects have more dimensions than the length of the point tuples, sliced arrays or stacks will be returned instead of single values.

Arguments

Keywords

geometrycolumn: Symbol to manually select the column the geometries are in when data is a Tables.jl compatible table, or a tuple of Symbol for columns of point coordinates.

Example

Here we extract points matching the occurrence of the Mountain Pygmy Possum, Burramis parvus. This could be used to fit a species distribution model.

julia
using Rasters, RasterDataSources, ArchGDAL, GBIF2, CSV
+
+# Get a stack of BioClim layers, and replace missing values with \`missing\`
+st = RasterStack(WorldClim{BioClim}, (1, 3, 5, 7, 12)) |> replace_missing
+
+# Download some occurrence data
+obs = GBIF2.occurrence_search("Burramys parvus"; limit=5, year="2009")
+
+# use \`extract\` to get values for all layers at each observation point.
+# We \`collect\` to get a \`Vector\` from the lazy iterator.
+extract(st, obs; skipmissing=true)
+
+# output
+5-element Vector{NamedTuple{(:geometry, :bio1, :bio3, :bio5, :bio7, :bio12)}}:
+ (geometry = (0.21, 40.07), bio1 = 17.077084f0, bio3 = 41.20417f0, bio5 = 30.1f0, bio7 = 24.775f0, bio12 = 446.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.03, 39.97), bio1 = 17.076923f0, bio3 = 39.7983f0, bio5 = 29.638462f0, bio7 = 24.153847f0, bio12 = 441.0f0)
+ (geometry = (0.52, 40.37), bio1 = missing, bio3 = missing, bio5 = missing, bio7 = missing, bio12 = missing)
+ (geometry = (0.32, 40.24), bio1 = 16.321388f0, bio3 = 41.659454f0, bio5 = 30.029825f0, bio7 = 25.544561f0, bio12 = 480.0f0)

Note: passing in arrays, geometry collections or feature collections containing a mix of points and other geometries has undefined results.

source

`,13))]),i("details",ts,[i("summary",null,[s[81]||(s[81]=i("a",{id:"Rasters.mappedbounds",href:"#Rasters.mappedbounds"},[i("span",{class:"jlbinding"},"Rasters.mappedbounds")],-1)),s[82]||(s[82]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[83]||(s[83]=t('
julia
mappedbounds(x)

Get the bounds converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular bounds.

source

',4))]),i("details",ns,[i("summary",null,[s[84]||(s[84]=i("a",{id:"Rasters.mappedcrs",href:"#Rasters.mappedcrs"},[i("span",{class:"jlbinding"},"Rasters.mappedcrs")],-1)),s[85]||(s[85]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[86]||(s[86]=t('
julia
mappedcrs(x)

Get the mapped coordinate reference system for the Y/X dims of an array.

In Projected lookup this is used to convert Selector values form the mappedcrs defined projection to the underlying projection, and to show plot axes in the mapped projection.

In Mapped lookup this is the coordinate reference system of the index values. See setmappedcrs to set it manually.

source

',5))]),i("details",ls,[i("summary",null,[s[87]||(s[87]=i("a",{id:"Rasters.mappedindex",href:"#Rasters.mappedindex"},[i("span",{class:"jlbinding"},"Rasters.mappedindex")],-1)),s[88]||(s[88]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[89]||(s[89]=t('
julia
mappedindex(x)

Get the index value of a dimension converted to the mappedcrs value.

Without ArchGDAL loaded, this is just the regular dim value.

source

',4))]),i("details",ps,[i("summary",null,[s[90]||(s[90]=i("a",{id:"Rasters.mask!",href:"#Rasters.mask!"},[i("span",{class:"jlbinding"},"Rasters.mask!")],-1)),s[91]||(s[91]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[92]||(s[92]=t(`
julia
mask!(x; with, missingval=missingval(A))

Mask A by the missing values of with, or by all values outside with if it is a polygon.

If with is a polygon, creates a new array where points falling outside the polygon have been replaced by missingval(A).

Return a new array with values of A masked by the missing values of with, or by a polygon.

Arguments

Keywords

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask to match the size and projection.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(RasterStack(AWAP, (:tmin, :tmax); date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45), c=:imola)
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+mask!(awap; with=wc_mask)
+b = plot(awap; clims=(10, 45))
+
+savefig(a, "build/mask_bang_example_before.png");
+savefig(b, "build/mask_bang_example_after.png"); nothing
+
+# output

Before mask!:

After mask!:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,15))]),i("details",os,[i("summary",null,[s[93]||(s[93]=i("a",{id:"Rasters.mask-Tuple{Any}",href:"#Rasters.mask-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.mask")],-1)),s[94]||(s[94]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[95]||(s[95]=t(`
julia
mask(A:AbstractRaster; with, missingval=missingval(A))
+mask(x; with)

Return a new array with values of A masked by the missing values of with, or by the shape of with, if with is a geometric object.

Arguments

Keywords

Geometry keywords

These can be used when with is a GeoInterface.jl compatible object:

Example

Mask an unmasked AWAP layer with a masked WorldClim layer, by first resampling the mask.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+
+# Load and plot the file
+awap = read(Raster(AWAP, :tmax; date=DateTime(2001, 1, 1)))
+a = plot(awap; clims=(10, 45))
+
+# Create a mask my resampling a worldclim file
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+wc_mask = resample(wc; to=awap)
+
+# Mask
+awap_masked = mask(awap; with=wc_mask)
+b = plot(awap_masked; clims=(10, 45))
+
+savefig(a, "build/mask_example_before.png");
+savefig(b, "build/mask_example_after.png"); nothing
+# output

Before mask:

After mask:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

`,16))]),i("details",rs,[i("summary",null,[s[96]||(s[96]=i("a",{id:"Rasters.missingmask-Tuple{Any}",href:"#Rasters.missingmask-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.missingmask")],-1)),s[97]||(s[97]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[98]||(s[98]=t(`
julia
missingmask(obj::Raster; kw...)
+missingmask(obj; [to, res, size, collapse])
+missingmask(obj::RasterStack; alllayers = true, kw...)

Create a mask array of missing and true values, from another Raster. AbstractRasterStack or AbstractRasterSeries are also accepted-

For AbstractRaster the default missingval is missingval(A), but others can be chosen manually.

The array returned from calling missingmask on a AbstractRaster is a Raster with the same size and fields as the original array.

Arguments

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates
+wc = Raster(WorldClim{Climate}, :prec; month=1)
+missingmask(wc) |> plot
+
+savefig("build/missingmask_example.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',13))]),i("details",hs,[i("summary",null,[s[99]||(s[99]=i("a",{id:"Rasters.missingval",href:"#Rasters.missingval"},[i("span",{class:"jlbinding"},"Rasters.missingval")],-1)),s[100]||(s[100]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[101]||(s[101]=t('
julia
missingval(x)

Returns the value representing missing data in the dataset

source

',3))]),i("details",ds,[i("summary",null,[s[102]||(s[102]=i("a",{id:"Rasters.mosaic!-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}",href:"#Rasters.mosaic!-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}"},[i("span",{class:"jlbinding"},"Rasters.mosaic!")],-1)),s[103]||(s[103]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[104]||(s[104]=t(`
julia
mosaic!(f, x, regions...; missingval, atol)
+mosaic!(f, x, regions::Tuple; missingval, atol)

Combine regions in x using the function f.

Arguments

Keywords

Example

Cut out Australia and Africa stacks, then combined them into a single stack.

julia
using Rasters, RasterDataSources, ArchGDAL, Statistics, Plots
+st = read(RasterStack(WorldClim{Climate}; month=1))
+aus = st[X=100.0 .. 160.0, Y=-50.0 .. -10.0]
+africa = st[X=-20.0 .. 60.0, Y=-40.0 .. 35.0]
+mosaic!(first, st, aus, africa)
+plot(st)
+savefig("build/mosaic_bang_example.png")
+nothing
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',12))]),i("details",ks,[i("summary",null,[s[105]||(s[105]=i("a",{id:"Rasters.mosaic-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}",href:"#Rasters.mosaic-Tuple{Function, Union{AbstractRaster, AbstractRasterStack}, Vararg{Union{AbstractRaster, AbstractRasterStack}}}"},[i("span",{class:"jlbinding"},"Rasters.mosaic")],-1)),s[106]||(s[106]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[107]||(s[107]=t(`
julia
mosaic(f, regions...; missingval, atol)
+mosaic(f, regions; missingval, atol)

Combine regions into a single raster.

Arguments

Keywords

If your mosaic has has apparent line errors, increase the atol value.

Example

Here we cut out Australia and Africa from a stack, and join them with mosaic.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+st = RasterStack(WorldClim{Climate}; month=1);
+
+africa = st[X(-20.0 .. 60.0), Y(-40.0 .. 35.0)]
+a = plot(africa)
+
+aus = st[X(100.0 .. 160.0), Y(-50.0 .. -10.0)]
+b = plot(aus)
+
+# Combine with mosaic
+mos = mosaic(first, aus, africa)
+c = plot(mos)
+
+savefig(a, "build/mosaic_example_africa.png")
+savefig(b, "build/mosaic_example_aus.png")
+savefig(c, "build/mosaic_example_combined.png")
+nothing
+# output

Individual continents

Mosaic of continents

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',17))]),i("details",cs,[i("summary",null,[s[108]||(s[108]=i("a",{id:"Rasters.points-Tuple{AbstractRaster}",href:"#Rasters.points-Tuple{AbstractRaster}"},[i("span",{class:"jlbinding"},"Rasters.points")],-1)),s[109]||(s[109]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[110]||(s[110]=t('
julia
points(A::AbstractRaster; dims=(YDim, XDim), ignore_missing) => Array{Tuple}

Returns a generator of the points in A for dimensions in dims, where points are a tuple of the values in each specified dimension index.

Keywords

The order of dims determines the order of the points.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',7))]),i("details",gs,[i("summary",null,[s[111]||(s[111]=i("a",{id:"Rasters.rasterize",href:"#Rasters.rasterize"},[i("span",{class:"jlbinding"},"Rasters.rasterize")],-1)),s[112]||(s[112]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[113]||(s[113]=t(`
julia
rasterize([reducer], data; geometrycolumn, kw...)

Rasterize a GeoInterface.jl compatable geometry or feature, or a Tables.jl table with a :geometry column of GeoInterface.jl objects, or points columns specified by geometrycolumn

Arguments

Keywords

These are detected automatically from data where possible.

Note on threading. Performance may be much better with threaded=false if reducer/op are not threadsafe. sum, prod, maximum, minimum count and mean (by combining sum and count) are threadsafe. If you know your algorithm is threadsafe, use threadsafe=true to allow all optimisations. Functions passed to fill are always threadsafe, and ignore the threadsafe argument.

Example

Rasterize a shapefile for China and plot, with a border.

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for china
+china_border = Shapefile.Handle(shapefile_name).shapes[10]
+
+# Rasterize the border polygon
+china = rasterize(last, china_border; res=0.1, missingval=0, fill=1, boundary=:touches, progress=false)
+
+# And plot
+p = plot(china; color=:spring, legend=false)
+plot!(p, china_border; fillalpha=0, linewidth=0.6)
+
+savefig("build/china_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',14))]),i("details",ys,[i("summary",null,[s[114]||(s[114]=i("a",{id:"Rasters.rasterize!",href:"#Rasters.rasterize!"},[i("span",{class:"jlbinding"},"Rasters.rasterize!")],-1)),s[115]||(s[115]=e()),n(a,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[116]||(s[116]=t(`
julia
rasterize!([reducer], dest, data; kw...)

Rasterize the geometries in data into the Raster or RasterStack dest, using the values specified by fill.

Arguments

Keywords

These are detected automatically from A and data where possible.

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Plots, Dates, Shapefile, GeoInterface, Downloads
+using Rasters.Lookups
+
+# Download a borders shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "country_borders.shp"
+isfile(shapefile_name) || Downloads.download(shapefile_url, shapefile_name)
+
+# Load the shapes for indonesia
+indonesia_border = Shapefile.Handle(shapefile_name).shapes[1]
+
+# Make an empty EPSG 4326 projected Raster of the area of Indonesia
+dimz = X(Projected(90.0:0.1:145; sampling=Intervals(), crs=EPSG(4326))),
+       Y(Projected(-15.0:0.1:10.9; sampling=Intervals(), crs=EPSG(4326)))
+
+A = zeros(UInt32, dimz; missingval=UInt32(0))
+
+# Rasterize each indonesian island with a different number. The islands are
+# rings of a multi-polygon, so we use \`GI.getring\` to get them all separately.
+islands = collect(GeoInterface.getring(indonesia_border))
+rasterize!(last, A, islands; fill=1:length(islands), progress=false)
+
+# And plot
+p = plot(Rasters.trim(A); color=:spring)
+plot!(p, indonesia_border; fillalpha=0, linewidth=0.7)
+
+savefig("build/indonesia_rasterized.png"); nothing
+
+# output

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',12))]),i("details",Es,[i("summary",null,[s[117]||(s[117]=i("a",{id:"Rasters.replace_missing-Tuple{Any}",href:"#Rasters.replace_missing-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.replace_missing")],-1)),s[118]||(s[118]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[119]||(s[119]=t(`
julia
replace_missing(a::AbstractRaster, newmissingval)
+replace_missing(a::AbstractRasterStack, newmissingval)

Replace missing values in the array or stack with a new missing value, also updating the missingval field/s.

Keywords

Example

julia
using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{Climate}, :prec; month=1) |> replace_missing
+missingval(A)
+# output
+missing

source

`,7))]),i("details",us,[i("summary",null,[s[120]||(s[120]=i("a",{id:"Rasters.reproject-NTuple{4, Any}",href:"#Rasters.reproject-NTuple{4, Any}"},[i("span",{class:"jlbinding"},"Rasters.reproject")],-1)),s[121]||(s[121]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[122]||(s[122]=t('
julia
reproject(source::GeoFormat, target::GeoFormat, dim::Dimension, val)

reproject uses ArchGDAL.reproject, but implemented for a reprojecting a value array of values, a single dimension at a time.

source

',3))]),i("details",ms,[i("summary",null,[s[123]||(s[123]=i("a",{id:"Rasters.reproject-Tuple{Any}",href:"#Rasters.reproject-Tuple{Any}"},[i("span",{class:"jlbinding"},"Rasters.reproject")],-1)),s[124]||(s[124]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[125]||(s[125]=t('
julia
reproject(obj; crs)

Reproject the lookups of obj to a different crs.

This is a lossless operation for the raster data, as only the lookup values change. This is only possible when the axes of source and destination projections are aligned: the change is usually from a Regular and an Irregular lookup spans.

For converting between projections that are rotated, skewed or warped in any way, use resample.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are silently returned without modification.

Arguments

source

',8))]),i("details",bs,[i("summary",null,[s[126]||(s[126]=i("a",{id:"Rasters.resample-Tuple",href:"#Rasters.resample-Tuple"},[i("span",{class:"jlbinding"},"Rasters.resample")],-1)),s[127]||(s[127]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[128]||(s[128]=t(`
julia
resample(x; kw...)
+resample(xs...; to=first(xs), kw...)

resample uses warp (which uses GDALs gdalwarp) to resample a Raster or RasterStack to a new resolution and optionally new crs, or to snap to the bounds, resolution and crs of the object to.

Dimensions without an AbstractProjected lookup (such as a Ti dimension) are iteratively resampled with GDAL and joined back into a single array.

If projections can be converted for each axis independently, it may be faster and more accurate to use reproject.

Run using ArchGDAL to make this method available.

Arguments

Keywords

Note:

Example

Resample a WorldClim layer to match an EarthEnv layer:

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+B = Raster(EarthEnv{HabitatHeterogeneity}, :evenness)
+
+a = plot(A)
+b = plot(resample(A; to=B))
+
+savefig(a, "build/resample_example_before.png");
+savefig(b, "build/resample_example_after.png"); nothing
+
+# output

Before resample:

After resample:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',20))]),i("details",Fs,[i("summary",null,[s[129]||(s[129]=i("a",{id:"Rasters.setcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.setcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.setcrs")],-1)),s[130]||(s[130]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[131]||(s[131]=t('
julia
setcrs(x, crs)

Set the crs of a Raster, RasterStack, Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

',3))]),i("details",fs,[i("summary",null,[s[132]||(s[132]=i("a",{id:"Rasters.setmappedcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.setmappedcrs-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.setmappedcrs")],-1)),s[133]||(s[133]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[134]||(s[134]=t('
julia
setmappedcrs(x, crs)

Set the mapped crs of a Raster, a RasterStack, a Tuple of Dimension, or a Dimension. The crs is expected to be a GeoFormatTypes.jl CRS or Mixed GeoFormat type

source

',3))]),i("details",Cs,[i("summary",null,[s[135]||(s[135]=i("a",{id:"Rasters.slice-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}",href:"#Rasters.slice-Tuple{Union{AbstractRaster, AbstractRasterStack}, Any}"},[i("span",{class:"jlbinding"},"Rasters.slice")],-1)),s[136]||(s[136]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[137]||(s[137]=t('
julia
slice(A::Union{AbstractRaster,AbstractRasterStack,AbstracRasterSeries}, dims) => RasterSeries

Slice views along some dimension/s to obtain a RasterSeries of the slices.

For a Raster or RasterStack this will return a RasterSeries of Raster or RasterStack that are slices along the specified dimensions.

For a RasterSeries, the output is another series where the child objects are sliced and the series dimensions index is now of the child dimensions combined. slice on a RasterSeries with no dimensions will slice along the dimensions shared by both the series and child object.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',6))]),i("details",As,[i("summary",null,[s[138]||(s[138]=i("a",{id:"Rasters.trim-Tuple{Union{AbstractRaster, AbstractRasterStack}}",href:"#Rasters.trim-Tuple{Union{AbstractRaster, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Rasters.trim")],-1)),s[139]||(s[139]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[140]||(s[140]=t(`
julia
trim(x; dims::Tuple, pad::Int)

Trim missingval(x) from x for axes in dims, returning a view of x.

Arguments

Keywords

As trim is lazy, filename and suffix keywords are not used.

Example

Create trimmed layers of Australian habitat heterogeneity.

julia
using Rasters, RasterDataSources, Plots
+layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+
+# Roughly cut out australia
+ausbounds = X(100 .. 160), Y(-50 .. -10)
+aus = st[ausbounds...]
+a = plot(aus)
+
+# Trim missing values and plot
+b = plot(trim(aus))
+
+savefig(a, "build/trim_example_before.png");
+savefig(b, "build/trim_example_after.png"); nothing
+
+# output

Before trim:

After trim:

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',16))]),i("details",Rs,[i("summary",null,[s[141]||(s[141]=i("a",{id:"Rasters.warp-Tuple",href:"#Rasters.warp-Tuple"},[i("span",{class:"jlbinding"},"Rasters.warp")],-1)),s[142]||(s[142]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[143]||(s[143]=t(`
julia
warp(A::AbstractRaster, flags::Dict; kw...)

Gives access to the GDALs gdalwarp method given a Dict of flag => value arguments that can be converted to strings, or vectors where multiple space-separated arguments are required.

Arrays with additional dimensions not handled by GDAL (other than X, Y, Band) are sliced, warped, and then combined to match the original array dimensions. These slices will not be written to disk and loaded lazily at this stage - you will need to do that manually if required.

See the gdalwarp docs for a list of arguments.

Run using ArchGDAL to make this method available.

Keywords

Any additional keywords are passed to ArchGDAL.Dataset.

Example

This simply resamples the array with the :tr (output file resolution) and :r flags, giving us a pixelated version:

julia
using Rasters, RasterDataSources, Plots
+A = Raster(WorldClim{Climate}, :prec; month=1)
+a = plot(A)
+
+flags = Dict(
+    :tr => [2.0, 2.0],
+    :r => :near,
+)
+b = plot(warp(A, flags))
+
+savefig(a, "build/warp_example_before.png");
+savefig(b, "build/warp_example_after.png"); nothing
+
+# output

Before warp:

After warp:

In practise, prefer resample for this. But warp may be more flexible.

WARNING: This feature is experimental. It may change in future versions, and may not be 100% reliable in all cases. Please file github issues if problems occur.

source

',18))]),i("details",vs,[i("summary",null,[s[144]||(s[144]=i("a",{id:"Rasters.zonal-Tuple{Any, Union{AbstractRaster, AbstractRasterStack}}",href:"#Rasters.zonal-Tuple{Any, Union{AbstractRaster, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Rasters.zonal")],-1)),s[145]||(s[145]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[146]||(s[146]=t(`
julia
zonal(f, x::Union{Raster,RasterStack}; of, kw...)

Calculate zonal statistics for the the zone of a Raster or RasterStack covered by the of object/s.

Arguments

Keywords

These can be used when of is or contains (a) GeoInterface.jl compatible object(s):

Example

julia
using Rasters, RasterDataSources, ArchGDAL, Shapefile, DataFrames, Downloads, Statistics, Dates
+
+# Download a borders shapefile
+ne_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries"
+shp_url, dbf_url  = ne_url * ".shp", ne_url * ".dbf"
+shp_name, dbf_name = "country_borders.shp", "country_borders.dbf"
+isfile(shp_name) || Downloads.download(shp_url, shp_name)
+isfile(dbf_url) || Downloads.download(dbf_url, dbf_name)
+
+# Download and read a raster stack from WorldClim
+st = RasterStack(WorldClim{Climate}; month=Jan, lazy=false)
+
+# Load the shapes for world countries
+countries = Shapefile.Table(shp_name) |> DataFrame
+
+# Calculate the january mean of all climate variables for all countries
+january_stats = zonal(mean, st; of=countries, boundary=:touches, progress=false) |> DataFrame
+
+# Add the country name column (natural earth has some string errors it seems)
+insertcols!(january_stats, 1, :country => first.(split.(countries.ADMIN, r"[^A-Za-z ]")))
+
+# output
+258×8 DataFrame
+ Row │ country                       tmin       tmax       tavg       prec     
+     │ SubStrin                     Float32    Float32    Float32    Float64  
+─────┼──────────────────────────────────────────────────────────────────────────
+   1 │ Indonesia                      21.5447    29.1864    25.3656   271.063
+   2 │ Malaysia                       21.3087    28.4291    24.8688   273.381
+   3 │ Chile                           7.24534   17.9263    12.5858    78.1287
+   4 │ Bolivia                        17.2065    27.7454    22.4759   192.542
+   5 │ Peru                           15.0273    25.5504    20.2888   180.007
+   6 │ Argentina                      13.6751    27.6715    20.6732    67.1837
+   7 │ Dhekelia Sovereign Base Area    5.87126   15.8991    10.8868    76.25
+   8 │ Cyprus                          5.65921   14.6665    10.1622    97.4474
+
+ 252 │ Spratly Islands                25.0       29.2       27.05      70.5
+ 253 │ Clipperton Island              21.5       33.2727    27.4        6.0
+ 254 │ Macao S                        11.6694    17.7288    14.6988    28.0
+ 255 │ Ashmore and Cartier Islands   NaN        NaN        NaN        NaN
+ 256 │ Bajo Nuevo Bank               NaN        NaN        NaN        NaN
+ 257 │ Serranilla Bank               NaN        NaN        NaN        NaN
+ 258 │ Scarborough Reef              NaN        NaN        NaN        NaN
+                                                  3 columns and 243 rows omitted

source

`,11))]),s[193]||(s[193]=i("h2",{id:"Reference-Internal-functions",tabindex:"-1"},[e("Reference - Internal functions "),i("a",{class:"header-anchor",href:"#Reference-Internal-functions","aria-label":'Permalink to "Reference - Internal functions {#Reference-Internal-functions}"'},"​")],-1)),i("details",Ds,[i("summary",null,[s[147]||(s[147]=i("a",{id:"Rasters.AbstractProjected",href:"#Rasters.AbstractProjected"},[i("span",{class:"jlbinding"},"Rasters.AbstractProjected")],-1)),s[148]||(s[148]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[149]||(s[149]=t('
julia
AbstractProjected <: AbstractSampled

Abstract supertype for projected index lookups.

source

',3))]),i("details",js,[i("summary",null,[s[150]||(s[150]=i("a",{id:"Rasters.FileArray",href:"#Rasters.FileArray"},[i("span",{class:"jlbinding"},"Rasters.FileArray")],-1)),s[151]||(s[151]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[152]||(s[152]=t('
julia
FileArray{S} <: DiskArrays.AbstractDiskArray

Filearray is a DiskArrays.jl AbstractDiskArray. Instead of holding an open object, it just holds a filename string that is opened lazily when it needs to be read.

source

',3))]),i("details",Bs,[i("summary",null,[s[153]||(s[153]=i("a",{id:"Rasters.FileStack",href:"#Rasters.FileStack"},[i("span",{class:"jlbinding"},"Rasters.FileStack")],-1)),s[154]||(s[154]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[155]||(s[155]=t(`
julia
FileStack{S,Na}
+
+FileStack{S,Na}(filename, types, sizes, eachchunk, haschunks, write)

A wrapper object that holds file pointer and size/chunking metadata for a multi-layered stack stored in a single file, typically netcdf or hdf5.

S is a backend type like NCDsource, and Na is a tuple of Symbol keys.

source

`,4))]),i("details",ws,[i("summary",null,[s[156]||(s[156]=i("a",{id:"Rasters.OpenStack",href:"#Rasters.OpenStack"},[i("span",{class:"jlbinding"},"Rasters.OpenStack")],-1)),s[157]||(s[157]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[158]||(s[158]=t(`
julia
OpenStack{X,K}
+
+OpenStack{X,K}(dataset)

A wrapper for any stack-like opened dataset that can be indexed with Symbol keys to retrieve AbstractArray layers.

OpenStack is usually hidden from users, wrapped in a regular RasterStack passed as the function argument in open(stack) when the stack is contained in a single file.

X is a backend type like NCDsource, and K is a tuple of Symbol keys.

source

`,5))]),i("details",xs,[i("summary",null,[s[159]||(s[159]=i("a",{id:"Rasters.RasterDiskArray",href:"#Rasters.RasterDiskArray"},[i("span",{class:"jlbinding"},"Rasters.RasterDiskArray")],-1)),s[160]||(s[160]=e()),n(a,{type:"info",class:"jlObjectType jlType",text:"Type"})]),s[161]||(s[161]=t('
julia
RasterDiskArray <: DiskArrays.AbstractDiskArray

A basic DiskArrays.jl wrapper for objects that don't have one defined yet. When we open a FileArray it is replaced with a RasterDiskArray.

source

',3))]),i("details",Ts,[i("summary",null,[s[162]||(s[162]=i("a",{id:"Base.open-Tuple{Function, AbstractRaster}",href:"#Base.open-Tuple{Function, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.open")],-1)),s[163]||(s[163]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[164]||(s[164]=t(`
julia
open(f, A::AbstractRaster; write=false)

open is used to open any lazy=true AbstractRaster and do multiple operations on it in a safe way. The write keyword opens the file in write lookup so that it can be altered on disk using e.g. a broadcast.

f is a method that accepts a single argument - an Raster object which is just an AbstractRaster that holds an open disk-based object. Often it will be a do block:

lazy=false (in-memory) rasters will ignore open and pass themselves to f.

julia
# A is an \`Raster\` wrapping the opened disk-based object.
+open(Raster(filepath); write=true) do A
+    mask!(A; with=maskfile)
+    A[I...] .*= 2
+    # ...  other things you need to do with the open file
+end

By using a do block to open files we ensure they are always closed again after we finish working with them.

source

`,7))]),i("details",Ss,[i("summary",null,[s[165]||(s[165]=i("a",{id:"Base.read!-Tuple{AbstractRaster, AbstractArray}",href:"#Base.read!-Tuple{AbstractRaster, AbstractArray}"},[i("span",{class:"jlbinding"},"Base.read!")],-1)),s[166]||(s[166]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[167]||(s[167]=t(`
julia
read!(src::Union{AbstractString,AbstractRaster}, dst::AbstractRaster)
+read!(src::Union{AbstractString,AbstractRasterStack}, dst::AbstractRasterStack)
+read!(scr::AbstractRasterSeries, dst::AbstractRasterSeries)

read! will copy the data from src to the object dst.

src can be an object or a file-path String.

source

`,4))]),i("details",qs,[i("summary",null,[s[168]||(s[168]=i("a",{id:"Base.read-Tuple{Union{AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}",href:"#Base.read-Tuple{Union{AbstractRaster, AbstractRasterSeries, AbstractRasterStack}}"},[i("span",{class:"jlbinding"},"Base.read")],-1)),s[169]||(s[169]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[170]||(s[170]=t(`
julia
read(A::AbstractRaster)
+read(A::AbstractRasterStack)
+read(A::AbstractRasterSeries)

read will move a Rasters.jl object completely to memory.

Keywords

source

`,5))]),i("details",Ls,[i("summary",null,[s[171]||(s[171]=i("a",{id:"Base.skipmissing-Tuple{Raster}",href:"#Base.skipmissing-Tuple{Raster}"},[i("span",{class:"jlbinding"},"Base.skipmissing")],-1)),s[172]||(s[172]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[173]||(s[173]=t('
julia
skipmissing(itr::Raster)

Returns an iterable over the elements in a Raster object, skipping any values equal to either the missingval or missing.

source

',3))]),i("details",Is,[i("summary",null,[s[174]||(s[174]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRasterSeries}",href:"#Base.write-Tuple{AbstractString, AbstractRasterSeries}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[175]||(s[175]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[176]||(s[176]=t('
julia
Base.write(filepath::AbstractString, s::AbstractRasterSeries; kw...)

Write any AbstractRasterSeries to multiple files, guessing the backend from the file extension.

The lookup values of the series will be appended to the filepath (before the extension), separated by underscores.

All keywords are passed through to these Raster and RasterStack methods.

Keywords

source

',7))]),i("details",zs,[i("summary",null,[s[177]||(s[177]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRasterStack}",href:"#Base.write-Tuple{AbstractString, AbstractRasterStack}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[178]||(s[178]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[179]||(s[179]=t('
julia
Base.write(filename::AbstractString, s::AbstractRasterStack; kw...)

Write any AbstractRasterStack to one or multiple files, depending on the backend. Backend is guessed from the filename extension or forced with the source keyword.

If the source can't be saved as a stack-like object, individual array layers will be saved.

Keywords

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

source

',17))]),i("details",Ps,[i("summary",null,[s[180]||(s[180]=i("a",{id:"Base.write-Tuple{AbstractString, AbstractRaster}",href:"#Base.write-Tuple{AbstractString, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[181]||(s[181]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[182]||(s[182]=t('
julia
Base.write(filename::AbstractString, A::AbstractRaster; [source], kw...)

Write an AbstractRaster to file, guessing the backend from the file extension or using the source keyword.

Keywords

Other keyword arguments are passed to the write method for the backend.

NetCDF keywords

GDAL Keywords

Valid options for each specific driver can be found at: https://gdal.org/drivers/raster/index.html

Source comments

R grd/grid files

Write a Raster to a .grd file with a .gri header file. Returns the base of filename with a .grd extension.

GDAL (tiff, and everything else)

Used if you write a Raster with a filename extension that no other backend can write. GDAL is the fallback, and writes a lot of file types, but is not guaranteed to work.

Returns filename.

source

',17))]),i("details",Gs,[i("summary",null,[s[183]||(s[183]=i("a",{id:"Base.write-Tuple{String, Rasters.GRDsource, AbstractRaster}",href:"#Base.write-Tuple{String, Rasters.GRDsource, AbstractRaster}"},[i("span",{class:"jlbinding"},"Base.write")],-1)),s[184]||(s[184]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[185]||(s[185]=t('
julia
Base.write(filename::AbstractString, ::Type{GRDsource}, s::AbstractRaster; kw...)

Write a Raster to a .grd file with a .gri header file.

This method is called automatically if you write a Raster with a .grd or .gri extension.

Keywords

If this method is called directly the extension of filename will be ignored.

Returns the base of filename with a .grd extension.

source

',8))]),i("details",Ns,[i("summary",null,[s[186]||(s[186]=i("a",{id:"Rasters.checkmem!-Tuple{Bool}",href:"#Rasters.checkmem!-Tuple{Bool}"},[i("span",{class:"jlbinding"},"Rasters.checkmem!")],-1)),s[187]||(s[187]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[188]||(s[188]=t('
julia
checkmem!(x::Bool)

Set checkmem to true or false.

In some architectures memory reporting may be wrong and you may wish to disable memory checks.

This setting can be overridden with the checkmem keyword, where applicable.

source

',5))]),i("details",Os,[i("summary",null,[s[189]||(s[189]=i("a",{id:"Rasters.rplot-Tuple",href:"#Rasters.rplot-Tuple"},[i("span",{class:"jlbinding"},"Rasters.rplot")],-1)),s[190]||(s[190]=e()),n(a,{type:"info",class:"jlObjectType jlMethod",text:"Method"})]),s[191]||(s[191]=t('
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

source

',5))])])}const Hs=l(x,[["render",Ms]]);export{Ys as __pageData,Hs as default}; diff --git a/previews/PR807/assets/app.hIvj5Ijy.js b/previews/PR807/assets/app.hIvj5Ijy.js new file mode 100644 index 00000000..2eab900d --- /dev/null +++ b/previews/PR807/assets/app.hIvj5Ijy.js @@ -0,0 +1 @@ +import{R as p}from"./chunks/theme.CJjspAw-.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,a4 as S}from"./chunks/framework.Cl7EIXwS.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/PR807/assets/argentina_crop_example.DlKBBk5m.png b/previews/PR807/assets/argentina_crop_example.DlKBBk5m.png new file mode 100644 index 00000000..26a5ae55 Binary files /dev/null and b/previews/PR807/assets/argentina_crop_example.DlKBBk5m.png differ diff --git a/previews/PR807/assets/array_operations.md.CRu0fcQR.js b/previews/PR807/assets/array_operations.md.CRu0fcQR.js new file mode 100644 index 00000000..8e20eedf --- /dev/null +++ b/previews/PR807/assets/array_operations.md.CRu0fcQR.js @@ -0,0 +1,141 @@ +import{_ as a,c as n,a5 as t,o as e}from"./chunks/framework.Cl7EIXwS.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"array_operations.md","filePath":"array_operations.md","lastUpdated":null}'),i={name:"array_operations.md"};function p(l,s,o,u,r,c){return e(),n("div",null,s[0]||(s[0]=[t(`

Most base methods work as for regular julia Arrays, such as reverse and rotations like rotl90. Base, statistics and linear algebra methods like mean that take a dims argument can also use the dimension name.

Mean over the time dimension:

julia
using Rasters, Statistics, RasterDataSources
+
+A = Raster(WorldClim{BioClim}, 5)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

Then we do the mean over the X dimension

julia
mean(A, dims=X) # Ti if time were available would also be possible
╭───────────────────────────────╮
+│ 1×1080 Raster{Float32,2} bio5 │
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} -180.0:360.0:-180.0 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 180.0), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →   89.8333   89.6667   89.5   89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0  -Inf      -Inf      -Inf   -Inf         -23.0768  -22.9373  -22.0094

broadcast works lazily from disk when lazy=true, and is only applied when data is directly indexed. Adding a dot to any function will use broadcast over a Raster just like an Array.

Broadcasting

For a disk-based array A, this will only be applied when indexing occurs or when we read the array.

julia
A .*= 2
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →     89.8333   89.6667   89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -Inf      -Inf      -Inf      -30.798   -27.61    -28.092
+    ⋮                                 ⋱                        ⋮
+  179.833  -Inf      -Inf      -Inf   …  -34.2955  -30.8485  -31.402

To broadcast directly to disk, we need to open the file in write mode:

julia
open(Raster(filename); write=true) do O
+   O .*= 2
+end

To broadcast over a RasterStack use map, which applies a function to the raster layers of the stack.

julia
newstack = map(stack) do raster
+   raster .* 2
+end

Modifying object properties

rebuild can be used to modify the fields of an object, generating a new object (but possibly holding the same arrays or files).

If you know that a file had an incorrectly specified missing value, you can do:

rebuild

julia
A = Raster(WorldClim{BioClim}, 5)
+rebuild(A; missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

(replace_missing will actually replace the current values).

Or if you need to change the name of the layer:

Then use rebuild as

julia
B = rebuild(A; name=:temperature)
+B.name
:temperature

replace_missing

julia
replace_missing(A, missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →       89.8333     89.6667     89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -9999.0     -9999.0     -9999.0     -15.399   -13.805   -14.046
+    ⋮                                       ⋱                        ⋮
+  179.833  -9999.0     -9999.0     -9999.0  …  -17.1478  -15.4243  -15.701

set

set can be used to modify the nested properties of an objects dimensions, that are more difficult to change with rebuild. set works on the principle that dimension properties can only be in one specific field, so we generally don't have to specify which one it is. set will also try to update anything affected by a change you make.

This will set the X axis to specify points, instead of intervals:

julia
using Rasters: Points
+set(A, X => Points)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Points,
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.83333333333331), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

We can also reassign dimensions, here X becomes Z:

julia
set(A, X => Z)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Z Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(Z = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

setcrs(A, crs) and setmappedcrs(A, crs) will set the crs value/s of an object to any GeoFormat from GeoFormatTypes.jl.

`,39)]))}const q=a(i,[["render",p]]);export{h as __pageData,q as default}; diff --git a/previews/PR807/assets/array_operations.md.CRu0fcQR.lean.js b/previews/PR807/assets/array_operations.md.CRu0fcQR.lean.js new file mode 100644 index 00000000..8e20eedf --- /dev/null +++ b/previews/PR807/assets/array_operations.md.CRu0fcQR.lean.js @@ -0,0 +1,141 @@ +import{_ as a,c as n,a5 as t,o as e}from"./chunks/framework.Cl7EIXwS.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"array_operations.md","filePath":"array_operations.md","lastUpdated":null}'),i={name:"array_operations.md"};function p(l,s,o,u,r,c){return e(),n("div",null,s[0]||(s[0]=[t(`

Most base methods work as for regular julia Arrays, such as reverse and rotations like rotl90. Base, statistics and linear algebra methods like mean that take a dims argument can also use the dimension name.

Mean over the time dimension:

julia
using Rasters, Statistics, RasterDataSources
+
+A = Raster(WorldClim{BioClim}, 5)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

Then we do the mean over the X dimension

julia
mean(A, dims=X) # Ti if time were available would also be possible
╭───────────────────────────────╮
+│ 1×1080 Raster{Float32,2} bio5 │
+├───────────────────────────────┴──────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} -180.0:360.0:-180.0 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 180.0), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →   89.8333   89.6667   89.5   89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0  -Inf      -Inf      -Inf   -Inf         -23.0768  -22.9373  -22.0094

broadcast works lazily from disk when lazy=true, and is only applied when data is directly indexed. Adding a dot to any function will use broadcast over a Raster just like an Array.

Broadcasting

For a disk-based array A, this will only be applied when indexing occurs or when we read the array.

julia
A .*= 2
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →     89.8333   89.6667   89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -Inf      -Inf      -Inf      -30.798   -27.61    -28.092
+    ⋮                                 ⋱                        ⋮
+  179.833  -Inf      -Inf      -Inf   …  -34.2955  -30.8485  -31.402

To broadcast directly to disk, we need to open the file in write mode:

julia
open(Raster(filename); write=true) do O
+   O .*= 2
+end

To broadcast over a RasterStack use map, which applies a function to the raster layers of the stack.

julia
newstack = map(stack) do raster
+   raster .* 2
+end

Modifying object properties

rebuild can be used to modify the fields of an object, generating a new object (but possibly holding the same arrays or files).

If you know that a file had an incorrectly specified missing value, you can do:

rebuild

julia
A = Raster(WorldClim{BioClim}, 5)
+rebuild(A; missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

(replace_missing will actually replace the current values).

Or if you need to change the name of the layer:

Then use rebuild as

julia
B = rebuild(A; name=:temperature)
+B.name
:temperature

replace_missing

julia
replace_missing(A, missingval=-9999)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -9999.0f0
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →       89.8333     89.6667     89.5  …  -89.6667  -89.8333  -90.0
+ -180.0    -9999.0     -9999.0     -9999.0     -15.399   -13.805   -14.046
+    ⋮                                       ⋱                        ⋮
+  179.833  -9999.0     -9999.0     -9999.0  …  -17.1478  -15.4243  -15.701

set

set can be used to modify the nested properties of an objects dimensions, that are more difficult to change with rebuild. set works on the principle that dimension properties can only be in one specific field, so we generally don't have to specify which one it is. set will also try to update anything affected by a change you make.

This will set the X axis to specify points, instead of intervals:

julia
using Rasters: Points
+set(A, X => Points)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Points,
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.83333333333331), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

We can also reassign dimensions, here X becomes Z:

julia
set(A, X => Z)
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ Z Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(Z = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701

setcrs(A, crs) and setmappedcrs(A, crs) will set the crs value/s of an object to any GeoFormat from GeoFormatTypes.jl.

`,39)]))}const q=a(i,[["render",p]]);export{h as __pageData,q as default}; diff --git a/previews/PR807/assets/aus_trim.B4Z7jnS4.png b/previews/PR807/assets/aus_trim.B4Z7jnS4.png new file mode 100644 index 00000000..af33b088 Binary files /dev/null and b/previews/PR807/assets/aus_trim.B4Z7jnS4.png differ diff --git a/previews/PR807/assets/boolmask_example.B6nOyO_A.png b/previews/PR807/assets/boolmask_example.B6nOyO_A.png new file mode 100644 index 00000000..06b9a04c Binary files /dev/null and b/previews/PR807/assets/boolmask_example.B6nOyO_A.png differ diff --git a/previews/PR807/assets/china_rasterized.kM95Jnlf.png b/previews/PR807/assets/china_rasterized.kM95Jnlf.png new file mode 100644 index 00000000..9af85a76 Binary files /dev/null and b/previews/PR807/assets/china_rasterized.kM95Jnlf.png differ diff --git a/previews/PR807/assets/chunks/@localSearchIndexroot.CCGZ83u0.js b/previews/PR807/assets/chunks/@localSearchIndexroot.CCGZ83u0.js new file mode 100644 index 00000000..28183d30 --- /dev/null +++ b/previews/PR807/assets/chunks/@localSearchIndexroot.CCGZ83u0.js @@ -0,0 +1 @@ +const e='{"documentCount":47,"nextId":47,"documentIds":{"0":"/Rasters.jl/previews/PR807/api#index","1":"/Rasters.jl/previews/PR807/api#Reference-Exported-functions","2":"/Rasters.jl/previews/PR807/api#Reference-Internal-functions","3":"/Rasters.jl/previews/PR807/array_operations#Mean-over-the-time-dimension:","4":"/Rasters.jl/previews/PR807/array_operations#broadcasting","5":"/Rasters.jl/previews/PR807/array_operations#Modifying-object-properties","6":"/Rasters.jl/previews/PR807/array_operations#rebuild","7":"/Rasters.jl/previews/PR807/array_operations#replace-missing","8":"/Rasters.jl/previews/PR807/array_operations#set","9":"/Rasters.jl/previews/PR807/data_sources#Data-sources","10":"/Rasters.jl/previews/PR807/data_sources#grd","11":"/Rasters.jl/previews/PR807/data_sources#netcdf","12":"/Rasters.jl/previews/PR807/data_sources#gdal","13":"/Rasters.jl/previews/PR807/data_sources#smap","14":"/Rasters.jl/previews/PR807/data_sources#Writing-file-formats-to-disk","15":"/Rasters.jl/previews/PR807/data_sources#RasterDataSources.jl-integration","16":"/Rasters.jl/previews/PR807/gbif_wflow#Load-GBIF","17":"/Rasters.jl/previews/PR807/gbif_wflow#Extract-coordinates","18":"/Rasters.jl/previews/PR807/gbif_wflow#Get-layer-/-Band","19":"/Rasters.jl/previews/PR807/get_started#Quick-start","20":"/Rasters.jl/previews/PR807/get_started#Install-the-package-by-typing:","21":"/Rasters.jl/previews/PR807/get_started#Getting-the-lookup-array-from-dimensions","22":"/Rasters.jl/previews/PR807/get_started#Select-by-index","23":"/Rasters.jl/previews/PR807/get_started#Select-by-value","24":"/Rasters.jl/previews/PR807/get_started#Subsetting-an-object","25":"/Rasters.jl/previews/PR807/#installation","26":"/Rasters.jl/previews/PR807/#Packages-extensions","27":"/Rasters.jl/previews/PR807/#Bugs-and-errors","28":"/Rasters.jl/previews/PR807/methods#Methods-that-change-the-resolution-or-extent-of-an-object","29":"/Rasters.jl/previews/PR807/methods#Methods-that-change-an-objects-values","30":"/Rasters.jl/previews/PR807/methods#Point,-polygon-and-table-operation","31":"/Rasters.jl/previews/PR807/methods#Methods-to-load,-write-and-modify-data-sources","32":"/Rasters.jl/previews/PR807/plot_makie#Plotting-in-Makie","33":"/Rasters.jl/previews/PR807/plot_makie#2-D-rasters-in-Makie","34":"/Rasters.jl/previews/PR807/plot_makie#3-D-rasters-in-Makie","35":"/Rasters.jl/previews/PR807/plot_makie#reset-theme","36":"/Rasters.jl/previews/PR807/plot_makie#Plotting-with-Observables,-animations","37":"/Rasters.jl/previews/PR807/plot_makie#Using-vanilla-Makie","38":"/Rasters.jl/previews/PR807/plotting#Plots,-simple","39":"/Rasters.jl/previews/PR807/plotting#Makie,-simple","40":"/Rasters.jl/previews/PR807/plotting#Loading-data","41":"/Rasters.jl/previews/PR807/plotting#Plot-a-contour-plot","42":"/Rasters.jl/previews/PR807/plotting#write-to-disk","43":"/Rasters.jl/previews/PR807/plotting#Polygon-masking,-mosaic-and-plot","44":"/Rasters.jl/previews/PR807/plotting#Download-the-shapefile","45":"/Rasters.jl/previews/PR807/plotting#Load-using-Shapefile.jl","46":"/Rasters.jl/previews/PR807/plotting#Plotting-with-Plots.jl"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[1,1,48],"1":[3,1,1509],"2":[3,1,499],"3":[6,1,169],"4":[1,1,157],"5":[3,1,33],"6":[1,3,139],"7":[2,3,114],"8":[1,3,184],"9":[2,1,24],"10":[1,2,30],"11":[1,2,69],"12":[1,2,37],"13":[1,2,67],"14":[5,2,53],"15":[3,2,60],"16":[2,1,90],"17":[2,1,73],"18":[3,1,141],"19":[2,1,1],"20":[6,2,135],"21":[6,2,21],"22":[3,2,107],"23":[3,2,158],"24":[3,2,118],"25":[1,1,4],"26":[2,1,100],"27":[3,1,163],"28":[10,1,70],"29":[6,1,47],"30":[5,1,19],"31":[8,1,34],"32":[3,1,37],"33":[5,1,137],"34":[5,1,84],"35":[2,1,4],"36":[4,2,174],"37":[3,2,165],"38":[2,1,125],"39":[2,1,20],"40":[2,1,235],"41":[4,2,10],"42":[3,2,59],"43":[5,1,38],"44":[3,1,28],"45":[4,3,144],"46":[4,3,208]},"averageFieldLength":[3.2127659574468086,1.5319148936170213,126.4042553191489],"storedFields":{"0":{"title":"Index","titles":[]},"1":{"title":"Reference - Exported functions","titles":[]},"2":{"title":"Reference - Internal functions","titles":[]},"3":{"title":"Mean over the time dimension:","titles":[]},"4":{"title":"Broadcasting","titles":[]},"5":{"title":"Modifying object properties","titles":[]},"6":{"title":"rebuild","titles":["Modifying object properties"]},"7":{"title":"replace_missing","titles":["Modifying object properties"]},"8":{"title":"set","titles":["Modifying object properties"]},"9":{"title":"Data sources","titles":[]},"10":{"title":"GRD","titles":["Data sources"]},"11":{"title":"NetCDF","titles":["Data sources"]},"12":{"title":"GDAL","titles":["Data sources"]},"13":{"title":"SMAP","titles":["Data sources"]},"14":{"title":"Writing file formats to disk","titles":["Data sources"]},"15":{"title":"RasterDataSources.jl integration","titles":["Data sources"]},"16":{"title":"Load GBIF","titles":[]},"17":{"title":"Extract coordinates","titles":[]},"18":{"title":"Get layer / Band","titles":[]},"19":{"title":"Quick start","titles":[]},"20":{"title":"Install the package by typing:","titles":["Quick start"]},"21":{"title":"Getting the lookup array from dimensions","titles":["Quick start"]},"22":{"title":"Select by index","titles":["Quick start"]},"23":{"title":"Select by value","titles":["Quick start"]},"24":{"title":"Subsetting an object","titles":["Quick start"]},"25":{"title":"Installation","titles":[]},"26":{"title":"Packages extensions","titles":[]},"27":{"title":"Bugs and errors","titles":[]},"28":{"title":"Methods that change the resolution or extent of an object","titles":[]},"29":{"title":"Methods that change an objects values","titles":[]},"30":{"title":"Point, polygon and table operation","titles":[]},"31":{"title":"Methods to load, write and modify data sources","titles":[]},"32":{"title":"Plotting in Makie","titles":[]},"33":{"title":"2-D rasters in Makie","titles":[]},"34":{"title":"3-D rasters in Makie","titles":[]},"35":{"title":"reset theme","titles":[]},"36":{"title":"Plotting with Observables, animations","titles":["reset theme"]},"37":{"title":"Using vanilla Makie","titles":["reset theme"]},"38":{"title":"Plots, simple","titles":[]},"39":{"title":"Makie, simple","titles":[]},"40":{"title":"Loading data","titles":[]},"41":{"title":"Plot a contour plot","titles":["Loading data"]},"42":{"title":"write to disk","titles":["Loading data"]},"43":{"title":"Polygon masking, mosaic and plot","titles":[]},"44":{"title":"Download the shapefile","titles":[]},"45":{"title":"Load using Shapefile.jl","titles":["Download the shapefile"]},"46":{"title":"Plotting with Plots.jl","titles":["Download the shapefile"]}},"dirtCount":0,"index":[["↗",{"2":{"20":1,"22":1,"40":2}}],["├─────────────────────┴──────────────────────────────────────────────────",{"2":{"37":1,"46":1}}],["├───────────────────────┴────────────────────────────────────────────────",{"2":{"45":1}}],["├───────────────────────┴───────────────────────────────────────────────────",{"2":{"1":1}}],["├───────────────────────┴─────────────────────────────",{"2":{"22":2,"23":1}}],["├──────────────────────────┴─────────────────────────────────────────────",{"2":{"20":1,"22":1}}],["├──────────────────────────┼─────────┼─────────┼─────────┼──────────┼───────────",{"2":{"16":1}}],["├───────────────────────────────┴────────────────────────────────────────",{"2":{"3":1}}],["├─────────────────────────────────────────────────┴──────────────────────",{"2":{"40":1}}],["├──────────────────────────────────────────────────┴─────────────────────",{"2":{"40":1}}],["├───────────────────────────────────────────────────",{"2":{"22":2,"23":1}}],["├──────────────────────────────────────────────────────────────────────",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":2,"20":1,"22":1,"33":1,"37":2,"40":2,"45":4,"46":2}}],["├─────────────────────────────────────────────────────────────────────────",{"2":{"1":1}}],["├────────────────────────────────────────────────────────────────────",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"40":2}}],["├──────────────────────────────────┴─────────────────────────────────────",{"2":{"3":1,"4":1,"6":1,"7":1,"8":2,"33":1}}],["├────────────────────┴───────────────────────────────────────────────────",{"2":{"18":1,"45":1}}],["╭─────────────────────╮",{"2":{"37":1,"46":1}}],["╭──────────────────────────╮",{"2":{"20":1,"22":1}}],["╭─────────────────────────────────────────────────╮",{"2":{"40":1}}],["╭──────────────────────────────────────────────────╮",{"2":{"40":1}}],["╭──────────────────────────────────╮",{"2":{"3":1,"4":1,"6":1,"7":1,"8":2,"33":1}}],["╭───────────────────────────────╮",{"2":{"3":1}}],["╭───────────────────────╮",{"2":{"1":1,"22":2,"23":1,"45":1}}],["╭────────────────────╮",{"2":{"18":1,"45":1}}],["└───────────────────────────────────────────────────────────┘",{"2":{"22":2,"23":1}}],["└──────────────────────────────────────────────────────────────────────────────┘",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"20":1,"22":1,"33":1,"37":1,"40":2,"45":2,"46":1}}],["└─────────────────────────────────────────────────────────────────────────────────┘",{"2":{"1":1}}],["└──────────────────────────┴─────────┴─────────┴─────────┴──────────┴───────────",{"2":{"16":1}}],["┌──────────────────────────┬─────────┬─────────┬─────────┬──────────┬───────────",{"2":{"16":1}}],["⋱",{"2":{"1":1,"3":1,"4":1,"6":1,"7":1,"8":2,"16":1,"33":1,"40":2}}],["⋮",{"2":{"1":6,"3":2,"4":2,"6":2,"7":2,"8":4,"16":6,"17":1,"33":2,"40":2}}],["─────┼──────────────────────────────────────────────────────────────────────────",{"2":{"1":1}}],["⋯",{"2":{"1":6,"16":17}}],["^a",{"2":{"1":1}}],["quickly",{"2":{"27":1,"38":1}}],["quick",{"0":{"19":1},"1":{"20":1,"21":1,"22":1,"23":1,"24":1}}],["quot",{"2":{"2":18,"11":4,"12":4,"13":4,"14":2,"36":2}}],["quartile",{"2":{"1":4}}],["quadratic",{"2":{"1":1}}],["quality",{"2":{"1":1,"38":1}}],["q3",{"2":{"1":1}}],["q1",{"2":{"1":1}}],["+",{"2":{"1":2}}],["`stack`",{"2":{"36":1}}],["`raster`",{"2":{"2":1}}],["`gi",{"2":{"1":1}}],["`missingval",{"2":{"1":1}}],["`missing`",{"2":{"1":1}}],["`vector`",{"2":{"1":1}}],["`collect`",{"2":{"1":1}}],["`extract`",{"2":{"1":1}}],["z",{"2":{"1":1,"2":1,"8":4,"11":1,"23":1,"36":1,"40":1,"42":1}}],["za",{"2":{"1":1}}],["zone",{"2":{"1":1}}],["zonal",{"2":{"0":1,"1":5,"30":2}}],["zeros",{"2":{"1":1}}],["zealand",{"2":{"1":1}}],["55",{"2":{"46":1}}],["5504",{"2":{"1":1}}],["53",{"2":{"45":3}}],["533883",{"2":{"20":1,"22":3,"23":1}}],["534878",{"2":{"20":1,"22":3,"23":1}}],["516819",{"2":{"20":1,"22":3,"23":1}}],["588274",{"2":{"20":1,"22":3,"23":1}}],["5858",{"2":{"1":1}}],["54",{"2":{"45":1}}],["54166666666667",{"2":{"37":2}}],["54166666666666",{"2":{"37":1}}],["542",{"2":{"1":1}}],["5447",{"2":{"1":1}}],["544561f0",{"2":{"1":1}}],["524924",{"2":{"17":1}}],["5249",{"2":{"16":1}}],["52",{"2":{"1":1,"46":2}}],["57",{"2":{"1":1}}],["5",{"2":{"1":8,"3":5,"4":2,"6":3,"7":2,"8":4,"18":2,"24":1,"33":3,"37":2,"38":1,"39":1,"40":8,"45":1}}],["504673",{"2":{"17":1}}],["5047",{"2":{"16":1}}],["50",{"2":{"1":7,"24":1,"37":1}}],[">",{"2":{"1":1,"18":1}}],[">=",{"2":{"1":2}}],["98",{"2":{"45":1}}],["98×102",{"2":{"45":5}}],["957178",{"2":{"20":1,"22":3,"23":1}}],["923752",{"2":{"20":1,"22":3,"23":1}}],["924799",{"2":{"20":1,"22":3,"23":1}}],["9263",{"2":{"1":1}}],["96572",{"2":{"20":1,"22":3,"23":1}}],["934186",{"2":{"20":1,"22":3,"23":1}}],["935687",{"2":{"17":1}}],["9357",{"2":{"16":1}}],["9373",{"2":{"3":1}}],["99999999999999",{"2":{"46":2}}],["99999999999997",{"2":{"3":1,"4":1,"6":1,"7":1,"8":1,"18":1,"33":1,"45":1}}],["9999",{"2":{"6":2,"7":8}}],["9122",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["97",{"2":{"1":3}}],["9",{"2":{"1":2,"2":2,"26":1,"40":2,"45":2}}],["909224",{"2":{"20":1,"22":3,"23":1}}],["90",{"2":{"1":5,"3":8,"4":4,"6":4,"7":4,"8":8,"33":4,"40":3,"45":3}}],["72",{"2":{"46":2}}],["7288",{"2":{"1":1}}],["73",{"2":{"46":1}}],["71",{"2":{"45":1}}],["75",{"2":{"36":1,"37":1}}],["75708",{"2":{"20":1,"22":3,"23":1}}],["755033",{"2":{"20":1,"22":3,"23":1}}],["756557",{"2":{"20":1,"22":3,"23":1}}],["79",{"2":{"40":2}}],["791698",{"2":{"20":1,"22":3,"23":1}}],["798",{"2":{"4":1}}],["7983f0",{"2":{"1":2}}],["76",{"2":{"1":1}}],["7454",{"2":{"1":1}}],["78",{"2":{"1":1,"16":1,"40":2}}],["775f0",{"2":{"1":1}}],["7",{"2":{"1":5,"18":1}}],["701",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["7030",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["708290",{"2":{"1":4}}],["70",{"2":{"1":2,"45":2}}],["6×6×10",{"2":{"22":1}}],["6×6×13",{"2":{"20":1}}],["6×6",{"2":{"22":2,"23":1}}],["624422",{"2":{"20":1,"22":3,"23":1}}],["697933",{"2":{"20":1,"22":3,"23":1}}],["6988",{"2":{"1":1}}],["61",{"2":{"4":1,"24":1}}],["66666666666664",{"2":{"46":1}}],["666666666666643",{"2":{"45":1}}],["66666666666666",{"2":{"46":1}}],["66666666666667",{"2":{"45":3}}],["6667",{"2":{"3":4,"4":2,"6":2,"7":2,"8":4,"33":2}}],["6665",{"2":{"1":1}}],["6694",{"2":{"1":1}}],["65921",{"2":{"1":1}}],["659454f0",{"2":{"1":1}}],["67",{"2":{"1":1}}],["6732",{"2":{"1":1}}],["6715",{"2":{"1":1}}],["6751",{"2":{"1":1}}],["6326",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["6378137",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["6371008",{"2":{"1":1}}],["638462f0",{"2":{"1":2}}],["6",{"2":{"1":4,"16":1,"46":1}}],["600",{"2":{"37":2}}],["60",{"2":{"1":3,"40":1}}],["┤",{"2":{"1":1,"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"20":1,"22":3,"23":1,"33":2,"37":2,"40":4,"45":4,"46":2}}],["→",{"2":{"1":2,"3":4,"4":2,"6":2,"7":2,"8":4,"18":1,"20":2,"22":6,"23":2,"33":2,"37":1,"40":2,"45":2,"46":1}}],["↓",{"2":{"1":2,"3":4,"4":2,"6":2,"7":2,"8":4,"18":1,"20":2,"22":6,"23":2,"33":2,"37":1,"40":2,"45":2,"46":1}}],["┐",{"2":{"1":1,"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"20":1,"22":3,"23":1,"33":1,"37":1,"40":2,"45":2,"46":1}}],["48",{"2":{"24":1}}],["480",{"2":{"1":1}}],["49999999999998",{"2":{"46":1}}],["499999999999972",{"2":{"45":2}}],["492677",{"2":{"20":1,"22":3,"23":1}}],["490719",{"2":{"17":1}}],["43",{"2":{"24":1,"37":2}}],["437709",{"2":{"17":1}}],["432552",{"2":{"17":2}}],["4326",{"2":{"1":14,"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"23":1,"33":1,"37":1,"40":4,"45":2,"46":1}}],["430986",{"2":{"17":1}}],["431684",{"2":{"17":1}}],["4317",{"2":{"16":1}}],["433349",{"2":{"17":1}}],["4333",{"2":{"16":1}}],["4243",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["4291",{"2":{"1":1}}],["4f38",{"2":{"3":10,"4":1,"6":8,"8":18,"18":1,"33":9,"45":6,"46":3}}],["4759",{"2":{"1":1}}],["453071",{"2":{"20":1,"22":3,"23":1}}],["45",{"2":{"1":4,"40":1}}],["448374",{"2":{"17":1}}],["4474",{"2":{"1":1}}],["441",{"2":{"1":2}}],["446",{"2":{"1":1}}],["418261",{"2":{"17":1}}],["41",{"2":{"1":2}}],["4",{"2":{"1":3,"2":2,"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":2}}],["400",{"2":{"41":1}}],["400058",{"2":{"17":1}}],["4001",{"2":{"16":1}}],["402",{"2":{"4":1}}],["40",{"2":{"1":8,"18":1,"46":1}}],["4×6",{"2":{"1":1}}],["│",{"2":{"1":20,"3":4,"4":2,"6":2,"7":2,"8":4,"16":108,"18":2,"20":2,"22":6,"23":2,"33":2,"37":2,"40":4,"45":4,"46":2}}],["800",{"2":{"41":1}}],["80",{"2":{"40":2}}],["805",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["853306",{"2":{"20":1,"22":3,"23":1}}],["833",{"2":{"3":1,"4":1,"6":1,"7":1,"8":2,"33":1}}],["8333",{"2":{"3":4,"4":2,"6":2,"7":2,"8":4,"33":2}}],["83333333333333",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":2,"33":1,"45":1,"46":1}}],["83333333333331",{"2":{"3":1,"4":1,"6":1,"7":1,"8":3,"18":1,"33":1,"45":2}}],["8485",{"2":{"4":1}}],["84",{"2":{"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"33":2,"37":2,"45":4,"46":2}}],["8901",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["89",{"2":{"3":14,"4":6,"6":7,"7":6,"8":14,"18":1,"33":7,"40":2,"45":1}}],["8991",{"2":{"1":1}}],["87126",{"2":{"1":1}}],["873182",{"2":{"1":4}}],["8688",{"2":{"1":1}}],["8868",{"2":{"1":1}}],["88",{"2":{"1":1,"40":2}}],["8",{"2":{"1":2,"26":1}}],["382602",{"2":{"17":1}}],["381847",{"2":{"17":1}}],["3818",{"2":{"16":1}}],["381",{"2":{"1":1}}],["311813",{"2":{"20":1,"22":3,"23":1}}],["310064",{"2":{"17":1}}],["31",{"2":{"4":1}}],["348444",{"2":{"20":1,"22":3,"23":1}}],["347186",{"2":{"17":1}}],["347",{"2":{"16":1}}],["34",{"2":{"4":1}}],["36",{"2":{"16":8,"17":18}}],["360",{"2":{"3":1,"40":2}}],["3656",{"2":{"1":1}}],["3d",{"2":{"2":2,"32":1,"33":2,"34":2,"36":2,"38":1}}],["338776",{"2":{"17":1}}],["332969",{"2":{"17":1}}],["333783",{"2":{"17":2}}],["333",{"2":{"16":1}}],["33333333333336",{"2":{"37":2}}],["3333",{"2":{"3":2,"6":1,"8":2,"33":1}}],["33",{"2":{"1":1}}],["32768",{"2":{"45":2,"46":1}}],["324747",{"2":{"20":1,"22":3,"23":1}}],["328025",{"2":{"17":1}}],["328896",{"2":{"17":1}}],["329765",{"2":{"20":1,"22":3,"23":1}}],["329",{"2":{"16":1}}],["321388f0",{"2":{"1":1}}],["32",{"2":{"1":3,"46":2}}],["359",{"2":{"40":2}}],["357",{"2":{"40":2}}],["35",{"2":{"1":6}}],["3",{"0":{"34":1},"2":{"1":9,"2":2,"3":10,"4":1,"6":8,"8":18,"10":1,"16":1,"18":2,"20":1,"22":1,"33":9,"36":3,"37":3,"40":5,"45":6,"46":5}}],["305028",{"2":{"20":1,"22":3,"23":1}}],["30362",{"2":{"17":1}}],["3036",{"2":{"16":1}}],["300",{"2":{"16":1}}],["3087",{"2":{"1":1}}],["30",{"2":{"1":5,"4":2,"20":8,"21":1,"22":18,"23":6,"40":2}}],["37036",{"2":{"20":1,"22":3,"23":1}}],["377673",{"2":{"17":1}}],["373215",{"2":{"17":1}}],["37",{"2":{"1":2,"17":1,"40":2}}],["398438",{"2":{"17":1}}],["394749",{"2":{"17":1}}],["396453",{"2":{"17":1}}],["396",{"2":{"16":1}}],["391682",{"2":{"17":1}}],["391097",{"2":{"17":1}}],["391",{"2":{"16":1}}],["399",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["39",{"2":{"1":9,"2":5,"8":1,"13":1,"18":2,"27":2,"38":1,"42":1}}],["0f20",{"2":{"40":4}}],["0f0",{"2":{"1":5,"6":1,"7":1}}],["0xffffffff",{"2":{"37":1}}],["0xffff",{"2":{"37":3}}],["04",{"2":{"24":1}}],["046",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["0840219",{"2":{"20":1,"22":3,"23":1}}],["0619296",{"2":{"20":1,"22":3,"23":1}}],["063",{"2":{"1":1}}],["096394",{"2":{"17":1}}],["096",{"2":{"16":1}}],["092",{"2":{"4":1}}],["05",{"2":{"1":1}}],["0273",{"2":{"1":1}}],["029825f0",{"2":{"1":1}}],["0351028",{"2":{"20":1,"22":3,"23":1}}],["03",{"2":{"1":2}}],["0768",{"2":{"3":1}}],["076923f0",{"2":{"1":2}}],["077084f0",{"2":{"1":1}}],["07",{"2":{"1":1}}],["0",{"2":{"1":78,"2":2,"3":27,"4":12,"6":12,"7":18,"8":24,"17":1,"18":4,"20":36,"22":108,"23":36,"26":1,"33":12,"36":1,"37":5,"40":22,"42":1,"44":1,"45":9,"46":5}}],["0094",{"2":{"3":1}}],["005fvlen",{"2":{"2":2}}],["005fdef",{"2":{"2":2}}],["007",{"2":{"1":1}}],["000000000000005",{"2":{"37":1}}],["000000000000004",{"2":{"18":1}}],["000",{"2":{"1":2}}],["00",{"2":{"1":12,"20":8,"22":8,"40":16}}],["0174532925199433",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["01154e6",{"2":{"1":4}}],["01t00",{"2":{"1":6,"20":4,"22":4,"40":4}}],["01",{"2":{"1":6,"20":4,"22":2,"40":10}}],["kingdom",{"2":{"16":1}}],["k",{"2":{"2":3,"40":2}}],["keeps",{"2":{"1":1}}],["keys",{"2":{"1":10,"2":4}}],["keyword",{"2":{"1":15,"2":6}}],["keywords",{"2":{"1":35,"2":11,"15":1,"34":1,"36":1}}],["key",{"2":{"1":2,"27":1}}],["known",{"2":{"11":1}}],["know",{"2":{"1":4,"5":1,"27":1}}],["kw",{"2":{"1":23,"2":5,"18":2,"36":1,"38":1}}],["uint16",{"2":{"37":3}}],["uint64",{"2":{"16":2}}],["uint8",{"2":{"16":1}}],["uint32",{"2":{"1":1,"37":1}}],["ucar",{"2":{"2":2,"40":1}}],["update",{"2":{"8":1,"29":1}}],["updating",{"2":{"1":1}}],["upper",{"2":{"1":13}}],["upper=",{"2":{"1":1}}],["url",{"2":{"1":14,"27":1,"40":2,"44":2}}],["unexported",{"2":{"34":1,"38":1}}],["unexpected",{"2":{"1":6}}],["until",{"2":{"24":1}}],["unitrange",{"2":{"16":1}}],["unit",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"39":1,"45":2,"46":1}}],["units",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"40":4}}],["unidata",{"2":{"2":2,"40":1}}],["union",{"2":{"1":10,"2":2,"40":2}}],["unmasked",{"2":{"1":2}}],["under",{"2":{"26":1}}],["underscores",{"2":{"2":1}}],["underlying",{"2":{"1":3,"2":1,"31":1,"36":1,"38":1}}],["undefined",{"2":{"1":1}}],["unchanged",{"2":{"1":3}}],["unless",{"2":{"1":2}}],["unopened",{"2":{"1":1}}],["us",{"2":{"1":1}}],["using",{"0":{"37":1,"45":1},"2":{"1":25,"2":3,"10":1,"11":2,"12":1,"14":1,"15":1,"16":1,"20":2,"22":1,"24":1,"26":8,"33":1,"39":1,"40":2,"43":2,"44":1,"45":3,"46":3}}],["usually",{"2":{"1":11,"2":5,"36":1}}],["users",{"2":{"2":1}}],["uses",{"2":{"1":3,"9":1,"23":1,"40":1}}],["used",{"2":{"1":90,"2":16,"5":1,"8":1,"11":2,"13":1,"15":2,"23":1,"24":1,"38":1,"42":1}}],["use",{"2":{"1":44,"2":6,"3":1,"4":1,"6":1,"9":1,"11":1,"24":2,"26":1,"27":1,"28":1,"34":1,"38":1,"40":1}}],["usefull",{"2":{"1":2}}],["usefulnesss",{"2":{"1":1}}],["useful",{"2":{"1":9,"31":1}}],["=a",{"2":{"22":1}}],["===",{"2":{"1":1}}],["=>",{"2":{"1":14,"3":8,"4":4,"6":4,"7":4,"8":10,"33":4,"40":18}}],["=",{"2":{"1":137,"2":18,"3":5,"4":5,"6":4,"7":2,"8":4,"15":1,"16":2,"17":1,"18":8,"20":6,"21":2,"22":7,"23":2,"24":3,"33":6,"34":4,"36":20,"37":20,"38":1,"39":2,"40":10,"44":2,"45":21,"46":18}}],["visualize",{"2":{"34":1}}],["via",{"2":{"2":2,"22":1,"45":1}}],["views",{"2":{"1":1}}],["view",{"2":{"1":4,"24":4}}],["vlen",{"2":{"2":2}}],["vebose",{"2":{"1":2,"2":2}}],["vertical",{"2":{"23":1}}],["verbose",{"2":{"1":4}}],["version",{"2":{"1":2}}],["versions",{"2":{"1":19}}],["very",{"2":{"1":5,"10":1,"38":1}}],["vectors",{"2":{"1":1}}],["vector",{"2":{"1":17,"2":2,"16":2,"17":2,"36":2,"44":1}}],["vanilla",{"0":{"37":1}}],["variations",{"2":{"27":1}}],["variable",{"2":{"2":2}}],["variables",{"2":{"1":2,"11":1,"18":1}}],["various",{"2":{"15":1}}],["valid",{"2":{"2":2}}],["values",{"0":{"29":1},"2":{"1":75,"2":3,"6":1,"24":3,"28":1,"29":2,"30":1,"36":1,"38":3,"42":1,"45":1}}],["value",{"0":{"23":1},"2":{"1":55,"2":4,"5":1,"8":1,"17":1,"24":4,"40":2,"46":1}}],["val",{"2":{"1":2}}],["val=",{"2":{"1":1}}],["2d",{"2":{"34":1,"38":1}}],["26",{"2":{"20":2,"22":6,"23":2}}],["235596",{"2":{"17":1}}],["236",{"2":{"16":1}}],["23",{"2":{"3":1,"16":1,"40":2}}],["23017e6",{"2":{"1":4}}],["220698",{"2":{"20":1,"22":3,"23":1}}],["22",{"2":{"1":1,"3":2,"16":1}}],["2727",{"2":{"1":1}}],["27",{"2":{"1":4,"4":1,"20":2,"22":6,"23":2}}],["273",{"2":{"1":1}}],["271",{"2":{"1":1}}],["284565",{"2":{"17":1}}],["285",{"2":{"16":1}}],["2888",{"2":{"1":1}}],["28",{"2":{"1":2,"4":1,"20":2,"22":6,"23":2}}],["2955",{"2":{"4":1}}],["298",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["29",{"2":{"1":4,"20":2,"22":6,"23":2}}],["240881",{"2":{"17":1}}],["241",{"2":{"16":1}}],["243",{"2":{"1":1}}],["24534",{"2":{"1":1}}],["24",{"2":{"1":5}}],["219342",{"2":{"20":1,"22":3,"23":1}}],["2160",{"2":{"3":1,"4":1,"6":1,"7":1,"8":2,"33":1,"45":1}}],["2160×1080",{"2":{"3":1,"4":1,"6":1,"7":1,"8":2,"33":1,"45":5}}],["21",{"2":{"1":4,"16":1}}],["2592000000",{"2":{"40":1}}],["259489",{"2":{"17":1}}],["258",{"2":{"1":1}}],["258×8",{"2":{"1":1}}],["257223563",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["257",{"2":{"1":1}}],["256",{"2":{"1":1,"2":6,"17":1}}],["255",{"2":{"1":1}}],["254",{"2":{"1":1}}],["253",{"2":{"1":1}}],["252",{"2":{"1":1}}],["25",{"2":{"1":9,"18":3,"20":8,"21":1,"22":18,"23":6,"24":2,"45":2}}],["2",{"0":{"33":1},"2":{"1":9,"2":3,"3":2,"4":4,"6":1,"7":1,"8":2,"13":1,"16":1,"22":2,"23":1,"32":1,"33":5,"36":2,"37":7,"39":1,"42":1}}],["20833333333334",{"2":{"37":1}}],["207309",{"2":{"20":1,"22":3,"23":1}}],["2020",{"2":{"16":1}}],["2021",{"2":{"16":1}}],["2012",{"2":{"16":2}}],["2016",{"2":{"16":2}}],["2011",{"2":{"16":2}}],["2015",{"2":{"16":1}}],["2065",{"2":{"1":1}}],["20417f0",{"2":{"1":1}}],["2003",{"2":{"40":2}}],["2005",{"2":{"40":2}}],["2009",{"2":{"1":1}}],["2002",{"2":{"1":3,"20":3,"40":5}}],["2001",{"2":{"1":6,"20":3,"22":4,"23":1,"40":7}}],["20",{"2":{"1":11,"42":2}}],["gadm",{"2":{"43":1}}],["going",{"2":{"38":1}}],["good",{"2":{"27":1}}],["google",{"2":{"27":1}}],["gbif",{"0":{"16":1}}],["gbif2",{"2":{"1":2,"16":4}}],["global",{"2":{"13":1,"45":1}}],["guaranteed",{"2":{"2":2}}],["guessed",{"2":{"2":3}}],["guessing",{"2":{"2":2}}],["gis",{"2":{"29":1}}],["giving",{"2":{"1":1}}],["given",{"2":{"1":2,"20":1}}],["gives",{"2":{"1":6}}],["give",{"2":{"1":7}}],["github",{"2":{"1":23,"44":1}}],["gpu",{"2":{"1":1,"31":1}}],["great",{"2":{"27":1}}],["greenwich",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["grow",{"2":{"1":2}}],["group3",{"2":{"1":2}}],["group2",{"2":{"1":2}}],["group1",{"2":{"1":2}}],["group=",{"2":{"1":2}}],["groups",{"2":{"1":2}}],["group",{"2":{"1":6}}],["gri",{"2":{"2":4}}],["grid=false",{"2":{"37":2}}],["gridposition",{"2":{"2":1,"36":1,"38":1}}],["grid",{"2":{"1":2,"2":2}}],["gridcell",{"2":{"1":1}}],["gribsource",{"2":{"1":2,"2":3}}],["grib",{"2":{"1":4,"2":3,"26":1}}],["grdsource",{"2":{"2":1}}],["grd",{"0":{"10":1},"2":{"1":2,"2":12,"10":1,"26":1}}],["g",{"2":{"1":11,"2":1,"20":1,"23":1,"24":2,"27":1,"28":1,"31":1,"38":1}}],["gdalwarp",{"2":{"1":4,"28":1}}],["gdals",{"2":{"1":2}}],["gdalsource",{"2":{"1":2,"2":3,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["gdal",{"0":{"12":1},"2":{"1":8,"2":15,"12":1,"26":3}}],["gdalarray",{"2":{"1":1}}],["gt",{"2":{"1":17,"2":2}}],["getting",{"0":{"21":1}}],["getdriver",{"2":{"2":2}}],["getring",{"2":{"1":1}}],["getring`",{"2":{"1":1}}],["getraster",{"2":{"1":1,"15":1}}],["get",{"0":{"18":1},"2":{"1":8,"18":1,"24":4,"27":1,"40":1,"43":1}}],["getindex",{"2":{"1":10,"24":2}}],["geogcs",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["geoaxis",{"2":{"2":1,"36":1}}],["geomakie",{"2":{"2":1,"36":1}}],["geom",{"2":{"1":7}}],["geometric",{"2":{"1":1}}],["geometries",{"2":{"1":50,"30":3}}],["geometrycolumn",{"2":{"1":20}}],["geometry",{"2":{"1":32,"16":1}}],["geotiff",{"2":{"1":1,"20":1}}],["geointerface",{"2":{"1":18,"17":1}}],["geoformattypes",{"2":{"1":7,"8":1}}],["geoformat",{"2":{"1":9,"8":1}}],["generating",{"2":{"5":1}}],["generator",{"2":{"1":1}}],["generates",{"2":{"20":1}}],["generate",{"2":{"1":4}}],["generally",{"2":{"1":1,"8":1,"12":1}}],["generically",{"2":{"23":1}}],["generic",{"2":{"1":1,"40":1,"46":1}}],["||",{"2":{"1":5}}],["|",{"2":{"1":2}}],["|>",{"2":{"1":7,"37":1,"40":2,"42":1}}],["np",{"2":{"46":3}}],["ncstack",{"2":{"11":1}}],["ncdatasets",{"2":{"11":1,"26":1,"40":1,"43":1}}],["ncdsource",{"2":{"1":2,"2":5,"40":2}}],["nc",{"2":{"2":4,"11":3,"40":2,"42":2,"46":1}}],["ntuple",{"2":{"2":3}}],["nuevo",{"2":{"1":1}}],["numbers",{"2":{"20":1}}],["number",{"2":{"1":3,"9":1}}],["natively",{"2":{"10":1}}],["natural",{"2":{"1":5,"44":1}}],["na",{"2":{"2":3}}],["nan",{"2":{"1":16,"2":2,"36":2}}],["name=",{"2":{"6":1,"11":1,"13":1}}],["nametuple",{"2":{"1":1}}],["names",{"2":{"1":2,"11":1,"23":1,"36":1}}],["named",{"2":{"1":1,"20":1}}],["namedtuple",{"2":{"1":12,"2":5}}],["name",{"2":{"1":29,"2":7,"6":2,"11":1,"13":1,"36":3,"40":6,"44":2,"45":1}}],["nvkelso",{"2":{"1":4,"44":1}}],["nz",{"2":{"1":6}}],["n",{"2":{"1":1,"2":3}}],["norway",{"2":{"45":4,"46":11}}],["north",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["normally",{"2":{"1":2}}],["nochecksum",{"2":{"2":2}}],["now",{"2":{"1":1,"26":1,"40":2,"46":2}}],["nodataval",{"2":{"2":3}}],["nodata",{"2":{"1":9}}],["none",{"2":{"18":1}}],["non",{"2":{"1":12,"42":1}}],["no",{"2":{"1":23,"2":4}}],["nometadata",{"2":{"1":1}}],["notice",{"2":{"40":1}}],["nothing",{"2":{"1":22,"2":2,"36":2}}],["note",{"2":{"1":10,"24":1,"29":1}}],["not",{"2":{"1":103,"2":6,"10":1,"11":1,"14":1,"26":1,"27":2,"33":1,"36":1,"38":1}}],["neighbour",{"2":{"1":1}}],["ne",{"2":{"1":7,"44":1}}],["newdocs",{"2":{"2":2}}],["newmissingval",{"2":{"1":2}}],["new",{"2":{"1":11,"5":1}}],["nested",{"2":{"1":13,"8":1}}],["needs",{"2":{"2":2}}],["needed",{"2":{"1":4,"26":1}}],["need",{"2":{"1":6,"2":2,"4":1,"6":1,"26":2,"27":4,"36":1,"40":1}}],["netcdf",{"0":{"11":1},"2":{"1":9,"2":14,"11":4,"20":1,"23":1,"26":1,"28":1,"40":2,"46":1}}],["nearly",{"2":{"27":1}}],["nearest",{"2":{"1":1}}],["near",{"2":{"1":3,"23":1,"24":1,"40":2,"42":1}}],["xlabel",{"2":{"2":1,"36":1,"37":1}}],["x=",{"2":{"1":1}}],["x=100",{"2":{"1":1}}],["xs",{"2":{"1":8}}],["xdim",{"2":{"1":8,"2":1,"36":1}}],["x",{"2":{"1":68,"2":11,"3":5,"4":2,"6":2,"7":2,"8":6,"10":1,"11":1,"13":1,"17":1,"18":7,"20":4,"21":2,"22":6,"23":4,"24":6,"29":1,"33":2,"36":4,"37":7,"40":7,"42":1,"45":12,"46":7}}],["x3c",{"2":{"1":14,"2":3}}],["ylabel",{"2":{"2":1,"36":1,"37":1}}],["year",{"2":{"16":1,"40":1}}],["year=",{"2":{"1":1}}],["yet",{"2":{"2":1,"26":1}}],["y=",{"2":{"1":2}}],["ydim",{"2":{"1":8,"2":2,"36":2}}],["y",{"2":{"1":18,"2":8,"3":4,"4":2,"6":2,"7":2,"8":4,"10":1,"11":1,"13":1,"17":1,"18":7,"20":4,"21":2,"22":6,"23":4,"24":2,"29":1,"33":2,"36":5,"37":7,"40":7,"42":2,"45":12,"46":7}}],["your",{"2":{"1":2,"27":2}}],["you",{"2":{"1":16,"2":6,"5":2,"6":1,"8":1,"9":1,"26":4,"27":3,"32":1,"34":2,"36":1,"38":1}}],["1×1080",{"2":{"3":1}}],["190",{"2":{"40":1}}],["194",{"2":{"37":1}}],["194×161",{"2":{"37":5}}],["1984",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["192",{"2":{"1":1}}],["19279e6",{"2":{"1":4}}],["185905",{"2":{"20":1,"22":3,"23":1}}],["18",{"2":{"16":1}}],["1837",{"2":{"1":1}}],["1864",{"2":{"1":1}}],["180×170×1",{"2":{"40":1}}],["180×170×24",{"2":{"40":1}}],["180",{"2":{"1":2,"3":8,"4":3,"6":3,"7":3,"8":6,"33":3,"45":2}}],["147",{"2":{"16":1,"17":2}}],["1478",{"2":{"3":1,"6":1,"7":1,"8":2,"33":1}}],["148",{"2":{"16":7,"17":17}}],["14",{"2":{"1":2,"3":1,"6":1,"7":1,"8":2,"33":1}}],["145538",{"2":{"20":1,"22":3,"23":1}}],["145",{"2":{"1":1}}],["144",{"2":{"1":1}}],["16666666666666666",{"2":{"46":2}}],["1666666666666443",{"2":{"46":2}}],["16666666666667",{"2":{"18":1}}],["16t00",{"2":{"40":4}}],["161",{"2":{"37":1}}],["1622",{"2":{"1":1}}],["160",{"2":{"1":3,"37":1}}],["16",{"2":{"1":1,"40":2}}],["165",{"2":{"1":1}}],["1f0",{"2":{"1":1}}],["177×119",{"2":{"46":5}}],["179414",{"2":{"20":1,"22":3,"23":1}}],["179",{"2":{"3":3,"4":3,"6":3,"7":3,"8":6,"33":3,"45":2}}],["17",{"2":{"1":6,"3":1,"6":1,"7":1,"8":2,"33":1,"40":1}}],["138",{"2":{"18":3}}],["13",{"2":{"1":2,"3":1,"6":1,"7":1,"8":2,"33":1,"37":2}}],["13084",{"2":{"20":1,"22":3,"23":1}}],["130",{"2":{"1":1}}],["153",{"2":{"37":2}}],["153847f0",{"2":{"1":2}}],["154",{"2":{"18":2}}],["155",{"2":{"18":1}}],["15",{"2":{"1":7,"3":3,"6":3,"7":3,"8":6,"16":2,"33":3}}],["150",{"2":{"1":1}}],["1287",{"2":{"1":1}}],["12",{"2":{"1":3,"18":1,"24":2,"36":1,"40":2}}],["120",{"2":{"1":3}}],["113",{"2":{"37":2}}],["11",{"2":{"1":1,"16":6,"40":2}}],["110",{"2":{"1":1}}],["11917e6",{"2":{"1":4}}],["109752",{"2":{"20":1,"22":3,"23":1}}],["102",{"2":{"18":1,"45":1}}],["102×89",{"2":{"18":5}}],["1080",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"45":1}}],["10m",{"2":{"1":8,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"44":2}}],["10",{"2":{"1":34,"16":1,"22":3,"37":3,"45":1}}],["100",{"2":{"1":28,"24":1,"37":1}}],["1",{"2":{"1":39,"2":4,"3":4,"4":2,"6":2,"7":2,"8":4,"16":3,"17":1,"18":4,"20":7,"21":1,"22":10,"23":2,"24":1,"26":1,"33":4,"34":1,"36":2,"37":6,"40":8,"42":1,"46":2}}],["dp",{"2":{"46":1}}],["dpi=300",{"2":{"41":1}}],["d",{"0":{"33":1,"34":1},"2":{"32":1}}],["df",{"2":{"18":2}}],["dark",{"2":{"37":1}}],["day",{"2":{"16":1}}],["datsets",{"2":{"15":1}}],["datum",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["date",{"2":{"40":1}}],["date=datetime",{"2":{"1":2}}],["dates",{"2":{"1":8,"15":1,"20":1,"43":1,"45":1}}],["datetime360day",{"2":{"40":12}}],["datetime",{"2":{"1":13,"20":7,"22":5,"23":1}}],["dataaspect",{"2":{"33":1,"34":1}}],["dataframe",{"2":{"1":3,"18":2}}],["dataframes",{"2":{"1":1,"18":1}}],["datasets",{"2":{"1":2,"15":1}}],["dataset",{"2":{"1":4,"2":4,"13":1,"45":1}}],["data",{"0":{"9":1,"31":1,"40":1},"1":{"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"41":1,"42":1},"2":{"1":52,"2":1,"3":1,"9":1,"13":1,"14":1,"15":3,"20":1,"23":1,"26":1,"27":1,"28":3,"31":4,"36":1,"37":1,"38":1,"40":2,"45":1}}],["drive",{"2":{"27":1}}],["drivers",{"2":{"2":2}}],["drivername",{"2":{"2":2}}],["driver",{"2":{"2":12}}],["draw",{"2":{"2":2,"36":2}}],["drop",{"2":{"1":2,"27":1}}],["dropband",{"2":{"1":2}}],["dhekelia",{"2":{"1":1}}],["dbf",{"2":{"1":7}}],["dstlookup",{"2":{"1":1}}],["dst",{"2":{"1":4,"2":4}}],["due",{"2":{"1":9}}],["during",{"2":{"1":2}}],["duplicate",{"2":{"1":4}}],["documentation",{"2":{"28":1}}],["documenter",{"2":{"13":1}}],["docstring",{"2":{"13":2}}],["docs",{"2":{"1":2,"14":1,"15":2}}],["dot",{"2":{"3":1}}],["down",{"2":{"1":2}}],["downloading",{"2":{"27":1}}],["downloads",{"2":{"1":9,"26":1,"27":1,"40":1,"43":1,"44":2}}],["download",{"0":{"44":1},"1":{"45":1,"46":1},"2":{"1":12,"15":2,"26":1,"40":2,"44":1}}],["do",{"2":{"1":2,"2":5,"3":1,"4":2,"5":1,"20":1,"26":1,"27":1,"36":1,"37":1}}],["don",{"2":{"1":1,"2":4,"8":1}}],["done",{"2":{"1":2,"22":1,"27":1}}],["doesn",{"2":{"42":1}}],["does",{"2":{"1":6}}],["denmark",{"2":{"45":4,"46":4}}],["degc",{"2":{"40":2}}],["degree",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"42":1,"45":2,"46":1}}],["degrees",{"2":{"1":6}}],["descriptions",{"2":{"28":1}}],["description",{"2":{"24":1,"28":1,"29":1,"30":1,"31":1}}],["designed",{"2":{"23":1}}],["destructively",{"2":{"2":6}}],["destination",{"2":{"1":1}}],["dest",{"2":{"1":3}}],["decimallatitude",{"2":{"17":2}}],["decimallongitude",{"2":{"17":1}}],["decline",{"2":{"1":2}}],["details",{"2":{"13":1,"23":1}}],["determines",{"2":{"1":1}}],["determine",{"2":{"1":6}}],["detect",{"2":{"9":1}}],["detected",{"2":{"1":10,"2":6}}],["detecting",{"2":{"1":1}}],["depending",{"2":{"1":2,"2":1}}],["depth",{"2":{"1":2,"28":1}}],["deferred",{"2":{"24":1}}],["deflate",{"2":{"2":2}}],["deflatelevel",{"2":{"2":2}}],["defualts",{"2":{"1":2}}],["defined",{"2":{"1":1,"2":1}}],["define",{"2":{"1":2,"46":1}}],["defines",{"2":{"1":1,"23":1}}],["defaults",{"2":{"1":3}}],["defaulting",{"2":{"1":1}}],["default",{"2":{"1":64,"2":20,"12":1,"36":1}}],["difficult",{"2":{"8":1}}],["differences",{"2":{"1":2}}],["differently",{"2":{"32":1}}],["different",{"2":{"1":3,"11":1,"14":1,"28":3,"32":1}}],["differnce",{"2":{"1":1}}],["divided",{"2":{"1":2}}],["directions",{"2":{"23":1}}],["directly",{"2":{"1":8,"2":1,"3":1,"4":1,"11":1,"15":1}}],["directory",{"2":{"1":4,"2":2}}],["directories",{"2":{"1":1}}],["dir",{"2":{"1":4}}],["dictionary",{"2":{"2":2}}],["dict",{"2":{"1":5,"2":4,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"40":2}}],["disable",{"2":{"2":1}}],["disaggregate",{"2":{"0":2,"1":4,"28":2}}],["distribution",{"2":{"1":1}}],["distance",{"2":{"1":4}}],["diskarrays",{"2":{"2":4}}],["disk",{"0":{"14":1,"42":1},"2":{"1":10,"2":3,"3":1,"4":2,"11":1,"14":1,"24":1,"31":1,"40":2,"42":1,"46":1}}],["dimtuple",{"2":{"1":1}}],["dimz",{"2":{"1":2}}],["dim",{"2":{"1":2,"11":1}}],["dims=ti",{"2":{"40":1}}],["dims=x",{"2":{"3":1}}],["dims=",{"2":{"1":2}}],["dims=band",{"2":{"1":1}}],["dims",{"2":{"1":22,"3":2,"4":1,"6":1,"7":1,"8":2,"18":5,"20":1,"22":3,"23":1,"33":1,"37":5,"40":2,"45":10,"46":5}}],["dimension",{"0":{"3":1},"2":{"1":47,"2":14,"3":1,"8":1,"11":1,"12":1,"23":2,"24":1,"28":2,"36":8,"38":1,"40":2}}],["dimensional",{"2":{"2":2,"10":1,"13":1,"36":2,"38":1}}],["dimensionalarray",{"2":{"1":1}}],["dimensionaldata",{"2":{"1":6,"20":1,"23":2,"24":1,"40":1,"42":1}}],["dimensions",{"0":{"21":1},"2":{"1":43,"2":7,"8":2,"10":1,"11":3,"13":1,"20":2,"23":5,"24":1,"29":1,"36":2,"40":1,"42":1}}],["efficient",{"2":{"34":1}}],["effort",{"2":{"27":1}}],["effect",{"2":{"1":3}}],["especially",{"2":{"23":1}}],["ecology",{"2":{"15":1}}],["eltype",{"2":{"18":4,"37":4,"45":8,"46":4}}],["else",{"2":{"2":2}}],["elements",{"2":{"1":1,"2":1}}],["element",{"2":{"1":3,"16":1,"17":1,"36":1}}],["elevation",{"2":{"1":1}}],["every",{"2":{"40":1}}],["everything",{"2":{"2":2}}],["evenness",{"2":{"1":19,"37":3}}],["even",{"2":{"1":1,"2":7,"32":1,"33":1,"36":1}}],["edu",{"2":{"2":2,"40":1}}],["etc",{"2":{"1":1}}],["errors",{"0":{"27":1},"2":{"1":2,"27":1}}],["error",{"2":{"1":4,"27":1}}],["empty",{"2":{"1":3}}],["enumerate",{"2":{"37":2}}],["environmental",{"2":{"15":1}}],["entries",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1,"40":2}}],["entire",{"2":{"1":2,"46":1}}],["enough",{"2":{"2":1}}],["ensure",{"2":{"2":1}}],["end",{"2":{"1":1,"2":1,"4":2,"36":1,"37":2,"46":2}}],["equal",{"2":{"1":1,"2":1}}],["ease",{"2":{"32":1}}],["easy",{"2":{"27":1}}],["east",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":2,"33":1,"37":1,"45":2,"46":1}}],["eagerly",{"2":{"1":1}}],["earthenv",{"2":{"1":8,"37":2}}],["earth",{"2":{"1":7,"44":1}}],["eachchunk",{"2":{"2":1}}],["each",{"2":{"1":24,"2":10,"26":1,"28":1,"36":1,"46":1}}],["e",{"2":{"1":13,"2":4,"20":1,"23":1,"24":2,"27":1,"28":1,"31":1,"36":1,"38":1}}],["eg",{"2":{"1":3}}],["epsg",{"2":{"1":8,"3":10,"4":5,"6":5,"7":5,"8":10,"18":5,"23":1,"33":5,"37":5,"40":4,"45":10,"46":5}}],["either",{"2":{"1":2,"2":1}}],["excluding",{"2":{"24":1}}],["excessive",{"2":{"1":5}}],["exact",{"2":{"27":1}}],["exactly",{"2":{"24":1}}],["examples",{"2":{"20":1,"28":1,"40":1}}],["example",{"2":{"1":46,"2":2,"26":1,"27":1,"34":1,"40":1,"42":1,"43":1}}],["exists",{"2":{"2":8}}],["existing",{"2":{"1":3}}],["explicit",{"2":{"23":1,"40":2}}],["experience",{"2":{"1":1}}],["experimental",{"2":{"1":19,"34":1}}],["expected",{"2":{"1":6}}],["exported",{"0":{"1":1}}],["extra",{"2":{"27":1}}],["extracts",{"2":{"1":1}}],["extract",{"0":{"17":1},"2":{"0":1,"1":5,"17":1,"18":2,"30":2}}],["extrema",{"2":{"1":2}}],["ext",{"2":{"1":1,"2":2,"14":1}}],["extensions",{"0":{"26":1},"2":{"26":3}}],["extension",{"2":{"1":2,"2":18}}],["extents",{"2":{"1":18,"28":1}}],["extent",{"0":{"28":1},"2":{"1":43,"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"20":2,"22":6,"23":2,"28":2,"33":2,"37":2,"40":4,"45":4,"46":2}}],["extends",{"2":{"20":1}}],["extend",{"2":{"0":1,"1":8,"28":2}}],["l",{"2":{"37":4}}],["lscene",{"2":{"2":1,"36":1}}],["limited",{"2":{"38":1}}],["limit=300",{"2":{"16":1}}],["limit=5",{"2":{"1":1}}],["little",{"2":{"14":1,"27":1,"34":2}}],["linrange",{"2":{"3":3,"4":2,"6":2,"7":2,"8":4,"18":2,"33":2,"37":2,"45":4}}],["linewidth=0",{"2":{"1":2,"46":1}}],["lines",{"2":{"1":11,"44":1}}],["line",{"2":{"1":11}}],["listed",{"2":{"24":1}}],["list",{"2":{"1":1}}],["likely",{"2":{"1":1}}],["like",{"2":{"1":18,"2":4,"3":1,"20":1,"23":3,"26":2,"32":1,"38":1}}],["lt",{"2":{"1":20}}],["lets",{"2":{"46":1}}],["legend=",{"2":{"18":1}}],["legend=false",{"2":{"1":1}}],["left",{"2":{"2":1,"36":1}}],["leave",{"2":{"1":2}}],["length",{"2":{"1":5,"2":1,"36":1,"46":1}}],["level",{"2":{"1":1,"2":2}}],["layout",{"2":{"37":2}}],["layername",{"2":{"11":2,"13":1}}],["layered",{"2":{"1":4,"2":1,"13":1,"46":1}}],["layer",{"0":{"18":1},"2":{"1":16,"2":2,"6":1,"11":1,"13":1,"40":1,"46":1}}],["layersfrom",{"2":{"1":1}}],["layersfrom=band",{"2":{"1":2,"12":1}}],["layers",{"2":{"1":24,"2":3,"4":1,"11":4,"12":1,"13":3,"18":2,"28":1,"37":5,"45":3,"46":1}}],["label",{"2":{"2":3,"36":3,"37":1,"40":1}}],["labels",{"2":{"1":1}}],["lanczos",{"2":{"1":2}}],["last",{"2":{"1":12}}],["largely",{"2":{"23":1}}],["largest",{"2":{"1":1}}],["larger",{"2":{"1":2}}],["large",{"2":{"1":19,"38":2}}],["lazy=false",{"2":{"1":1,"2":1}}],["lazy=true",{"2":{"1":5,"2":1,"3":1}}],["lazy",{"2":{"1":10,"2":3,"24":1}}],["lazily",{"2":{"1":10,"2":1,"3":1,"46":1}}],["latitude",{"2":{"1":1,"3":2,"4":1,"6":1,"7":1,"8":2,"17":1,"18":1,"21":1,"23":1,"33":1,"37":1,"42":1,"45":2,"46":1}}],["latter",{"2":{"1":1}}],["later",{"2":{"1":1}}],["lat",{"2":{"1":5,"20":2,"21":1,"37":1,"40":1}}],["log",{"2":{"13":1}}],["lot",{"2":{"2":2,"46":1}}],["lost",{"2":{"14":1}}],["loses",{"2":{"1":1}}],["lossless",{"2":{"1":1}}],["lower",{"2":{"1":13}}],["lower=",{"2":{"1":1}}],["low",{"2":{"1":5,"2":1,"36":1}}],["locus",{"2":{"1":4}}],["location",{"2":{"1":1}}],["longest",{"2":{"38":1}}],["longitude",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"17":1,"18":1,"21":1,"23":1,"33":1,"37":1,"45":2,"46":1}}],["long",{"2":{"1":1,"40":2}}],["lon",{"2":{"1":4,"20":2,"37":1,"40":1}}],["lookups",{"2":{"1":9,"2":1}}],["lookup",{"0":{"21":1},"2":{"1":17,"2":2,"21":2,"23":2}}],["loads",{"2":{"26":1,"40":1}}],["load",{"0":{"16":1,"31":1,"45":1},"2":{"1":13,"9":1,"15":1,"26":2,"40":1,"45":2}}],["loading",{"0":{"40":1},"1":{"41":1,"42":1},"2":{"1":5,"11":1,"38":1}}],["loaded",{"2":{"1":6,"10":1,"11":2,"12":3,"13":2,"14":1}}],["h5",{"2":{"13":2}}],["html",{"2":{"2":4}}],["https",{"2":{"1":4,"2":6,"40":1,"44":1}}],["hosting",{"2":{"27":1}}],["however",{"2":{"1":2}}],["how",{"2":{"1":3,"23":1,"27":2,"38":1}}],["holding",{"2":{"2":1,"5":1}}],["holds",{"2":{"1":1,"2":3}}],["hold",{"2":{"1":6}}],["height=relative",{"2":{"36":1}}],["help",{"2":{"11":1}}],["header",{"2":{"2":3}}],["heatmap",{"2":{"1":1,"2":4,"32":1,"36":4,"37":1,"38":2}}],["heterogeneity",{"2":{"1":1}}],["here",{"2":{"1":3,"2":1,"8":1,"24":1,"34":1,"36":1,"40":1}}],["history",{"2":{"40":2}}],["hidden",{"2":{"2":1}}],["hideydecorations",{"2":{"37":1}}],["hidexdecorations",{"2":{"37":1}}],["hide",{"2":{"1":7}}],["high",{"2":{"1":6,"2":1,"24":1,"36":1,"38":1}}],["had",{"2":{"5":1}}],["handling",{"2":{"1":1}}],["handled",{"2":{"1":1}}],["handle",{"2":{"1":3,"23":2,"45":1}}],["habitat",{"2":{"1":1}}],["habitatheterogeneity",{"2":{"1":7,"37":2}}],["having",{"2":{"1":3}}],["have",{"2":{"1":13,"2":4,"8":1,"10":1,"11":3,"23":1,"26":1,"27":1,"40":1,"42":1}}],["haschunks",{"2":{"2":1}}],["has",{"2":{"1":10,"14":1,"34":1,"40":2}}],["hdf5",{"2":{"1":1,"2":1,"13":1,"14":1,"26":1}}],["j",{"2":{"37":2}}],["json3",{"2":{"16":2}}],["january",{"2":{"1":3,"36":1}}],["join",{"2":{"1":1,"28":1}}],["joined",{"2":{"1":2}}],["just",{"2":{"1":4,"2":2,"3":1,"24":1,"26":1,"27":2,"34":1}}],["julianorway",{"2":{"46":2}}],["julianp",{"2":{"46":1}}],["julianewstack",{"2":{"4":1}}],["juliadp",{"2":{"46":1}}],["juliadisaggregate",{"2":{"1":2}}],["juliafunction",{"2":{"46":1}}],["juliafig",{"2":{"33":1}}],["juliafilearray",{"2":{"2":1}}],["juliafilestack",{"2":{"2":1}}],["juliafiles",{"2":{"1":1}}],["juliawrite",{"2":{"42":1,"46":1}}],["juliawarp",{"2":{"1":1}}],["julialayers",{"2":{"37":1}}],["julialon",{"2":{"21":1}}],["juliaopen",{"2":{"2":1,"4":1}}],["juliaopenstack",{"2":{"2":1}}],["juliazonal",{"2":{"1":1}}],["juliatrim",{"2":{"1":1}}],["juliascandinavia",{"2":{"46":1}}],["juliasp",{"2":{"46":1}}],["juliashapes",{"2":{"45":1}}],["juliastack",{"2":{"34":1}}],["julias",{"2":{"2":3,"10":1}}],["juliaskipmissing",{"2":{"2":1}}],["juliaslice",{"2":{"1":1}}],["juliaset",{"2":{"8":1}}],["juliasetmappedcrs",{"2":{"1":1}}],["juliasetcrs",{"2":{"1":1}}],["juliaras",{"2":{"22":3,"23":1}}],["juliarasterdiskarray",{"2":{"2":1}}],["juliarasterize",{"2":{"1":2}}],["juliarasters",{"2":{"2":1,"36":1}}],["juliarasterstack",{"2":{"1":1}}],["juliarasterseries",{"2":{"1":2}}],["juliaraster",{"2":{"1":1}}],["juliarecords",{"2":{"16":1}}],["juliaread",{"2":{"2":2}}],["juliaresample",{"2":{"1":1}}],["juliareproject",{"2":{"1":2}}],["juliareplace",{"2":{"1":1,"7":1}}],["juliap",{"2":{"46":1}}],["juliapoints",{"2":{"1":1}}],["juliaprojected",{"2":{"1":1}}],["juliaextract",{"2":{"1":1}}],["juliaextend",{"2":{"1":1}}],["juliacheckmem",{"2":{"2":1}}],["juliacrop",{"2":{"1":1}}],["juliacrs",{"2":{"1":1}}],["juliacoords",{"2":{"17":1}}],["juliacoverage",{"2":{"1":2}}],["juliaconvertlookup",{"2":{"1":1}}],["juliacombine",{"2":{"1":1}}],["juliaclassify",{"2":{"1":2}}],["juliacellarea",{"2":{"1":1}}],["juliab",{"2":{"6":1}}],["juliabase",{"2":{"2":4}}],["juliabanddim",{"2":{"1":1}}],["juliaband",{"2":{"1":1}}],["juliaboolmask",{"2":{"1":1}}],["juliausing",{"2":{"1":21,"3":1,"8":1,"13":1,"15":1,"16":1,"18":3,"20":2,"24":1,"26":1,"33":1,"37":1,"38":1,"39":1,"40":3,"41":1,"44":1,"45":1}}],["juliaa",{"2":{"4":1,"6":1,"18":1,"40":1,"42":1}}],["juliaabstractprojected",{"2":{"2":1}}],["juliaabstractrasterstack",{"2":{"1":1}}],["juliaabstractrasterseries",{"2":{"1":1}}],["juliaabstractraster",{"2":{"1":1}}],["juliaaggregate",{"2":{"1":2}}],["juliamean",{"2":{"3":1}}],["juliamosaic",{"2":{"1":2}}],["juliamodify",{"2":{"1":1}}],["juliamissingval",{"2":{"1":1}}],["juliamissingmask",{"2":{"1":1}}],["juliamakie",{"2":{"34":1,"35":1,"36":2}}],["juliamask",{"2":{"1":2,"45":1}}],["juliamappedindex",{"2":{"1":1}}],["juliamappedcrs",{"2":{"1":1}}],["juliamappedbounds",{"2":{"1":1}}],["juliamapped",{"2":{"1":1}}],["juliajulia>",{"2":{"1":2}}],["juliagdalarray",{"2":{"1":1}}],["julia",{"2":{"1":1,"2":1,"20":1,"25":1,"26":1,"29":1,"37":1}}],["jl",{"0":{"15":1,"45":1,"46":1},"2":{"1":46,"2":4,"8":1,"9":1,"11":1,"12":1,"15":3,"17":1,"20":2,"23":1,"24":1,"26":1,"27":3,"36":1,"38":3,"40":2,"42":2,"43":1,"45":1,"46":1}}],["ignore",{"2":{"1":4,"2":2}}],["ignored",{"2":{"1":1,"2":1}}],["image",{"2":{"37":1}}],["imola",{"2":{"1":1}}],["improve",{"2":{"2":2}}],["implemented",{"2":{"1":1,"14":1}}],["implementation",{"2":{"1":2}}],["implementations",{"2":{"1":1}}],["import",{"2":{"1":1}}],["irregular",{"2":{"1":3}}],["i",{"2":{"1":2,"2":4,"18":1,"36":3,"37":6,"46":1}}],["ie",{"2":{"1":1}}],["if",{"2":{"1":77,"2":37,"3":1,"5":1,"6":1,"17":1,"21":2,"27":1,"31":1,"36":7,"38":1,"40":1,"46":1}}],["identically",{"2":{"1":1}}],["identical",{"2":{"1":4}}],["input",{"2":{"36":2}}],["inputs",{"2":{"1":1}}],["invoke",{"2":{"38":1}}],["involves",{"2":{"27":1}}],["invert",{"2":{"1":8}}],["info",{"2":{"24":1,"29":1}}],["information",{"2":{"1":3}}],["inf",{"2":{"3":4,"4":6}}],["indices",{"2":{"22":1,"24":2,"40":1}}],["indicates",{"2":{"2":1,"36":1}}],["individually",{"2":{"2":2}}],["individual",{"2":{"1":1,"2":1,"13":1,"46":1}}],["independently",{"2":{"1":1}}],["indexing",{"2":{"4":1}}],["indexed",{"2":{"1":3,"2":1,"3":1,"20":1}}],["index",{"0":{"0":1,"22":1},"2":{"1":19,"2":3,"22":1,"23":1,"24":4,"40":1}}],["indonesian",{"2":{"1":1}}],["indonesia",{"2":{"1":7}}],["installation",{"0":{"25":1}}],["install",{"0":{"20":1}}],["instead",{"2":{"1":5,"2":1,"8":1,"38":1,"40":2}}],["insertcols",{"2":{"1":1}}],["inside",{"2":{"1":18}}],["including",{"2":{"1":4}}],["includes",{"2":{"46":1}}],["included",{"2":{"1":4,"46":1}}],["include",{"2":{"1":9,"27":1}}],["increase",{"2":{"1":1}}],["increases",{"2":{"1":2}}],["incorrectly",{"2":{"5":1}}],["incorrect",{"2":{"1":6}}],["int16",{"2":{"45":2,"46":1}}],["int64",{"2":{"16":4,"20":2,"21":1,"22":6,"23":2}}],["into",{"2":{"1":12,"15":1,"27":1,"28":1,"29":1,"46":1}}],["intended",{"2":{"26":1}}],["integrated",{"2":{"15":1}}],["integration",{"0":{"15":1}}],["integer",{"2":{"1":6}}],["integers",{"2":{"1":5}}],["interpreted",{"2":{"34":1}}],["interpolation",{"2":{"1":1}}],["interface",{"2":{"34":1}}],["intervalsets",{"2":{"1":1}}],["intervals",{"2":{"1":3,"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"33":2,"37":2,"40":6,"45":4,"46":3}}],["interval",{"2":{"1":5,"22":1,"24":1,"40":2}}],["internal",{"0":{"2":1},"2":{"1":2,"2":3}}],["int",{"2":{"1":24,"2":9}}],["in",{"0":{"32":1,"33":1,"34":1},"2":{"1":176,"2":13,"4":1,"8":1,"11":2,"13":1,"14":3,"15":1,"17":2,"24":2,"26":3,"27":2,"28":1,"29":2,"31":1,"32":1,"34":3,"36":1,"37":4,"38":1,"40":5,"42":1,"43":1,"46":1}}],["inherit",{"2":{"1":1}}],["issue",{"2":{"27":3}}],["issues",{"2":{"1":19,"11":1,"27":3}}],["isn",{"2":{"27":1}}],["ismissing",{"2":{"17":1}}],["islands",{"2":{"1":6,"46":1}}],["island",{"2":{"1":2}}],["isfile",{"2":{"1":5}}],["is",{"2":{"1":217,"2":28,"3":2,"8":1,"11":2,"12":1,"13":1,"15":1,"20":1,"21":2,"22":1,"23":3,"24":2,"27":1,"31":1,"32":1,"33":2,"34":2,"36":2,"38":3,"42":1,"46":1}}],["itr",{"2":{"2":1}}],["iteratively",{"2":{"1":1}}],["iterator",{"2":{"1":2}}],["iterable",{"2":{"1":8,"2":1}}],["iterables",{"2":{"1":1}}],["it",{"2":{"1":51,"2":21,"8":1,"26":2,"27":7,"31":1,"34":1,"36":1,"38":1,"40":5,"46":1}}],["itself",{"2":{"1":1}}],["its",{"2":{"1":2,"2":1,"26":1,"27":1,"36":1}}],["wgs",{"2":{"3":6,"4":3,"6":3,"7":3,"8":6,"18":3,"33":3,"37":3,"45":6,"46":3}}],["www",{"2":{"2":2,"40":1}}],["wc2",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["wc",{"2":{"1":10}}],["well",{"2":{"26":1}}],["wellknowntext",{"2":{"1":1}}],["were",{"2":{"3":1,"14":1}}],["web",{"2":{"2":2,"27":1}}],["weighted",{"2":{"1":2}}],["wether",{"2":{"1":3}}],["we",{"2":{"1":6,"2":3,"3":1,"4":2,"8":2,"26":1,"27":9,"34":1,"38":1,"40":4,"42":1,"43":1,"45":2,"46":2}}],["wrong",{"2":{"2":1}}],["writing",{"0":{"14":1},"2":{"1":5,"2":6,"31":1}}],["written",{"2":{"1":7,"2":6,"14":2}}],["writes",{"2":{"2":2}}],["write=false",{"2":{"2":1}}],["write=true",{"2":{"1":2,"2":1,"4":1}}],["write",{"0":{"31":1,"42":1},"2":{"1":15,"2":24,"4":1,"14":2,"18":2,"31":2,"42":1,"46":3}}],["wrapping",{"2":{"2":4,"21":1}}],["wrapped",{"2":{"1":1,"2":1}}],["wrapper",{"2":{"1":2,"2":3}}],["wraper",{"2":{"1":1}}],["wrap",{"2":{"1":1}}],["worst",{"2":{"1":1}}],["world",{"2":{"1":2}}],["worldclim",{"2":{"1":20,"3":3,"4":1,"6":2,"7":1,"8":2,"15":1,"18":1,"24":1,"26":1,"33":2,"34":1,"36":2,"38":1,"39":1,"45":2}}],["works",{"2":{"3":1,"8":1,"32":1}}],["working",{"2":{"2":1,"27":1}}],["work",{"2":{"1":7,"2":2,"23":1,"24":1,"26":1,"27":1,"29":1,"33":1,"46":1}}],["would",{"2":{"1":2,"3":1}}],["way",{"2":{"1":3,"2":1,"24":1,"34":1,"38":1}}],["warned",{"2":{"1":1}}],["warnings",{"2":{"1":2}}],["warning",{"2":{"1":19,"34":1}}],["warped",{"2":{"1":2}}],["warp",{"2":{"0":1,"1":8,"28":1}}],["was",{"2":{"1":2,"26":2}}],["wind",{"2":{"45":5,"46":4}}],["windowed",{"2":{"1":1}}],["width=5",{"2":{"36":1}}],["width",{"2":{"2":1,"36":1,"37":5}}],["wish",{"2":{"2":1}}],["will",{"2":{"1":97,"2":22,"3":1,"4":1,"6":1,"8":3,"9":1,"11":1,"20":1,"23":1,"38":5,"40":2,"43":1,"46":2}}],["within",{"2":{"24":1}}],["with=poly",{"2":{"45":1}}],["with=maskfile",{"2":{"2":1}}],["with=wc",{"2":{"1":2}}],["without",{"2":{"1":6,"11":1,"13":1,"27":2}}],["with",{"0":{"36":1,"46":1},"2":{"1":83,"2":17,"3":2,"4":1,"6":1,"7":1,"8":3,"13":1,"14":1,"15":1,"20":1,"23":4,"24":1,"27":2,"32":1,"33":1,"36":1,"37":1,"38":2,"40":4,"43":1,"45":1,"46":3}}],["whose",{"2":{"2":1,"36":1}}],["whole",{"2":{"1":3}}],["whatever",{"2":{"1":1,"27":1}}],["whether",{"2":{"1":4,"2":3,"36":1}}],["wherever",{"2":{"1":2}}],["where",{"2":{"1":46,"2":1,"14":1,"23":2,"24":2,"26":1,"46":1}}],["when",{"2":{"1":66,"2":3,"3":2,"4":2,"26":1,"27":1,"42":1,"46":1}}],["while",{"2":{"1":1}}],["which",{"2":{"1":28,"2":6,"4":1,"8":1,"9":1,"10":1,"12":1,"34":3,"36":3,"38":1,"40":1,"46":1}}],["text",{"2":{"34":1}}],["template",{"2":{"27":2}}],["temperatures",{"2":{"40":1}}],["temperature",{"2":{"6":2,"13":1,"40":4,"42":1}}],["tempname",{"2":{"1":1}}],["tempfile",{"2":{"1":4}}],["tempory",{"2":{"1":1}}],["temp=",{"2":{"1":1}}],["temp",{"2":{"1":2}}],["typing",{"0":{"20":1}}],["typically",{"2":{"2":1}}],["typename",{"2":{"2":2}}],["types",{"2":{"2":3,"27":1,"46":1}}],["type",{"2":{"1":7,"2":8,"14":1,"36":3}}],["two",{"2":{"1":2,"24":1,"38":1}}],["twice",{"2":{"1":2}}],["tmax",{"2":{"1":3,"45":5,"46":4}}],["tmin",{"2":{"1":2,"45":5,"46":4}}],["t",{"2":{"1":3,"2":5,"8":1,"27":1,"40":2,"42":1}}],["target",{"2":{"1":1}}],["tavg",{"2":{"1":3,"15":1}}],["tabular",{"2":{"1":1}}],["table",{"0":{"30":1},"2":{"1":18,"16":1}}],["tables",{"2":{"1":18}}],["take",{"2":{"2":1,"24":1,"27":1,"36":1,"40":1,"46":1}}],["takes",{"2":{"1":2}}],["taken",{"2":{"1":4}}],["taking",{"2":{"1":3,"12":1}}],["tickalign",{"2":{"37":4}}],["tickalign=1",{"2":{"37":1}}],["ticks=false",{"2":{"37":2}}],["ticksize",{"2":{"37":5}}],["tiled",{"2":{"34":1,"38":1}}],["ti=at",{"2":{"23":1}}],["ti=1",{"2":{"22":1,"40":1}}],["tightly",{"2":{"15":1}}],["titles",{"2":{"2":1,"36":1}}],["title",{"2":{"2":1,"36":1,"37":1}}],["ti",{"2":{"1":7,"3":1,"11":1,"20":6,"22":4,"23":1,"40":5,"42":1}}],["tif",{"2":{"1":8,"3":2,"4":1,"6":1,"7":1,"8":2,"12":2,"33":1,"46":6}}],["tifs",{"2":{"1":1}}],["tiff",{"2":{"1":2,"2":4,"12":1}}],["timespan",{"2":{"40":1}}],["time",{"0":{"3":1},"2":{"1":4,"3":1,"20":1,"22":1,"23":1,"26":1,"27":2,"34":1,"40":4,"46":1}}],["trace",{"2":{"27":1}}],["transect",{"2":{"42":1}}],["transparent",{"2":{"2":2,"36":2,"37":2}}],["transformations",{"2":{"26":1}}],["transforming",{"2":{"1":1}}],["transferred",{"2":{"1":1}}],["tr",{"2":{"1":2}}],["trigger",{"2":{"27":1}}],["triggers",{"2":{"1":1,"27":1}}],["trims",{"2":{"28":1}}],["trimming",{"2":{"1":1}}],["trimmed",{"2":{"1":3,"37":1}}],["trim",{"2":{"0":1,"1":10,"28":1,"37":2,"45":7,"46":1}}],["try",{"2":{"1":1,"8":1}}],["true",{"2":{"1":38,"2":18,"16":1,"36":1}}],["treated",{"2":{"1":11,"23":1,"34":1}}],["tuples",{"2":{"1":3}}],["tuple",{"2":{"1":64,"2":6,"16":2,"17":2}}],["together",{"2":{"43":1}}],["tos",{"2":{"40":5,"41":1,"42":3}}],["toy",{"2":{"20":1}}],["top",{"2":{"2":1,"36":1}}],["touch",{"2":{"1":2}}],["touches=false",{"2":{"1":1}}],["touches",{"2":{"1":13}}],["tolerances",{"2":{"1":2}}],["tolerance",{"2":{"1":3}}],["to=b",{"2":{"1":1}}],["to=first",{"2":{"1":1}}],["to=awap",{"2":{"1":2}}],["to=rnge",{"2":{"1":1}}],["to=shp",{"2":{"1":1}}],["to=nz",{"2":{"1":1}}],["total",{"2":{"1":2}}],["to",{"0":{"14":1,"31":1,"42":1},"2":{"1":320,"2":57,"3":1,"4":5,"5":1,"6":1,"8":6,"9":2,"11":1,"14":2,"15":2,"17":1,"18":3,"20":2,"23":4,"24":4,"26":5,"27":9,"28":5,"31":5,"32":1,"34":1,"36":8,"37":1,"38":4,"40":4,"42":1,"43":1,"46":5}}],["things",{"2":{"2":1}}],["third",{"2":{"1":2,"2":1,"36":1,"40":1}}],["this",{"2":{"1":64,"2":9,"4":1,"8":1,"20":2,"26":2,"27":1,"33":1,"34":2,"36":4,"38":1,"40":1,"43":1}}],["three",{"2":{"27":1}}],["thread",{"2":{"1":4}}],["threadsafe=true",{"2":{"1":1}}],["threadsafe",{"2":{"1":7}}],["threading",{"2":{"1":6}}],["threaded=false",{"2":{"1":1}}],["threaded",{"2":{"1":20}}],["through",{"2":{"1":1,"2":1,"28":1}}],["than",{"2":{"1":7,"14":2,"32":1,"40":1}}],["that",{"0":{"28":1,"29":1},"2":{"1":64,"2":9,"5":1,"8":2,"11":1,"14":1,"15":1,"20":1,"27":7,"29":1,"34":1,"36":1,"40":1,"46":1}}],["then",{"2":{"1":2,"2":1,"3":1,"6":1,"18":1,"20":1,"27":2,"36":1,"40":1,"43":1,"45":2}}],["theme",{"0":{"35":1},"1":{"36":1,"37":1},"2":{"34":3,"35":1,"36":4,"37":2}}],["theming",{"2":{"34":1}}],["themselves",{"2":{"2":1}}],["them",{"2":{"1":5,"2":1,"18":1,"23":1,"27":2,"46":1}}],["there",{"2":{"1":6,"2":1,"27":3,"46":1}}],["these",{"2":{"1":13,"2":2,"12":1,"13":1,"23":1,"29":1,"36":1,"46":2}}],["their",{"2":{"1":1,"45":1}}],["they",{"2":{"1":6,"2":1,"10":2,"14":2,"23":1,"27":2}}],["the",{"0":{"3":1,"20":1,"21":1,"28":1,"44":1},"1":{"45":1,"46":1},"2":{"1":508,"2":114,"3":2,"4":4,"5":2,"6":3,"8":4,"11":3,"12":2,"13":2,"14":1,"15":4,"17":1,"20":2,"22":1,"23":4,"24":13,"26":2,"27":14,"28":4,"31":2,"32":1,"34":1,"36":42,"37":2,"38":7,"40":10,"42":3,"43":2,"45":2,"46":6}}],["ocean",{"2":{"40":1,"42":1}}],["occurs",{"2":{"4":1}}],["occurrence",{"2":{"1":3,"16":2,"18":1}}],["occur",{"2":{"1":24,"27":1}}],["o1",{"2":{"40":2}}],["o",{"2":{"4":2}}],["omitted",{"2":{"1":1,"16":1}}],["obtain",{"2":{"1":1,"38":1}}],["observable",{"2":{"36":2}}],["observables",{"0":{"36":1}}],["observation",{"2":{"1":1}}],["obs",{"2":{"1":2,"36":3}}],["obj",{"2":{"1":10}}],["object",{"0":{"5":1,"24":1,"28":1},"1":{"6":1,"7":1,"8":1},"2":{"1":41,"2":10,"5":2,"8":1,"16":1,"24":1,"28":4,"29":2,"30":1,"42":1}}],["objects",{"0":{"29":1},"2":{"1":17,"2":5,"8":1,"24":2,"28":2,"31":3,"40":2}}],["our",{"2":{"1":1,"27":1,"40":1}}],["outside",{"2":{"1":2}}],["output",{"2":{"1":29,"20":1}}],["out",{"2":{"1":6,"36":1,"37":1,"46":1}}],["opacity=0",{"2":{"18":1}}],["op",{"2":{"1":5}}],["optionally",{"2":{"1":1}}],["options",{"2":{"1":1,"2":6,"23":1}}],["optimisations",{"2":{"1":3}}],["opbject",{"2":{"1":1}}],["operation",{"0":{"30":1},"2":{"1":8,"2":1}}],["operations",{"2":{"1":5,"2":1,"11":1}}],["opens",{"2":{"2":1}}],["openstack",{"2":{"0":1,"2":3}}],["openinterval",{"2":{"1":1}}],["open",{"2":{"1":6,"2":11,"4":1,"31":2}}],["opened",{"2":{"1":3,"2":3}}],["otherwise",{"2":{"1":10,"11":1}}],["others=0",{"2":{"1":2}}],["others=nothing",{"2":{"1":1}}],["others",{"2":{"1":9}}],["other",{"2":{"1":20,"2":8,"13":1,"14":1,"23":1,"24":1,"26":1,"27":1,"29":1,"34":1,"40":2,"46":1}}],["overridden",{"2":{"2":1}}],["overlap",{"2":{"1":2,"46":1}}],["overlapping",{"2":{"1":2}}],["over",{"0":{"3":1},"2":{"1":12,"2":1,"3":2,"4":1,"27":1,"40":1,"46":1}}],["onwards",{"2":{"26":1}}],["one",{"2":{"1":9,"2":4,"8":2,"40":3}}],["on",{"2":{"1":27,"2":5,"8":1,"15":1,"18":1,"23":1,"24":1,"26":1,"27":3,"28":1,"31":1,"36":2,"38":3,"40":2}}],["only",{"2":{"1":29,"2":5,"3":1,"4":1,"8":1,"26":1,"38":1,"40":2}}],["offset",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["of=countries",{"2":{"1":1}}],["often",{"2":{"1":9,"2":1,"27":1}}],["of",{"0":{"28":1},"2":{"1":225,"2":50,"3":2,"4":2,"5":1,"6":2,"7":1,"8":5,"9":1,"13":1,"15":1,"17":1,"22":1,"23":1,"24":3,"27":4,"28":3,"33":1,"34":1,"36":20,"37":1,"38":2,"40":4,"42":1,"46":3}}],["org",{"2":{"2":4}}],["original",{"2":{"1":4,"2":3,"40":4}}],["order=autoorder",{"2":{"1":2}}],["order",{"2":{"1":14}}],["or",{"0":{"28":1},"2":{"1":295,"2":35,"4":1,"5":1,"6":1,"14":1,"15":1,"18":1,"20":1,"22":2,"26":1,"27":4,"28":5,"29":2,"30":1,"31":1,"32":1,"34":1,"36":8,"38":2,"42":1}}],["flipaxis",{"2":{"37":3}}],["fletcher32",{"2":{"2":2}}],["flexible",{"2":{"1":1}}],["flag",{"2":{"1":1}}],["flags",{"2":{"1":4}}],["float",{"2":{"1":2}}],["floating",{"2":{"1":5}}],["float32",{"2":{"1":5,"3":2,"4":1,"6":1,"7":1,"8":2,"18":4,"33":1,"40":2,"45":6,"46":3}}],["float64",{"2":{"1":8,"3":7,"4":4,"6":4,"7":4,"8":8,"16":2,"17":2,"18":4,"20":1,"22":3,"23":1,"33":4,"37":4,"40":4,"45":8,"46":2}}],["framerate",{"2":{"36":1}}],["fraction",{"2":{"1":2}}],["from",{"0":{"21":1},"2":{"1":67,"2":14,"3":1,"8":1,"11":2,"12":1,"23":1,"24":1,"26":1,"30":1,"31":1,"36":1,"40":1,"45":1,"46":1}}],["features",{"2":{"1":2}}],["feature",{"2":{"1":24}}],["f",{"2":{"1":15,"2":3,"24":1}}],["fully",{"2":{"1":1,"38":1}}],["functionality",{"2":{"26":2}}],["function",{"2":{"1":17,"2":1,"3":1,"4":1,"24":2,"27":1,"28":1,"32":1,"38":3,"46":2}}],["functions",{"0":{"1":1,"2":1},"2":{"1":10,"38":1,"40":1}}],["future",{"2":{"1":21}}],["fast",{"2":{"10":1}}],["fastest",{"2":{"1":1}}],["faster",{"2":{"1":9}}],["fall",{"2":{"40":1}}],["falls",{"2":{"24":1}}],["fallback",{"2":{"2":2,"42":1}}],["falling",{"2":{"1":1}}],["false",{"2":{"1":25,"2":11,"37":1}}],["fail",{"2":{"1":1}}],["factor",{"2":{"1":4}}],["facilitate",{"2":{"1":1}}],["following",{"2":{"20":1}}],["focus",{"2":{"15":1}}],["fo",{"2":{"1":1}}],["found",{"2":{"1":2,"2":2}}],["forward",{"2":{"38":1}}],["forwardordered",{"2":{"1":4,"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"20":3,"21":1,"22":7,"23":2,"33":1,"37":1,"40":6,"45":2,"46":1}}],["foreach",{"2":{"18":1}}],["form",{"2":{"1":1}}],["formats",{"0":{"14":1},"2":{"14":3}}],["format",{"2":{"1":3,"13":1}}],["forced",{"2":{"2":1}}],["force",{"2":{"1":10,"2":15}}],["for",{"2":{"1":138,"2":25,"4":1,"9":1,"11":1,"13":2,"14":2,"15":3,"17":1,"23":2,"26":3,"27":3,"28":3,"29":1,"30":1,"31":1,"32":1,"34":1,"36":6,"37":4,"38":4,"42":1,"46":3}}],["figure",{"2":{"37":3}}],["fig",{"2":{"33":4,"36":2,"37":10}}],["fixing",{"2":{"27":1}}],["fixed",{"2":{"27":1}}],["fix",{"2":{"27":3}}],["fix2",{"2":{"1":9}}],["finally",{"2":{"26":1}}],["find",{"2":{"24":1,"27":1}}],["finished",{"2":{"26":1}}],["finish",{"2":{"2":1}}],["field",{"2":{"1":1,"8":1}}],["fields",{"2":{"1":6,"5":1}}],["filter",{"2":{"2":2,"24":1}}],["filled",{"2":{"38":1,"40":1}}],["fillvalue",{"2":{"2":3,"40":2}}],["fillalpha=0",{"2":{"1":2,"46":1}}],["fill=1",{"2":{"1":2}}],["fill",{"2":{"1":12}}],["fills",{"2":{"1":2}}],["filepaths",{"2":{"1":1}}],["filepath",{"2":{"1":6,"2":6,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["file",{"0":{"14":1},"2":{"1":45,"2":23,"4":1,"5":1,"11":2,"14":1,"27":7,"28":1,"31":1,"40":2,"46":3}}],["files",{"2":{"1":18,"2":7,"5":1,"10":1,"11":3,"12":2,"14":1,"20":1,"26":1,"27":1,"38":1,"43":1}}],["filestack",{"2":{"0":1,"2":2}}],["filenames",{"2":{"1":5}}],["filename",{"2":{"1":34,"2":20,"4":1,"11":2,"12":2,"13":2,"14":1,"40":2}}],["filearray",{"2":{"0":1,"1":2,"2":3}}],["fit",{"2":{"1":1}}],["first",{"2":{"1":22,"11":1,"13":1,"27":1,"40":3,"43":1,"46":4}}],["sweden",{"2":{"45":4,"46":5}}],["swapping",{"2":{"1":1}}],["squished",{"2":{"34":1}}],["square",{"2":{"1":7}}],["smaller",{"2":{"34":1}}],["smallest",{"2":{"1":2}}],["smapseries",{"2":{"13":1}}],["smap",{"0":{"13":1},"2":{"14":1,"26":1}}],["sciences",{"2":{"15":1}}],["screen",{"2":{"37":1}}],["scr",{"2":{"2":1}}],["scandinavia",{"2":{"46":10}}],["scandinavian",{"2":{"43":1}}],["scatter",{"2":{"18":2}}],["scarborough",{"2":{"1":1}}],["scale^2",{"2":{"1":2}}],["scale",{"2":{"1":27,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["snap",{"2":{"1":1,"28":1}}],["skewed",{"2":{"1":1}}],["skipping",{"2":{"2":1}}],["skipped",{"2":{"1":2}}],["skip",{"2":{"1":1}}],["skipmissing=true",{"2":{"1":1}}],["skipmissingval=false",{"2":{"1":1}}],["skipmissingval=true",{"2":{"1":1}}],["skipmissingval",{"2":{"1":2}}],["skipmissing",{"2":{"1":4,"2":1}}],["slow",{"2":{"1":1}}],["slicing",{"2":{"1":1}}],["slices",{"2":{"1":3}}],["sliced",{"2":{"1":5,"40":1}}],["slice",{"2":{"0":1,"1":6,"22":1}}],["src",{"2":{"1":10,"2":4}}],["s",{"2":{"1":11,"2":7,"8":1,"13":1,"24":2,"27":1}}],["system",{"2":{"1":10,"32":1}}],["symbols",{"2":{"2":1,"36":1}}],["symbol",{"2":{"1":32,"2":6}}],["syntax",{"2":{"1":2,"15":1,"22":1,"46":1}}],["safe",{"2":{"1":4,"2":1}}],["sa",{"2":{"1":6}}],["saved",{"2":{"2":2}}],["savefig",{"2":{"1":24}}],["save",{"2":{"1":3,"2":2,"37":1,"40":1,"46":1}}],["sample",{"2":{"1":4}}],["sampled",{"2":{"1":6,"20":3,"21":1,"22":7,"23":2,"40":2}}],["sampling=intervals",{"2":{"1":4}}],["sampling=autosampling",{"2":{"1":2}}],["sampling",{"2":{"1":2}}],["same",{"2":{"1":11,"5":1,"11":1,"27":1,"28":1,"36":2,"46":1}}],["sure",{"2":{"27":2,"38":1}}],["surface",{"2":{"2":1,"32":2,"33":1,"36":1,"38":2,"40":4,"42":1}}],["subtle",{"2":{"27":2}}],["subplot=i",{"2":{"18":1,"46":1}}],["subplots",{"2":{"18":1,"46":1}}],["subarray",{"2":{"16":1}}],["substrin",{"2":{"1":1}}],["subsetting",{"0":{"24":1}}],["subset",{"2":{"1":1,"18":1,"23":1,"24":1}}],["subdivision",{"2":{"1":2}}],["summed",{"2":{"1":2}}],["sum",{"2":{"1":23}}],["suffix",{"2":{"1":19,"2":2}}],["such",{"2":{"1":11,"2":5,"12":1,"29":1}}],["supports",{"2":{"38":1}}],["supported",{"2":{"38":1}}],["support",{"2":{"36":1}}],["supplied",{"2":{"1":1}}],["supertype",{"2":{"1":3,"2":1}}],["sosstsst",{"2":{"40":2}}],["soil",{"2":{"13":2}}],["software",{"2":{"2":2,"40":1}}],["sovereign",{"2":{"1":1}}],["south",{"2":{"1":1,"18":1}}],["sources",{"0":{"9":1,"31":1},"1":{"10":1,"11":1,"12":1,"13":1,"14":1,"15":1},"2":{"1":2,"15":2,"26":1}}],["source",{"2":{"1":58,"2":27,"36":1}}],["so",{"2":{"1":11,"2":1,"8":1,"15":1,"20":1,"26":1,"27":4,"33":1,"40":1,"42":1}}],["somewhat",{"2":{"32":1}}],["something",{"2":{"20":1}}],["somelayer",{"2":{"1":2}}],["some",{"2":{"1":16,"2":1,"11":1,"14":2,"27":2,"34":1,"45":1}}],["side",{"2":{"2":1,"36":1}}],["sides",{"2":{"1":1}}],["since",{"2":{"1":1,"32":1,"38":1}}],["sinc",{"2":{"1":1}}],["singleton",{"2":{"2":1,"36":1}}],["single",{"2":{"1":37,"2":3,"28":1,"43":1,"46":2}}],["silently",{"2":{"1":1}}],["size=",{"2":{"37":1,"41":1}}],["sizes",{"2":{"2":1,"28":2}}],["size",{"2":{"1":32,"2":10,"18":4,"28":1,"37":4,"45":8,"46":4}}],["sized",{"2":{"1":1}}],["simple",{"0":{"38":1,"39":1},"2":{"1":5}}],["simply",{"2":{"1":3,"40":1}}],["similarly",{"2":{"28":1,"38":1}}],["similar",{"2":{"1":1,"20":1,"38":1}}],["still",{"2":{"11":1,"40":1}}],["store",{"2":{"14":1}}],["stored",{"2":{"1":1,"2":4}}],["stores",{"2":{"1":1}}],["steps",{"2":{"1":1,"27":1}}],["stem",{"2":{"1":1}}],["st",{"2":{"1":16,"37":2}}],["stats",{"2":{"1":2}}],["statistics",{"2":{"1":9,"3":1,"30":1,"40":1}}],["stage",{"2":{"1":1}}],["start",{"0":{"19":1},"1":{"20":1,"21":1,"22":1,"23":1,"24":1},"2":{"1":12,"3":4,"4":2,"6":2,"7":2,"8":3,"18":2,"33":2,"37":2,"45":4,"46":2}}],["stack",{"2":{"1":33,"2":7,"4":2,"27":1,"28":2,"34":2,"36":4,"46":1}}],["stacks",{"2":{"1":8}}],["standardises",{"2":{"15":1}}],["standard",{"2":{"1":1,"29":1,"40":2}}],["strings",{"2":{"1":1,"2":1,"36":1}}],["string",{"2":{"1":23,"2":9,"3":2,"4":1,"6":1,"7":1,"8":2,"16":2,"33":1,"37":1,"40":2}}],["structures",{"2":{"1":1}}],["sp",{"2":{"46":1}}],["spratly",{"2":{"1":1}}],["spring",{"2":{"1":2}}],["spread",{"2":{"1":1}}],["spheroid",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["spherical",{"2":{"1":2}}],["sphere",{"2":{"1":2}}],["speed",{"2":{"1":1}}],["speedups",{"2":{"1":5}}],["special",{"2":{"1":2}}],["species",{"2":{"1":4}}],["specify",{"2":{"1":3,"2":5,"8":2,"15":1,"23":1}}],["specifying",{"2":{"1":4,"2":3}}],["specific",{"2":{"2":7,"8":1,"26":1,"28":2}}],["specifically",{"2":{"1":1}}],["specifies",{"2":{"1":2,"38":1}}],["specified",{"2":{"1":14,"5":1}}],["spline",{"2":{"1":1}}],["split",{"2":{"1":2}}],["splat",{"2":{"1":1}}],["splatted",{"2":{"1":2}}],["space",{"2":{"1":1,"24":1,"34":1}}],["spans",{"2":{"1":1,"23":1}}],["span=autospan",{"2":{"1":2}}],["span",{"2":{"1":2}}],["spatial",{"2":{"1":6,"14":1,"20":2,"23":1,"42":1}}],["shrink",{"2":{"28":1}}],["shuffle",{"2":{"2":4}}],["shp",{"2":{"1":15,"44":2}}],["shapes",{"2":{"1":6,"45":6}}],["shapefile",{"0":{"44":1,"45":1},"1":{"45":1,"46":1},"2":{"1":31,"43":1,"44":5,"45":2}}],["shape=",{"2":{"1":1}}],["shape",{"2":{"1":9,"43":1,"46":1}}],["sharing",{"2":{"1":1}}],["shared",{"2":{"1":4}}],["share",{"2":{"1":2,"27":1}}],["shoudle",{"2":{"1":1}}],["should",{"2":{"1":15,"2":2,"36":3}}],["shortcuts",{"2":{"1":2}}],["show",{"2":{"1":10,"38":1}}],["shown",{"2":{"1":1,"38":1}}],["sea",{"2":{"40":4}}],["search",{"2":{"1":1,"16":1}}],["second",{"2":{"26":1}}],["seconds",{"2":{"26":1}}],["se",{"2":{"18":3}}],["separated",{"2":{"1":1,"2":1}}],["separately",{"2":{"1":3}}],["separator",{"2":{"1":3}}],["seem",{"2":{"34":1}}],["seems",{"2":{"1":1}}],["see",{"2":{"1":3,"14":1,"15":1,"23":1}}],["serranilla",{"2":{"1":1}}],["ser",{"2":{"1":2}}],["series",{"2":{"1":19,"2":2,"34":1}}],["sense",{"2":{"1":1}}],["selecting",{"2":{"22":1}}],["selects",{"2":{"1":6}}],["select",{"0":{"22":1,"23":1},"2":{"1":12}}],["selectors",{"2":{"1":1,"24":3}}],["selector",{"2":{"1":10,"24":1}}],["sets",{"2":{"2":1,"36":1}}],["setting",{"2":{"2":1}}],["set",{"0":{"8":1},"2":{"1":14,"2":10,"8":6,"34":1,"35":1,"36":8,"38":1}}],["setmappedcrs",{"2":{"0":1,"1":2,"8":1}}],["setcrs",{"2":{"0":1,"1":2,"8":1}}],["rs",{"2":{"16":1,"18":1,"24":1}}],["right",{"2":{"2":2,"27":1,"36":2}}],["rings",{"2":{"1":1}}],["r",{"2":{"1":3,"2":2,"10":1,"17":4}}],["rms",{"2":{"1":1}}],["root",{"2":{"1":1}}],["rotated",{"2":{"1":1}}],["roughly",{"2":{"1":3,"37":1}}],["rowgap",{"2":{"37":1}}],["rows",{"2":{"1":3,"16":1}}],["row",{"2":{"1":3}}],["rnge",{"2":{"1":3}}],["ras",{"2":{"20":1,"21":2}}],["rasterisation",{"2":{"1":2}}],["rasterized",{"2":{"1":2}}],["rasterize",{"2":{"0":2,"1":10,"30":2}}],["rasterdatasources",{"0":{"15":1},"2":{"1":21,"3":1,"15":4,"16":1,"24":1,"26":2,"33":1,"37":1,"38":1,"39":1,"43":1,"45":2}}],["rasterdiskarray",{"2":{"0":1,"2":2}}],["raster",{"2":{"0":1,"1":109,"2":32,"3":6,"4":6,"6":3,"7":2,"8":4,"9":2,"11":1,"12":1,"13":1,"15":4,"18":1,"20":3,"22":6,"23":2,"24":1,"26":1,"27":2,"29":1,"32":1,"33":4,"36":11,"37":1,"38":4,"39":1,"40":5,"45":3,"46":3}}],["rasterstacks",{"2":{"1":2,"34":1,"38":1,"46":1}}],["rasterstack",{"2":{"0":1,"1":57,"2":7,"4":1,"9":1,"11":1,"12":1,"13":1,"15":2,"18":2,"34":1,"36":5,"37":3,"38":1,"40":1,"45":3,"46":1}}],["rasterseries",{"2":{"0":1,"1":22,"9":1,"15":2,"46":1}}],["rasters",{"0":{"33":1,"34":1},"2":{"0":56,"1":106,"2":22,"3":3,"4":1,"6":1,"7":1,"8":3,"9":1,"13":1,"15":2,"16":3,"20":5,"23":2,"24":2,"25":1,"26":5,"27":3,"28":1,"33":2,"34":8,"36":6,"37":2,"38":5,"39":1,"40":3,"42":1,"43":1,"45":2,"46":1}}],["ratio",{"2":{"2":2}}],["rather",{"2":{"1":1}}],["raw",{"2":{"1":4,"44":1}}],["range",{"2":{"1":13,"37":3,"46":1}}],["random",{"2":{"20":1,"42":1}}],["rand",{"2":{"1":1,"20":1}}],["radius",{"2":{"1":4}}],["race",{"2":{"1":5}}],["runs",{"2":{"27":1}}],["running",{"2":{"1":4,"27":1}}],["run",{"2":{"1":8}}],["rplot",{"2":{"0":2,"2":2,"34":3,"36":6,"38":1}}],["re",{"2":{"38":1}}],["remain",{"2":{"36":2}}],["record",{"2":{"36":1}}],["records",{"2":{"17":1}}],["recipes",{"2":{"38":1,"42":1}}],["recipe",{"2":{"32":1}}],["reverseordered",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["reversing",{"2":{"1":1}}],["reef",{"2":{"1":1}}],["reduced",{"2":{"26":1}}],["reduces",{"2":{"1":1}}],["reduce",{"2":{"1":2,"27":1}}],["reducer",{"2":{"1":9}}],["reducing",{"2":{"1":5}}],["region",{"2":{"1":1,"46":3}}],["regions",{"2":{"1":12}}],["regular",{"2":{"1":6,"2":1,"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"20":3,"21":1,"22":7,"23":2,"24":1,"29":1,"33":2,"37":2,"40":5,"45":4,"46":2}}],["related",{"2":{"13":1}}],["reliable",{"2":{"1":19}}],["relhum",{"2":{"1":2}}],["relhum=",{"2":{"1":1}}],["reason",{"2":{"34":1}}],["reassign",{"2":{"8":1}}],["really",{"2":{"27":1}}],["real",{"2":{"1":18}}],["reading",{"2":{"31":1}}],["reads",{"2":{"24":1}}],["read",{"2":{"1":13,"2":9,"4":1,"11":1,"20":1,"31":4,"46":1}}],["rebuild",{"0":{"6":1},"2":{"1":1,"5":1,"6":3,"8":1}}],["res=3000",{"2":{"38":1}}],["res=0",{"2":{"1":1}}],["reset",{"0":{"35":1},"1":{"36":1,"37":1},"2":{"36":1}}],["responsible",{"2":{"1":1}}],["resampling",{"2":{"1":17}}],["resamples",{"2":{"1":1}}],["resampled",{"2":{"1":1}}],["resample",{"2":{"0":1,"1":15,"28":2}}],["result",{"2":{"1":6}}],["results",{"2":{"1":6}}],["resulting",{"2":{"1":6}}],["resolution",{"0":{"28":1},"2":{"1":19,"38":3}}],["res",{"2":{"1":21,"38":1}}],["rest",{"2":{"1":1}}],["refer",{"2":{"1":1}}],["reference",{"0":{"1":1,"2":1},"2":{"1":11}}],["refdims",{"2":{"1":5}}],["retrieved",{"2":{"2":2}}],["retrieve",{"2":{"1":3,"2":1}}],["returning",{"2":{"1":2}}],["returned",{"2":{"1":14}}],["returns",{"2":{"1":8,"2":5}}],["return",{"2":{"1":7,"46":1}}],["required",{"2":{"1":24,"2":2,"29":1}}],["reports",{"2":{"27":1}}],["reporting",{"2":{"2":1}}],["reproduced",{"2":{"27":1}}],["reproduce",{"2":{"27":1}}],["reprojecting",{"2":{"1":1}}],["reproject",{"2":{"0":2,"1":6}}],["represent",{"2":{"1":1,"23":2}}],["representing",{"2":{"1":1}}],["reprsenting",{"2":{"1":1}}],["replaced",{"2":{"1":1,"2":1}}],["replacement",{"2":{"1":6}}],["replace",{"0":{"7":1},"2":{"0":1,"1":17,"6":2,"29":3,"31":1}}],["px",{"2":{"39":1}}],["put",{"2":{"26":1,"27":1}}],["phylum",{"2":{"16":1}}],["p",{"2":{"1":4,"18":3,"46":8}}],["pygmy",{"2":{"1":1}}],["per",{"2":{"39":1}}],["peru",{"2":{"1":1}}],["performance",{"2":{"1":4}}],["permission",{"2":{"1":1}}],["permissions",{"2":{"1":1}}],["plt",{"2":{"37":5}}],["platform",{"2":{"27":1}}],["plane",{"2":{"1":1}}],["planar",{"2":{"1":2}}],["places",{"2":{"27":1}}],["placed",{"2":{"2":1,"36":1}}],["place",{"2":{"1":6,"27":1}}],["please",{"2":{"1":19}}],["plotted",{"2":{"34":1}}],["plotting",{"0":{"32":1,"36":1,"46":1},"2":{"2":2,"32":1,"36":2,"38":2,"40":1,"42":1}}],["plottype",{"2":{"2":1,"36":1}}],["plot`",{"2":{"1":1}}],["plots",{"0":{"38":1,"46":1},"2":{"1":20,"18":1,"26":1,"32":1,"34":2,"38":4,"40":3,"41":2,"43":1,"46":1}}],["plot",{"0":{"41":2,"43":1},"2":{"1":39,"2":3,"15":1,"18":2,"24":1,"32":1,"33":2,"36":3,"37":1,"38":7,"39":1,"40":8,"42":3,"43":1,"46":9}}],["pixelated",{"2":{"1":1}}],["pixel",{"2":{"1":18,"38":2,"45":1}}],["pixels",{"2":{"1":15}}],["png",{"2":{"1":24,"37":1}}],["principle",{"2":{"8":1}}],["print",{"2":{"1":4,"2":2}}],["primem",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"33":1,"37":1,"45":2,"46":1}}],["practically",{"2":{"27":1}}],["practice",{"2":{"1":2,"2":1,"36":1}}],["practise",{"2":{"1":1}}],["predefined",{"2":{"31":1}}],["predictor",{"2":{"18":1}}],["predictors",{"2":{"18":6}}],["previously",{"2":{"26":1}}],["prefer",{"2":{"1":1}}],["prec",{"2":{"1":8,"45":5,"46":4}}],["pressure",{"2":{"1":1}}],["pressure=",{"2":{"1":1}}],["present",{"2":{"1":2}}],["problem",{"2":{"27":2}}],["problems",{"2":{"1":23,"2":2}}],["providing",{"2":{"14":1}}],["provide",{"2":{"34":1}}],["provides",{"2":{"13":1,"46":1}}],["provided",{"2":{"1":6,"38":1}}],["prod",{"2":{"1":1}}],["produces",{"2":{"27":1}}],["produce",{"2":{"1":2,"40":1}}],["productive",{"2":{"1":5}}],["properties",{"0":{"5":1},"1":{"6":1,"7":1,"8":1},"2":{"1":3,"8":2,"23":1}}],["progress=false",{"2":{"1":4}}],["progress",{"2":{"1":22}}],["projections",{"2":{"1":5,"23":1}}],["projection",{"2":{"1":6,"23":2,"28":1}}],["projected",{"2":{"0":1,"1":16,"2":1,"3":4,"4":2,"6":2,"7":2,"8":4,"18":2,"23":1,"33":2,"37":2,"45":4,"46":2}}],["pane",{"2":{"40":1}}],["paste",{"2":{"27":1}}],["passive",{"2":{"13":1}}],["passing",{"2":{"1":3}}],["passes",{"2":{"1":1}}],["passed",{"2":{"1":25,"2":12,"24":2}}],["pass",{"2":{"1":3,"2":1,"32":1,"34":1}}],["packages",{"0":{"26":1},"2":{"26":4}}],["package",{"0":{"20":1},"2":{"26":2}}],["pad=10",{"2":{"45":1}}],["padding",{"2":{"1":1,"2":2,"36":2}}],["padded",{"2":{"1":1}}],["pad",{"2":{"1":3,"45":1}}],["pair",{"2":{"1":2}}],["pairs",{"2":{"1":16}}],["part",{"2":{"27":1}}],["parvus",{"2":{"1":2,"16":1,"18":2}}],["parallel",{"2":{"1":5}}],["parse",{"2":{"1":1}}],["parsed",{"2":{"1":1}}],["path",{"2":{"1":7,"2":3}}],["paths",{"2":{"1":6}}],["poly",{"2":{"45":1,"46":2}}],["polygons",{"2":{"1":15,"43":1}}],["polygon",{"0":{"30":1,"43":1},"2":{"1":37,"29":1,"45":1}}],["poor",{"2":{"1":1}}],["potential",{"2":{"1":2,"2":2}}],["pointer",{"2":{"2":1}}],["point",{"0":{"30":1},"2":{"1":27,"17":1}}],["points",{"2":{"0":1,"1":43,"8":4,"17":1,"18":1,"20":3,"21":1,"22":7,"23":2,"30":2}}],["possibly",{"2":{"5":1}}],["possible",{"2":{"1":9,"3":1,"20":1,"26":1,"27":2}}],["possum",{"2":{"1":1}}],["positive",{"2":{"1":2}}],["position",{"2":{"1":1,"2":2,"36":2}}],["mp4",{"2":{"36":2}}],["mmap",{"2":{"10":1}}],["my",{"2":{"1":2}}],["myraster",{"2":{"1":2}}],["myseries",{"2":{"1":3}}],["month",{"2":{"16":1,"20":2,"22":1,"34":1,"36":1,"40":2}}],["month=july",{"2":{"45":1}}],["month=june",{"2":{"15":1}}],["month=jan",{"2":{"1":1}}],["month=6",{"2":{"1":1}}],["month=1",{"2":{"1":11}}],["moisture",{"2":{"13":2}}],["move",{"2":{"2":1,"31":1}}],["mountain",{"2":{"1":1}}],["more",{"2":{"1":5,"8":1,"23":2,"28":1,"40":1}}],["modification",{"2":{"1":1}}],["modifying",{"0":{"5":1},"1":{"6":1,"7":1,"8":1}}],["modify",{"0":{"31":1},"2":{"1":1,"5":1,"8":1,"31":1}}],["model",{"2":{"1":1}}],["mode=",{"2":{"1":2}}],["mode",{"2":{"1":15,"4":1}}],["mos",{"2":{"1":2}}],["most",{"2":{"1":4,"27":1,"29":1}}],["mosaic",{"0":{"43":1},"2":{"0":2,"1":15,"28":1,"43":1,"46":2}}],["millisecond",{"2":{"40":1}}],["minutes",{"2":{"40":2}}],["min",{"2":{"1":3}}],["minimum",{"2":{"1":7,"27":1}}],["minor",{"2":{"1":2}}],["mix",{"2":{"1":1}}],["mixed",{"2":{"1":7}}],["missing=false",{"2":{"1":2}}],["missing",{"0":{"7":1},"2":{"0":1,"1":51,"2":7,"5":1,"6":1,"7":1,"13":2,"16":25,"28":1,"29":2,"40":6,"45":1}}],["missingval=",{"2":{"6":1,"7":1}}],["missingval=uint32",{"2":{"1":1}}],["missingval=missingval",{"2":{"1":2}}],["missingval=0",{"2":{"1":2}}],["missingval",{"2":{"0":1,"1":36,"2":7,"3":2,"4":1,"6":1,"7":1,"8":2,"18":1,"29":1,"33":1,"37":1,"40":2,"45":2,"46":1}}],["missingmask",{"2":{"0":1,"1":6}}],["must",{"2":{"1":17,"36":2}}],["multidimensional",{"2":{"28":1}}],["multi",{"2":{"1":5,"2":1,"13":1,"40":1,"46":1}}],["multiple",{"2":{"1":18,"2":3}}],["much",{"2":{"1":3}}],["med",{"2":{"1":1}}],["median",{"2":{"1":6}}],["merge",{"2":{"1":1}}],["messages",{"2":{"1":2,"2":2}}],["meters",{"2":{"1":6}}],["method",{"2":{"1":22,"2":7,"46":1}}],["methods",{"0":{"28":1,"29":1,"31":1},"2":{"1":5,"2":1,"28":1,"29":3,"30":1,"31":1,"40":2,"46":3}}],["metadata",{"2":{"1":7,"2":4,"3":4,"4":2,"6":2,"7":2,"8":4,"14":3,"33":2,"40":4}}],["means",{"2":{"1":4,"2":7,"10":1,"26":1}}],["mean",{"0":{"3":1},"2":{"1":16,"2":3,"3":1,"40":6,"41":1,"42":4}}],["memory",{"2":{"1":18,"2":6,"31":2}}],["margin",{"2":{"45":1}}],["markercolor=",{"2":{"18":1}}],["markershape=",{"2":{"18":1}}],["many",{"2":{"26":1,"27":2}}],["manually",{"2":{"1":17,"2":3,"26":1,"31":1,"38":1}}],["madagascar",{"2":{"24":3}}],["made",{"2":{"1":2}}],["map",{"2":{"4":2}}],["mappedindex",{"2":{"0":1,"1":1}}],["mappedcrs=epsg",{"2":{"1":3}}],["mappedcrs=nothing",{"2":{"1":2}}],["mappedcrs",{"2":{"0":1,"1":20,"38":1,"40":2}}],["mappedbounds",{"2":{"0":1,"1":1}}],["mapped",{"2":{"0":1,"1":16,"23":3,"40":4}}],["making",{"2":{"24":1,"27":1}}],["makie",{"0":{"32":1,"33":1,"34":1,"37":1,"39":1},"2":{"2":13,"15":1,"24":1,"26":2,"32":1,"33":1,"34":2,"36":13,"37":1,"38":3,"39":1}}],["make",{"2":{"1":4,"8":1,"27":1,"43":1}}],["makes",{"2":{"1":1,"34":1}}],["macao",{"2":{"1":1}}],["malaysia",{"2":{"1":1}}],["max",{"2":{"1":1,"38":2}}],["maximum",{"2":{"1":7,"2":2,"38":1}}],["magnitude",{"2":{"1":2}}],["magma",{"2":{"1":2}}],["master",{"2":{"1":4,"44":1}}],["masking",{"0":{"43":1}}],["masks",{"2":{"1":1}}],["masked",{"2":{"1":16,"30":1}}],["mask",{"2":{"0":2,"1":36,"2":1,"29":2,"43":1,"45":5,"46":2}}],["matters",{"2":{"1":2}}],["matter",{"2":{"1":2}}],["matching",{"2":{"1":3,"24":1,"38":1}}],["match",{"2":{"1":9}}],["matches",{"2":{"1":1}}],["matrix",{"2":{"1":2}}],["may",{"2":{"1":70,"2":5,"11":2,"14":1,"34":1,"36":1}}],["cftime",{"2":{"40":2}}],["cmor",{"2":{"40":2}}],["cgrads",{"2":{"2":1,"36":1}}],["cyprus",{"2":{"1":1}}],["c",{"2":{"1":2,"2":2}}],["cp",{"2":{"1":1}}],["c=",{"2":{"1":3}}],["csv",{"2":{"1":1,"18":5}}],["cs",{"2":{"1":1}}],["circumstances",{"2":{"1":5}}],["closest",{"2":{"24":1}}],["closed",{"2":{"2":1}}],["click",{"2":{"28":1}}],["clipperton",{"2":{"1":1}}],["clims=",{"2":{"1":4}}],["climate",{"2":{"1":14,"15":1,"26":1,"34":1,"36":2,"45":7,"46":1}}],["classes",{"2":{"1":5}}],["classified",{"2":{"1":3}}],["classify",{"2":{"0":2,"1":10,"29":2}}],["certain",{"2":{"24":1}}],["center",{"2":{"1":20,"40":6}}],["cell",{"2":{"1":6,"40":2}}],["cells",{"2":{"1":4}}],["cellarea",{"2":{"0":1,"1":2}}],["cubicspline",{"2":{"1":1}}],["cubic",{"2":{"1":3}}],["custom",{"2":{"1":4,"13":1}}],["current",{"2":{"1":3,"2":2,"6":1,"37":1}}],["currently",{"2":{"1":6}}],["cultural",{"2":{"1":4,"44":1}}],["cut",{"2":{"1":5,"37":1}}],["cuda",{"2":{"1":1}}],["cuarray",{"2":{"1":1}}],["chordata",{"2":{"16":15}}],["chosen",{"2":{"1":3,"2":3}}],["chunk",{"2":{"2":11}}],["chunks",{"2":{"2":6}}],["chunking",{"2":{"2":1}}],["changing",{"2":{"1":1}}],["changes",{"2":{"1":2}}],["change",{"0":{"28":1,"29":1},"2":{"1":22,"6":1,"8":2,"38":2}}],["chile",{"2":{"1":1}}],["child",{"2":{"1":11,"2":1}}],["china",{"2":{"1":8}}],["checks",{"2":{"2":1}}],["checksum",{"2":{"2":4}}],["check",{"2":{"2":1,"13":1}}],["checked",{"2":{"1":2}}],["checkmemory",{"2":{"2":1}}],["checkmem",{"2":{"0":1,"2":3}}],["creep",{"2":{"27":1}}],["creation",{"2":{"2":2}}],["creating",{"2":{"1":3}}],["creates",{"2":{"1":1}}],["create",{"2":{"1":6}}],["cross",{"2":{"18":1}}],["crop",{"2":{"0":1,"1":13,"28":1,"46":1}}],["crs=epsg",{"2":{"1":4}}],["crs=nothing",{"2":{"1":1}}],["crs",{"2":{"1":56,"3":2,"4":1,"6":1,"7":1,"8":5,"18":1,"33":1,"37":1,"38":1,"40":2,"45":2,"46":1}}],["categories",{"2":{"29":1}}],["cairomakie",{"2":{"15":1,"24":2,"33":1,"37":1,"39":3}}],["caveats",{"2":{"14":1}}],["cartier",{"2":{"1":1}}],["cartesianindex",{"2":{"1":1}}],["caused",{"2":{"27":1}}],["cause",{"2":{"1":1}}],["caution",{"2":{"1":5}}],["calculate",{"2":{"1":4,"30":1}}],["calculated",{"2":{"1":8}}],["calling",{"2":{"1":3}}],["called",{"2":{"1":1,"2":2}}],["cased",{"2":{"1":2}}],["case",{"2":{"1":8}}],["cases",{"2":{"1":20}}],["cannot",{"2":{"1":1,"2":3}}],["can",{"2":{"1":69,"2":30,"5":2,"8":3,"10":1,"11":2,"12":3,"13":2,"14":2,"15":1,"20":1,"23":1,"26":1,"27":5,"32":1,"34":2,"36":5,"38":2,"46":2}}],["code",{"2":{"26":1,"27":1}}],["coords",{"2":{"18":2}}],["coordinatetransformations",{"2":{"26":1}}],["coordinate",{"2":{"1":10,"26":1}}],["coordinates",{"0":{"17":1},"2":{"1":11,"20":1,"24":1,"40":1}}],["could",{"2":{"1":1,"40":1,"42":1}}],["counts",{"2":{"17":1}}],["country",{"2":{"1":7,"43":1}}],["countries",{"2":{"1":8,"43":1,"44":1,"46":2}}],["count",{"2":{"1":4}}],["counted",{"2":{"1":2}}],["counter",{"2":{"1":5}}],["correlation",{"2":{"1":1,"37":3}}],["corresponding",{"2":{"1":1}}],["correctly",{"2":{"40":1}}],["correct",{"2":{"1":1}}],["covering",{"2":{"28":1}}],["cover",{"2":{"1":2}}],["covered",{"2":{"1":10}}],["coverage",{"2":{"0":2,"1":15}}],["colgap",{"2":{"37":1}}],["color",{"2":{"2":2,"36":2}}],["colorrange",{"2":{"2":1,"36":1}}],["colormaps",{"2":{"2":1,"36":1}}],["colormap",{"2":{"2":3,"36":3,"37":2}}],["colorbar=",{"2":{"36":1}}],["colorbarlabel",{"2":{"2":1,"36":1}}],["colorbar",{"2":{"2":8,"36":8,"37":5}}],["color=",{"2":{"1":2}}],["collect",{"2":{"1":1,"18":1}}],["collection",{"2":{"1":1}}],["collections",{"2":{"1":3}}],["collapse",{"2":{"1":3}}],["columns",{"2":{"1":19,"16":1}}],["column",{"2":{"1":21}}],["copying",{"2":{"1":1}}],["copy",{"2":{"1":2,"2":1}}],["command",{"2":{"42":1}}],["comments",{"2":{"2":2}}],["common",{"2":{"1":4,"11":1,"15":1,"46":1}}],["commonly",{"2":{"1":1,"29":1}}],["com",{"2":{"1":4,"44":1}}],["compress",{"2":{"2":2}}],["compressed",{"2":{"2":2,"10":1}}],["compression",{"2":{"2":8}}],["compatable",{"2":{"1":1}}],["compatible",{"2":{"1":22}}],["comparison",{"2":{"1":6}}],["computes",{"2":{"1":1}}],["compute",{"2":{"1":3}}],["complicated",{"2":{"1":5,"27":1}}],["completely",{"2":{"1":7,"2":1,"14":1}}],["complete",{"2":{"1":1,"27":1}}],["combining",{"2":{"1":3}}],["combination",{"2":{"1":4}}],["combined",{"2":{"1":7}}],["combine",{"2":{"0":1,"1":9,"46":1}}],["conversion",{"2":{"14":2}}],["converting",{"2":{"1":1}}],["converted",{"2":{"1":7,"11":1,"38":1}}],["convert",{"2":{"1":4,"18":1}}],["convertlookup",{"2":{"0":1,"1":1}}],["const",{"2":{"16":1,"24":1}}],["constructor",{"2":{"1":3}}],["considering",{"2":{"1":1}}],["concatenate",{"2":{"1":2}}],["concrete",{"2":{"1":2}}],["conditions",{"2":{"1":5}}],["contourf",{"2":{"2":1,"32":1,"33":1,"36":1,"38":2,"41":1}}],["contour",{"0":{"41":1},"2":{"2":1,"32":1,"33":1,"36":1,"38":2,"40":1}}],["contributing",{"2":{"1":8}}],["contribute",{"2":{"1":4}}],["contrast",{"2":{"1":3,"37":3}}],["continents",{"2":{"1":2}}],["contained",{"2":{"2":1}}],["contains",{"2":{"1":7,"23":1,"24":1}}],["contain",{"2":{"1":4}}],["containing",{"2":{"1":13,"2":2}}],["contents",{"2":{"1":2}}],["break",{"2":{"34":1}}],["breaks",{"2":{"27":1}}],["broadcast",{"2":{"2":1,"3":2,"4":2}}],["broadcasting",{"0":{"4":1},"2":{"1":1}}],["black",{"2":{"18":1}}],["block",{"2":{"2":2}}],["blocks",{"2":{"1":2}}],["blocking",{"2":{"1":4}}],["b",{"2":{"1":13,"6":1,"22":2,"24":2}}],["bilinear",{"2":{"1":2}}],["bio",{"2":{"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["bio7",{"2":{"1":6,"18":1}}],["bio5",{"2":{"1":6,"3":2,"4":1,"6":1,"7":1,"8":2,"33":1}}],["bio3",{"2":{"1":6,"18":1}}],["bio12",{"2":{"1":6,"18":1}}],["bio1",{"2":{"1":6,"18":1}}],["bioclim",{"2":{"1":2,"3":3,"4":1,"6":2,"7":1,"8":2,"18":3,"24":1,"33":2,"38":1,"39":1}}],["bitarray",{"2":{"1":5}}],["bug",{"2":{"27":5}}],["bugs",{"0":{"27":1},"2":{"27":2}}],["built",{"2":{"1":2,"26":1}}],["build",{"2":{"1":24,"13":1}}],["burramys",{"2":{"1":1,"16":1,"18":2}}],["burramis",{"2":{"1":1}}],["but",{"2":{"1":13,"2":3,"5":1,"10":1,"12":1,"23":1,"26":1,"27":3,"36":2}}],["by",{"0":{"20":1,"22":1,"23":1},"2":{"1":75,"2":15,"8":1,"22":1,"24":1,"28":1,"29":1,"30":1,"34":1,"38":1}}],["box",{"2":{"27":1,"36":1}}],["bottom",{"2":{"2":1,"27":1,"36":1}}],["both",{"2":{"1":2}}],["bolivia",{"2":{"1":1}}],["border",{"2":{"1":8,"43":1,"45":7,"46":9}}],["borders",{"2":{"1":8,"46":11}}],["boundaries",{"2":{"1":1}}],["boundary=",{"2":{"1":2}}],["boundary",{"2":{"1":8,"43":1,"44":1}}],["bounds",{"2":{"1":9}}],["bool",{"2":{"1":5,"2":1}}],["boolmask",{"2":{"0":1,"1":6}}],["batlow",{"2":{"37":1}}],["basic",{"2":{"2":1}}],["based",{"2":{"1":2,"2":2,"4":1,"46":1}}],["base",{"2":{"1":2,"2":11}}],["bajo",{"2":{"1":1}}],["bank",{"2":{"1":2}}],["bang",{"2":{"1":4}}],["bands",{"2":{"1":1,"23":1}}],["band",{"0":{"18":1},"2":{"0":1,"1":10,"2":1,"10":1,"12":1,"18":1,"23":1,"36":1}}],["backgroundcolor=",{"2":{"37":2}}],["back",{"2":{"1":2,"40":1}}],["backends",{"2":{"9":1}}],["backend",{"2":{"1":1,"2":10,"9":1,"26":2}}],["backed",{"2":{"1":8}}],["bar",{"2":{"1":9}}],["becomes",{"2":{"8":1}}],["because",{"2":{"1":5,"20":1,"27":2}}],["best",{"2":{"2":1,"12":1,"36":1}}],["besides",{"2":{"1":2}}],["being",{"2":{"2":3,"46":1}}],["beyond",{"2":{"1":1}}],["bets",{"2":{"2":1,"36":1}}],["better",{"2":{"1":1}}],["between",{"2":{"1":9,"2":1,"24":3,"36":1}}],["before",{"2":{"1":14,"2":1}}],["behaviours",{"2":{"1":2}}],["been",{"2":{"1":2,"14":1}}],["below",{"2":{"1":1,"34":1}}],["be",{"2":{"1":191,"2":50,"3":1,"4":1,"5":1,"8":2,"10":1,"11":1,"12":2,"13":2,"14":3,"15":1,"20":1,"23":1,"27":2,"36":7,"38":2}}],["api",{"2":{"38":1}}],["appropriately",{"2":{"34":1}}],["approximately",{"2":{"1":2}}],["approximates",{"2":{"1":1}}],["approximate",{"2":{"1":1}}],["appreciated",{"2":{"27":1}}],["appears",{"2":{"1":1}}],["appended",{"2":{"2":3}}],["append",{"2":{"1":8,"2":3}}],["apparent",{"2":{"1":1}}],["applications",{"2":{"29":1}}],["applicable",{"2":{"2":1,"46":1}}],["applies",{"2":{"4":1}}],["applied",{"2":{"1":13,"2":1,"3":1,"4":1}}],["apply",{"2":{"1":2}}],["amounts",{"2":{"28":1}}],["amount",{"2":{"2":1,"36":1}}],["americas",{"2":{"40":1}}],["america",{"2":{"1":1}}],["average",{"2":{"1":3}}],["available",{"2":{"1":3,"3":1,"23":1,"24":1}}],["affected",{"2":{"8":1}}],["africa",{"2":{"1":8}}],["after",{"2":{"1":13,"2":1}}],["authentication",{"2":{"27":1}}],["authority",{"2":{"3":10,"4":5,"6":5,"7":5,"8":10,"18":5,"33":5,"37":5,"45":10,"46":5}}],["automatic",{"2":{"2":9,"36":9}}],["automatically",{"2":{"1":8,"2":4,"9":1}}],["ausbounds",{"2":{"1":2,"37":2}}],["aus",{"2":{"1":9,"18":3,"37":3}}],["australian",{"2":{"1":1}}],["australia",{"2":{"1":3,"18":1,"37":2}}],["awap",{"2":{"1":13}}],["admin",{"2":{"1":5,"44":1}}],["adding",{"2":{"3":1}}],["additional",{"2":{"1":3,"23":1,"26":2,"29":1}}],["additionally",{"2":{"1":5}}],["addition",{"2":{"1":2}}],["add",{"2":{"1":1,"20":1,"25":1,"27":1,"46":1}}],["added",{"2":{"1":2,"46":1}}],["again",{"2":{"1":1,"2":1,"46":1}}],["ag",{"2":{"1":2}}],["aggregation",{"2":{"1":8}}],["aggregated",{"2":{"1":8}}],["aggregate",{"2":{"0":2,"1":12,"28":2}}],["axs",{"2":{"37":5}}],["ax",{"2":{"33":3}}],["axis3",{"2":{"2":1,"36":1}}],["axistype",{"2":{"2":1,"36":1}}],["axis",{"2":{"1":6,"2":8,"3":4,"4":2,"6":2,"7":2,"8":5,"18":2,"24":1,"28":1,"33":3,"34":1,"36":8,"37":3,"38":1,"45":4,"46":2}}],["axes",{"2":{"1":4,"38":2,"40":1}}],["across",{"2":{"28":1}}],["activate",{"2":{"24":1,"39":1}}],["activated",{"2":{"2":2}}],["active",{"2":{"13":1}}],["actually",{"2":{"2":2,"6":1,"27":1}}],["actual",{"2":{"1":2}}],["accurate",{"2":{"1":1}}],["accept",{"2":{"38":1}}],["accepts",{"2":{"1":2,"2":2,"36":1}}],["accepted",{"2":{"1":2,"33":1}}],["accessible",{"2":{"27":1}}],["access",{"2":{"1":3,"12":1}}],["atol",{"2":{"1":9}}],["attributes",{"2":{"34":1,"37":1}}],["attempt",{"2":{"1":2}}],["attempting",{"2":{"1":1}}],["attached",{"2":{"1":7}}],["at",{"2":{"1":8,"2":5,"24":2,"27":1,"34":1,"40":2,"42":1}}],["altered",{"2":{"2":1,"40":2}}],["although",{"2":{"1":1}}],["aligned",{"2":{"1":1}}],["algorithm",{"2":{"1":3}}],["already",{"2":{"1":1,"2":6}}],["along",{"2":{"1":7,"29":1}}],["alphabetically",{"2":{"1":1}}],["also",{"2":{"1":24,"2":3,"3":1,"8":2,"11":1,"12":1,"22":1,"27":1,"46":1}}],["allow",{"2":{"1":1,"38":1}}],["allows",{"2":{"1":1}}],["allocating",{"2":{"1":1}}],["alllayers",{"2":{"1":3}}],["alllayers=true",{"2":{"1":1}}],["all",{"2":{"1":75,"2":4,"11":1,"12":1,"14":1,"18":1,"24":2,"27":1,"29":1,"46":2}}],["always",{"2":{"1":4,"2":1,"10":1,"13":1,"24":1,"26":1,"27":2}}],["around",{"2":{"40":1}}],["arbitrary",{"2":{"11":1,"23":1}}],["architectures",{"2":{"2":1}}],["archive",{"2":{"2":2}}],["archgdal",{"2":{"1":23,"2":2,"12":1,"26":2,"33":1,"38":1,"39":1,"43":1}}],["args",{"2":{"38":1}}],["argentina",{"2":{"1":4}}],["argument",{"2":{"1":4,"2":2}}],["arguments",{"2":{"1":26,"2":2}}],["area",{"2":{"1":14}}],["areas",{"2":{"1":17,"28":1}}],["are",{"2":{"1":90,"2":8,"8":1,"10":3,"11":3,"12":1,"13":1,"23":1,"24":3,"27":6,"29":1,"34":3,"36":3,"38":1,"40":1,"42":1,"46":1}}],["arrays",{"2":{"1":18,"2":2,"5":1,"23":2,"28":1,"46":1}}],["array",{"0":{"21":1},"2":{"1":49,"2":1,"3":1,"4":2,"16":1,"24":2,"28":1,"29":1,"38":1}}],["aspect",{"2":{"33":1,"34":1}}],["asc",{"2":{"12":1}}],["ashmore",{"2":{"1":1}}],["associated",{"2":{"23":1}}],["assuming",{"2":{"1":1}}],["assign",{"2":{"1":2}}],["assigned",{"2":{"1":6}}],["assigns",{"2":{"1":1}}],["as",{"2":{"1":64,"2":10,"6":1,"11":2,"12":3,"13":2,"14":1,"15":1,"17":1,"24":1,"29":2,"34":2,"40":1,"42":1}}],["a",{"0":{"41":1},"2":{"1":427,"2":100,"3":4,"4":4,"5":2,"6":2,"7":1,"8":5,"9":1,"13":1,"14":1,"15":4,"17":3,"18":2,"22":2,"24":7,"26":2,"27":5,"28":3,"29":2,"31":1,"32":2,"33":7,"34":4,"36":11,"38":6,"39":2,"40":5,"42":3,"43":1,"45":1,"46":6}}],["absolute",{"2":{"1":2}}],["abstracrasterseries",{"2":{"1":2}}],["abstrackrasterstack",{"2":{"1":1}}],["abstractdiskarray",{"2":{"2":3}}],["abstractdimensionalarray",{"2":{"1":1}}],["abstractdimarray",{"2":{"1":4}}],["abstractvector",{"2":{"1":3}}],["abstractgeometry",{"2":{"1":15}}],["abstractstack",{"2":{"1":2}}],["abstractstring",{"2":{"1":3,"2":6}}],["abstractsampled",{"2":{"1":2,"2":1}}],["abstractarray",{"2":{"1":5,"2":1}}],["abstract",{"2":{"1":3,"2":1}}],["abstractrasters",{"2":{"1":5}}],["abstractrasterstack",{"2":{"0":1,"1":12,"2":5}}],["abstractrasterseries",{"2":{"0":1,"1":8,"2":5}}],["abstractraster",{"2":{"0":1,"1":27,"2":9}}],["abstractprojected",{"2":{"0":1,"1":4,"2":1}}],["about",{"2":{"1":4,"2":2}}],["animations",{"0":{"36":1}}],["animalia",{"2":{"16":15}}],["answer",{"2":{"1":2}}],["anything",{"2":{"8":1}}],["any",{"2":{"1":19,"2":6,"3":3,"4":1,"6":1,"7":1,"8":3,"27":1,"28":1,"32":1,"33":1,"34":2,"36":1,"38":1,"40":2}}],["another",{"2":{"1":9,"23":1,"28":3}}],["and",{"0":{"27":1,"30":1,"31":1,"43":1},"2":{"1":133,"2":18,"3":1,"8":1,"9":1,"10":2,"11":1,"12":1,"13":2,"15":5,"16":1,"18":3,"20":2,"22":1,"23":7,"24":3,"26":5,"27":7,"28":3,"29":1,"30":1,"34":3,"36":2,"38":3,"40":5,"45":1,"46":9}}],["an",{"0":{"24":1,"28":1,"29":1},"2":{"1":69,"2":9,"3":1,"5":2,"8":2,"24":3,"27":2,"29":2,"30":1,"34":1,"36":1,"38":1,"46":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/previews/PR807/assets/chunks/VPLocalSearchBox.eYTovQk2.js b/previews/PR807/assets/chunks/VPLocalSearchBox.eYTovQk2.js new file mode 100644 index 00000000..36707750 --- /dev/null +++ b/previews/PR807/assets/chunks/VPLocalSearchBox.eYTovQk2.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 Ce=(a,e,t)=>Ft(a,typeof e!="symbol"?e+"":e,t);import{V as Ot,p as ne,h as ve,aj as Xe,ak as Rt,al as Ct,q as Ve,am as Mt,d as At,D as we,an as et,ao as Lt,ap as Dt,s as zt,aq as Pt,v as Me,P as de,O as xe,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 Se,C as st,F as nt,a as he,t as fe,aw as Ht,ax as it,ay as Qt,a9 as Yt,af as Zt,az as Xt,_ as es}from"./framework.Cl7EIXwS.js";import{u as ts,c as ss}from"./theme.CJjspAw-.js";const ns={root:()=>Ot(()=>import("./@localSearchIndexroot.CCGZ83u0.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])"],ke=vt.join(","),mt=typeof Element>"u",re=mt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Ne=!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},Fe=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(Fe(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(ke));return t&&re.call(e,ke)&&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(!Fe(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=re.call(i,ke);h&&s.filter(i)&&(t||!e.includes(i))&&n.push(i);var v=i.shadowRoot||typeof s.getShadowRoot=="function"&&s.getShadowRoot(i),p=!Fe(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))},ie=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=ie(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(re.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=Ne(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:$e.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:ms}):s=gt(e,t.includeContainer,$e.bind(null,t)),gs(s)},ys=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Oe.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):s=gt(e,t.includeContainer,Oe.bind(null,t)),s},ae=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return re.call(e,ke)===!1?!1:$e(t,e)},ws=vt.concat("iframe").join(","),Ae=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return re.call(e,ws)===!1?!1:Oe(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},me=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Is=function(e){return me(e)&&!e.shiftKey},ks=function(e){return me(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},pe=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 ae(f)}),F=g.slice().reverse().find(function(f){return ae(f)}),m=!!u.find(function(f){return ie(f)>0});return{container:d,tabbableNodes:u,focusableNodes:g,posTabIndexesFound:m,firstTabbableNode:_,lastTabbableNode:E,firstDomTabbableNode:N,lastDomTabbableNode:F,nextTabbableNode:function(I){var A=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,C=u.indexOf(I);return C<0?A?g.slice(g.indexOf(I)+1).find(function(M){return ae(M)}):g.slice(0,g.indexOf(I)).reverse().find(function(M){return ae(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||_e(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(T){var P=T.firstTabbableNode;return u===P});if(f<0&&(m.container===u||Ae(u,r.tabbableOptions)&&!ae(u,r.tabbableOptions)&&!m.nextTabbableNode(u,!1))&&(f=F),f>=0){var I=f===0?i.tabbableGroups.length-1:f-1,A=i.tabbableGroups[I];N=ie(u)>=0?A.lastTabbableNode:A.lastDomTabbableNode}else me(g)||(N=m.nextTabbableNode(u,!1))}else{var C=ut(i.tabbableGroups,function(T){var P=T.lastTabbableNode;return u===P});if(C<0&&(m.container===u||Ae(u,r.tabbableOptions)&&!ae(u,r.tabbableOptions)&&!m.nextTabbableNode(u))&&(C=F),C>=0){var M=C===i.tabbableGroups.length-1?0:C+1,j=i.tabbableGroups[M];N=ie(u)>=0?j.firstTabbableNode:j.firstDomTabbableNode}else me(g)||(N=m.nextTabbableNode(u))}}else N=h("fallbackFocus");return N},O=function(d){var u=_e(d);if(!(c(u,d)>=0)){if(pe(r.clickOutsideDeactivates,d)){o.deactivate({returnFocus:r.returnFocusOnDeactivate});return}pe(r.allowOutsideClick,d)||d.preventDefault()}},R=function(d){var u=_e(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(ie(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(I){return ie(I)>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&&(me(d)&&d.preventDefault(),y(g))},G=function(d){(r.isKeyForward(d)||r.isKeyBackward(d))&&K(d,r.isKeyBackward(d))},W=function(d){Ts(d)&&pe(r.escapeDeactivates,d)!==!1&&(d.preventDefault(),o.deactivate())},V=function(d){var u=_e(d);c(u,d)>=0||pe(r.clickOutsideDeactivates,d)||pe(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},ge=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},L=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(L):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,ge(),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(),ge(),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=ne(!1),i=ne(!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=ve(()=>{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 Ve(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 le{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=>{le.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 le(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 le(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 le.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=le.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 Ie(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 Le{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}=oe(this._path);if(oe(t)===z)return{done:!1,value:this.result()};const s=e.get(oe(t));return this._path.push({node:s,keys:Array.from(s.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=oe(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:e})=>oe(e)).filter(e=>e!==z).join("")}value(){return oe(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 oe=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]=Re(this._tree,e.slice(this._prefix.length));if(t===void 0){const[n,r]=Je(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 Le(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=Be(this._tree,e);return t!==void 0?t.get(z):void 0}has(e){const t=Be(this._tree,e);return t!==void 0&&t.has(z)}keys(){return new Le(this,xt)}set(e,t){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,De(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=De(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=De(this._tree,e);let n=s.get(z);return n===void 0&&s.set(z,n=t()),n}values(){return new Le(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 Re=(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]),Re(a.get(s),e.slice(s.length),t);return t.push([a,e]),Re(void 0,"",t)},Be=(a,e)=>{if(e.length===0||a==null)return a;for(const t of a.keys())if(t!==z&&e.startsWith(t))return Be(a.get(t),e.slice(t.length))},De=(a,e)=>{const t=e.length;e:for(let s=0;a&&s{const[t,s]=Re(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]=Je(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]=Je(a);s.set(n+e,t),s.delete(n)},Je=a=>a[a.length-1],Ue="or",It="and",Ds="and_not";class ce{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?je:e.autoVacuum;this._options=Object.assign(Object.assign(Object.assign({},Pe),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=Ke,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=Ke,this.performVacuuming(e,s)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)}performVacuuming(e,t){return Ie(this,void 0,void 0,function*(){const s=this._dirtCount;if(this.vacuumConditionsMet(t)){const n=e.batchSize||We.batchSize,r=e.batchWait||We.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||je.minDirtCount,s=s||je.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===ce.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 Ie(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(Pe.hasOwnProperty(e))return ze(Pe,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=Ee(n),l._fieldLength=Ee(r),l._storedFields=Ee(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),Ee(b))}l._index.set(c,v)}return l}static loadJSAsync(e,t){return Ie(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 Te(n),l._fieldLength=yield Te(r),l._storedFields=yield Te(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 Te(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 ce(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===ce.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]:ze(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=Ue){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 $=ze(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={[Ue]:(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}},Pe={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:Ue,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},We={batchSize:1e3,batchWait:10},Ke={minDirtFactor:.1,minDirtCount:20},je=Object.assign(Object.assign({},We),Ke),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,Ee=a=>{const e=new Map;for(const t of Object.keys(a))e.set(parseInt(t,10),a[t]);return e},Te=a=>Ie(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){Ce(this,"max");Ce(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=["aria-activedescendant","aria-controls","placeholder"],Ys={class:"search-actions"},Zs=["title"],Xs=["disabled","title"],en=["id","role","aria-labelledby"],tn=["id","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=we(),n=we(),r=we(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,I,A,C,M,j,T,P;return it(ce.loadJSON((I=await((f=(m=r.value)[l.value])==null?void 0:f.call(m)))==null?void 0:I.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)},...((j=c.value.search)==null?void 0:j.provider)==="local"&&((P=(T=c.value.search.options)==null?void 0:T.miniSearch)==null?void 0:P.options)}))}),p=ve(()=>{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?ne(""):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=ve(()=>{var m,f,I;return((m=c.value.search)==null?void 0:m.provider)==="local"&&(((f=c.value.search.options)==null?void 0:f.disableDetailedView)===!0||((I=c.value.search.options)==null?void 0:I.detailedView)===!1)}),x=ve(()=>{var f,I,A,C,M,j,T;const m=((f=c.value.search)==null?void 0:f.options)??c.value.algolia;return((M=(C=(A=(I=m==null?void 0:m.locales)==null?void 0:I[l.value])==null?void 0:A.translations)==null?void 0:C.button)==null?void 0:M.buttonText)||((T=(j=m==null?void 0:m.translations)==null?void 0:j.button)==null?void 0:T.buttonText)||"Search"});zt(()=>{y.value&&(b.value=!1)});const w=we([]),O=ne(!1);Ve(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,I],A,C)=>{var X,be,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 j=I?await Promise.all(w.value.map(B=>G(B.id))):[];if(M)return;for(const{id:B,mod:ee}of j){const te=B.slice(0,B.indexOf("#"));let Q=K.get(te);if(Q)continue;Q=new Map,K.set(te,Q);const U=ee.default??ee;if(U!=null&&U.render||U!=null&&U.setup){const se=Qt(U);se.config.warnHandler=()=>{},se.provide(Yt,i),Object.defineProperties(se.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const He=document.createElement("div");se.mount(He),He.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(ue=>{var Ze;const ye=(Ze=ue.querySelector("a"))==null?void 0:Ze.getAttribute("href"),Qe=(ye==null?void 0:ye.startsWith("#"))&&ye.slice(1);if(!Qe)return;let Ye="";for(;(ue=ue.nextElementSibling)&&!/^h[1-6]$/i.test(ue.tagName);)Ye+=ue.outerHTML;Q.set(Qe,Ye)}),se.unmount()}if(M)return}const T=new Set;if(w.value=w.value.map(B=>{const[ee,te]=B.id.split("#"),Q=K.get(ee),U=(Q==null?void 0:Q.get(te))??"";for(const se in B.match)T.add(se);return{...B,text:U}}),await de(),M)return;await new Promise(B=>{var ee;(ee=R.value)==null||ee.unmark({done:()=>{var te;(te=R.value)==null||te.markRegExp(E(T),{done:B})}})});const P=((X=s.value)==null?void 0:X.querySelectorAll(".result .excerpt"))??[];for(const B of P)(be=B.querySelector('mark[data-markjs="true"]'))==null||be.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(I){return console.error(I),{id:m,mod:{}}}}const W=ne(),V=ve(()=>{var m;return((m=p.value)==null?void 0:m.length)<=0});function $(m=!0){var f,I;(f=W.value)==null||f.focus(),m&&((I=W.value)==null||I.select())}Me(()=>{$()});function ge(m){m.pointerType==="mouse"&&$()}const L=ne(-1),H=ne(!1);Ve(w,m=>{L.value=m.length?0:-1,J()});function J(){de(()=>{const m=document.querySelector(".result.selected");m==null||m.scrollIntoView({block:"nearest"})})}xe("ArrowUp",m=>{m.preventDefault(),L.value--,L.value<0&&(L.value=w.value.length-1),H.value=!0,J()}),xe("ArrowDown",m=>{m.preventDefault(),L.value++,L.value>=w.value.length&&(L.value=0),H.value=!0,J()});const k=jt();xe("Enter",m=>{if(m.isComposing||m.target instanceof HTMLButtonElement&&m.target.type!=="submit")return;const f=w.value[L.value];if(m.target instanceof HTMLInputElement&&!f){m.preventDefault();return}f&&(k.go(f.id),t("close"))}),xe("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"}}});Me(()=>{window.history.pushState(null,"",null)}),Vt("popstate",m=>{m.preventDefault(),t("close")});const g=$t(Bt?document.body:null);Me(()=>{de(()=>{g.value=!0,de().then(()=>o())})}),Wt(()=>{g.value=!1});function _(){p.value="",de().then(()=>$(!1))}function E(m){return new RegExp([...m].sort((f,I)=>I.length-f.length).map(f=>`(${Xt(f)})`).join("|"),"gi")}return(m,f)=>{var I,A,C,M,j;return q(),Kt(Ht,{to:"body"},[S("div",{ref_key:"el",ref:s,role:"button","aria-owns":(I=w.value)!=null&&I.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]=T=>m.$emit("close"))}),S("div",Us,[S("form",{class:"search-bar",onPointerup:f[4]||(f[4]=T=>ge(T)),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]=T=>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]=T=>Gt(p)?p.value=T:null),"aria-activedescendant":L.value>-1?"localsearch-item-"+L.value:void 0,"aria-autocomplete":"both","aria-controls":(A=w.value)!=null&&A.length?"localsearch-list":void 0,"aria-labelledby":"localsearch-label",autocapitalize:"off",autocomplete:"off",autocorrect:"off",class:"search-input",id:"localsearch-input",enterkeyhint:"go",maxlength:"64",placeholder:x.value,spellcheck:"false",type:"search"},null,8,Qs),[[qt,D(p)]]),S("div",Ys,[y.value?Se("",!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]=T=>L.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:(C=w.value)!=null&&C.length?"localsearch-list":void 0,role:(M=w.value)!=null&&M.length?"listbox":void 0,"aria-labelledby":(j=w.value)!=null&&j.length?"localsearch-label":void 0,class:"results",onMousemove:f[7]||(f[7]=T=>H.value=!1)},[(q(!0),Y(nt,null,st(w.value,(T,P)=>(q(),Y("li",{key:T.id,id:"localsearch-item-"+P,"aria-selected":L.value===P?"true":"false",role:"option"},[S("a",{href:T.id,class:tt(["result",{selected:L.value===P}]),"aria-label":[...T.titles,T.title].join(" > "),onMouseenter:X=>!H.value&&(L.value=P),onFocusin:X=>L.value=P,onClick:f[6]||(f[6]=X=>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(T.titles,(X,be)=>(q(),Y("span",{key:be,class:"title"},[S("span",{class:"text",innerHTML:X},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:T.title},null,8,on)])]),D(b)?(q(),Y("div",ln,[T.text?(q(),Y("div",cn,[S("div",{class:"vp-doc",innerHTML:T.text},null,8,un)])):Se("",!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))])):Se("",!0)])],42,sn)],8,tn))),128)),D(p)&&!w.value.length&&O.value?(q(),Y("li",dn,[he(fe(D(u)("modal.noResultsText"))+' "',1),S("strong",null,fe(D(p)),1),f[16]||(f[16]=he('" '))])):Se("",!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),he(" "+fe(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),he(" "+fe(D(u)("modal.footer.selectText")),1)]),S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.closeKeyAriaLabel")},"esc",8,mn),he(" "+fe(D(u)("modal.footer.closeText")),1)])])])],8,Js)])}}}),_n=es(gn,[["__scopeId","data-v-1783de97"]]);export{_n as default}; diff --git a/previews/PR807/assets/chunks/framework.Cl7EIXwS.js b/previews/PR807/assets/chunks/framework.Cl7EIXwS.js new file mode 100644 index 00000000..ca8b84d5 --- /dev/null +++ b/previews/PR807/assets/chunks/framework.Cl7EIXwS.js @@ -0,0 +1,18 @@ +/** +* @vue/shared v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function Ns(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Z={},Et=[],ke=()=>{},Uo=()=>!1,Zt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Fs=e=>e.startsWith("onUpdate:"),ce=Object.assign,Hs=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},ko=Object.prototype.hasOwnProperty,z=(e,t)=>ko.call(e,t),K=Array.isArray,Tt=e=>In(e)==="[object Map]",si=e=>In(e)==="[object Set]",q=e=>typeof e=="function",re=e=>typeof e=="string",Ye=e=>typeof e=="symbol",ne=e=>e!==null&&typeof e=="object",ri=e=>(ne(e)||q(e))&&q(e.then)&&q(e.catch),ii=Object.prototype.toString,In=e=>ii.call(e),Bo=e=>In(e).slice(8,-1),oi=e=>In(e)==="[object Object]",$s=e=>re(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ct=Ns(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Nn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Wo=/-(\w)/g,Le=Nn(e=>e.replace(Wo,(t,n)=>n?n.toUpperCase():"")),Ko=/\B([A-Z])/g,st=Nn(e=>e.replace(Ko,"-$1").toLowerCase()),Fn=Nn(e=>e.charAt(0).toUpperCase()+e.slice(1)),vn=Nn(e=>e?`on${Fn(e)}`:""),tt=(e,t)=>!Object.is(e,t),bn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},vs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},qo=e=>{const t=re(e)?Number(e):NaN;return isNaN(t)?e:t};let ar;const Hn=()=>ar||(ar=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Ds(e){if(K(e)){const t={};for(let n=0;n{if(n){const s=n.split(Yo);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function js(e){let t="";if(re(e))t=e;else if(K(e))for(let n=0;n!!(e&&e.__v_isRef===!0),Zo=e=>re(e)?e:e==null?"":K(e)||ne(e)&&(e.toString===ii||!q(e.toString))?ai(e)?Zo(e.value):JSON.stringify(e,fi,2):String(e),fi=(e,t)=>ai(t)?fi(e,t.value):Tt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],i)=>(n[zn(s,i)+" =>"]=r,n),{})}:si(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>zn(n))}:Ye(t)?zn(t):ne(t)&&!K(t)&&!oi(t)?String(t):t,zn=(e,t="")=>{var n;return Ye(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let _e;class el{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.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;if(jt){let t=jt;for(jt=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Dt;){let t=Dt;for(Dt=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function gi(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function mi(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),ks(s),nl(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function bs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(yi(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function yi(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Kt))return;e.globalVersion=Kt;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!bs(e)){e.flags&=-3;return}const n=te,s=Ne;te=e,Ne=!0;try{gi(e);const r=e.fn(e._value);(t.version===0||tt(r,e._value))&&(e._value=r,t.version++)}catch(r){throw t.version++,r}finally{te=n,Ne=s,mi(e),e.flags&=-3}}function ks(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)ks(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function nl(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let Ne=!0;const vi=[];function rt(){vi.push(Ne),Ne=!1}function it(){const e=vi.pop();Ne=e===void 0?!0:e}function fr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=te;te=void 0;try{t()}finally{te=n}}}let Kt=0;class sl{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class $n{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!te||!Ne||te===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==te)n=this.activeLink=new sl(te,this),te.deps?(n.prevDep=te.depsTail,te.depsTail.nextDep=n,te.depsTail=n):te.deps=te.depsTail=n,bi(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=te.depsTail,n.nextDep=void 0,te.depsTail.nextDep=n,te.depsTail=n,te.deps===n&&(te.deps=s)}return n}trigger(t){this.version++,Kt++,this.notify(t)}notify(t){Vs();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Us()}}}function bi(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)bi(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Tn=new WeakMap,dt=Symbol(""),_s=Symbol(""),qt=Symbol("");function me(e,t,n){if(Ne&&te){let s=Tn.get(e);s||Tn.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new $n),r.map=s,r.key=n),r.track()}}function qe(e,t,n,s,r,i){const o=Tn.get(e);if(!o){Kt++;return}const l=c=>{c&&c.trigger()};if(Vs(),t==="clear")o.forEach(l);else{const c=K(e),f=c&&$s(n);if(c&&n==="length"){const a=Number(s);o.forEach((d,y)=>{(y==="length"||y===qt||!Ye(y)&&y>=a)&&l(d)})}else switch((n!==void 0||o.has(void 0))&&l(o.get(n)),f&&l(o.get(qt)),t){case"add":c?f&&l(o.get("length")):(l(o.get(dt)),Tt(e)&&l(o.get(_s)));break;case"delete":c||(l(o.get(dt)),Tt(e)&&l(o.get(_s)));break;case"set":Tt(e)&&l(o.get(dt));break}}Us()}function rl(e,t){const n=Tn.get(e);return n&&n.get(t)}function bt(e){const t=J(e);return t===e?t:(me(t,"iterate",qt),Pe(e)?t:t.map(ye))}function Dn(e){return me(e=J(e),"iterate",qt),e}const il={__proto__:null,[Symbol.iterator](){return Zn(this,Symbol.iterator,ye)},concat(...e){return bt(this).concat(...e.map(t=>K(t)?bt(t):t))},entries(){return Zn(this,"entries",e=>(e[1]=ye(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(ye),arguments)},find(e,t){return We(this,"find",e,t,ye,arguments)},findIndex(e,t){return We(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return We(this,"findLast",e,t,ye,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 es(this,"includes",e)},indexOf(...e){return es(this,"indexOf",e)},join(e){return bt(this).join(e)},lastIndexOf(...e){return es(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 ur(this,"reduce",e,t)},reduceRight(e,...t){return ur(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 Zn(this,"values",ye)}};function Zn(e,t,n){const s=Dn(e),r=s[t]();return s!==e&&!Pe(e)&&(r._next=r.next,r.next=()=>{const i=r._next();return i.value&&(i.value=n(i.value)),i}),r}const ol=Array.prototype;function We(e,t,n,s,r,i){const o=Dn(e),l=o!==e&&!Pe(e),c=o[t];if(c!==ol[t]){const d=c.apply(e,i);return l?ye(d):d}let f=n;o!==e&&(l?f=function(d,y){return n.call(this,ye(d),y,e)}:n.length>2&&(f=function(d,y){return n.call(this,d,y,e)}));const a=c.call(o,f,s);return l&&r?r(a):a}function ur(e,t,n,s){const r=Dn(e);let i=n;return r!==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,ye(l),c,e)}),r[t](i,...s)}function es(e,t,n){const s=J(e);me(s,"iterate",qt);const r=s[t](...n);return(r===-1||r===!1)&&Ks(n[0])?(n[0]=J(n[0]),s[t](...n)):r}function Ft(e,t,n=[]){rt(),Vs();const s=J(e)[t].apply(e,n);return Us(),it(),s}const ll=Ns("__proto__,__v_isRef,__isVue"),_i=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ye));function cl(e){Ye(e)||(e=String(e));const t=J(this);return me(t,"has",e),t.hasOwnProperty(e)}class wi{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return i;if(n==="__v_raw")return s===(r?i?vl:Ti:i?Ei:xi).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=K(t);if(!r){let c;if(o&&(c=il[n]))return c;if(n==="hasOwnProperty")return cl}const l=Reflect.get(t,n,fe(t)?t:s);return(Ye(n)?_i.has(n):ll(n))||(r||me(t,"get",n),i)?l:fe(l)?o&&$s(n)?l:l.value:ne(l)?r?Vn(l):jn(l):l}}class Si extends wi{constructor(t=!1){super(!1,t)}set(t,n,s,r){let i=t[n];if(!this._isShallow){const c=yt(i);if(!Pe(s)&&!yt(s)&&(i=J(i),s=J(s)),!K(t)&&fe(i)&&!fe(s))return c?!1:(i.value=s,!0)}const o=K(t)&&$s(n)?Number(n)e,ln=e=>Reflect.getPrototypeOf(e);function hl(e,t,n){return function(...s){const r=this.__v_raw,i=J(r),o=Tt(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,f=r[e](...s),a=n?ws:t?Ss:ye;return!t&&me(i,"iterate",c?_s:dt),{next(){const{value:d,done:y}=f.next();return y?{value:d,done:y}:{value:l?[a(d[0]),a(d[1])]:a(d),done:y}},[Symbol.iterator](){return this}}}}function cn(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function pl(e,t){const n={get(r){const i=this.__v_raw,o=J(i),l=J(r);e||(tt(r,l)&&me(o,"get",r),me(o,"get",l));const{has:c}=ln(o),f=t?ws:e?Ss:ye;if(c.call(o,r))return f(i.get(r));if(c.call(o,l))return f(i.get(l));i!==o&&i.get(r)},get size(){const r=this.__v_raw;return!e&&me(J(r),"iterate",dt),Reflect.get(r,"size",r)},has(r){const i=this.__v_raw,o=J(i),l=J(r);return e||(tt(r,l)&&me(o,"has",r),me(o,"has",l)),r===l?i.has(r):i.has(r)||i.has(l)},forEach(r,i){const o=this,l=o.__v_raw,c=J(l),f=t?ws:e?Ss:ye;return!e&&me(c,"iterate",dt),l.forEach((a,d)=>r.call(i,f(a),f(d),o))}};return ce(n,e?{add:cn("add"),set:cn("set"),delete:cn("delete"),clear:cn("clear")}:{add(r){!t&&!Pe(r)&&!yt(r)&&(r=J(r));const i=J(this);return ln(i).has.call(i,r)||(i.add(r),qe(i,"add",r,r)),this},set(r,i){!t&&!Pe(i)&&!yt(i)&&(i=J(i));const o=J(this),{has:l,get:c}=ln(o);let f=l.call(o,r);f||(r=J(r),f=l.call(o,r));const a=c.call(o,r);return o.set(r,i),f?tt(i,a)&&qe(o,"set",r,i):qe(o,"add",r,i),this},delete(r){const i=J(this),{has:o,get:l}=ln(i);let c=o.call(i,r);c||(r=J(r),c=o.call(i,r)),l&&l.call(i,r);const f=i.delete(r);return c&&qe(i,"delete",r,void 0),f},clear(){const r=J(this),i=r.size!==0,o=r.clear();return i&&qe(r,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=hl(r,e,t)}),n}function Bs(e,t){const n=pl(e,t);return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(z(n,r)&&r in s?n:s,r,i)}const gl={get:Bs(!1,!1)},ml={get:Bs(!1,!0)},yl={get:Bs(!0,!1)};const xi=new WeakMap,Ei=new WeakMap,Ti=new WeakMap,vl=new WeakMap;function bl(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function _l(e){return e.__v_skip||!Object.isExtensible(e)?0:bl(Bo(e))}function jn(e){return yt(e)?e:Ws(e,!1,fl,gl,xi)}function wl(e){return Ws(e,!1,dl,ml,Ei)}function Vn(e){return Ws(e,!0,ul,yl,Ti)}function Ws(e,t,n,s,r){if(!ne(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=_l(e);if(o===0)return e;const l=new Proxy(e,o===2?s:n);return r.set(e,l),l}function ht(e){return yt(e)?ht(e.__v_raw):!!(e&&e.__v_isReactive)}function yt(e){return!!(e&&e.__v_isReadonly)}function Pe(e){return!!(e&&e.__v_isShallow)}function Ks(e){return e?!!e.__v_raw:!1}function J(e){const t=e&&e.__v_raw;return t?J(t):e}function _n(e){return!z(e,"__v_skip")&&Object.isExtensible(e)&&li(e,"__v_skip",!0),e}const ye=e=>ne(e)?jn(e):e,Ss=e=>ne(e)?Vn(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function oe(e){return Ci(e,!1)}function qs(e){return Ci(e,!0)}function Ci(e,t){return fe(e)?e:new Sl(e,t)}class Sl{constructor(t,n){this.dep=new $n,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:J(t),this._value=n?t:ye(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||Pe(t)||yt(t);t=s?t:J(t),tt(t,n)&&(this._rawValue=t,this._value=s?t:ye(t),this.dep.trigger())}}function Ai(e){return fe(e)?e.value:e}const xl={get:(e,t,n)=>t==="__v_raw"?e:Ai(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return fe(r)&&!fe(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Ri(e){return ht(e)?e:new Proxy(e,xl)}class El{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new $n,{get:s,set:r}=t(n.track.bind(n),n.trigger.bind(n));this._get=s,this._set=r}get value(){return this._value=this._get()}set value(t){this._set(t)}}function Tl(e){return new El(e)}class Cl{constructor(t,n,s){this._object=t,this._key=n,this._defaultValue=s,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 rl(J(this._object),this._key)}}class Al{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 Rl(e,t,n){return fe(e)?e:q(e)?new Al(e):ne(e)&&arguments.length>1?Ol(e,t,n):oe(e)}function Ol(e,t,n){const s=e[t];return fe(s)?s:new Cl(e,t,n)}class Ml{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new $n(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Kt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&te!==this)return pi(this,!0),!0}get value(){const t=this.dep.track();return yi(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Pl(e,t,n=!1){let s,r;return q(e)?s=e:(s=e.get,r=e.set),new Ml(s,r,n)}const an={},Cn=new WeakMap;let ft;function Ll(e,t=!1,n=ft){if(n){let s=Cn.get(n);s||Cn.set(n,s=[]),s.push(e)}}function Il(e,t,n=Z){const{immediate:s,deep:r,once:i,scheduler:o,augmentJob:l,call:c}=n,f=g=>r?g:Pe(g)||r===!1||r===0?Ge(g,1):Ge(g);let a,d,y,v,S=!1,b=!1;if(fe(e)?(d=()=>e.value,S=Pe(e)):ht(e)?(d=()=>f(e),S=!0):K(e)?(b=!0,S=e.some(g=>ht(g)||Pe(g)),d=()=>e.map(g=>{if(fe(g))return g.value;if(ht(g))return f(g);if(q(g))return c?c(g,2):g()})):q(e)?t?d=c?()=>c(e,2):e:d=()=>{if(y){rt();try{y()}finally{it()}}const g=ft;ft=a;try{return c?c(e,3,[v]):e(v)}finally{ft=g}}:d=ke,t&&r){const g=d,M=r===!0?1/0:r;d=()=>Ge(g(),M)}const B=ui(),N=()=>{a.stop(),B&&Hs(B.effects,a)};if(i&&t){const g=t;t=(...M)=>{g(...M),N()}}let j=b?new Array(e.length).fill(an):an;const p=g=>{if(!(!(a.flags&1)||!a.dirty&&!g))if(t){const M=a.run();if(r||S||(b?M.some((F,$)=>tt(F,j[$])):tt(M,j))){y&&y();const F=ft;ft=a;try{const $=[M,j===an?void 0:b&&j[0]===an?[]:j,v];c?c(t,3,$):t(...$),j=M}finally{ft=F}}}else a.run()};return l&&l(p),a=new di(d),a.scheduler=o?()=>o(p,!1):p,v=g=>Ll(g,!1,a),y=a.onStop=()=>{const g=Cn.get(a);if(g){if(c)c(g,4);else for(const M of g)M();Cn.delete(a)}},t?s?p(!0):j=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 Ge(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--,fe(e))Ge(e.value,t,n);else if(K(e))for(let s=0;s{Ge(s,t,n)});else if(oi(e)){for(const s in e)Ge(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Ge(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function en(e,t,n,s){try{return s?e(...s):e()}catch(r){tn(r,t,n)}}function He(e,t,n,s){if(q(e)){const r=en(e,t,n,s);return r&&ri(r)&&r.catch(i=>{tn(i,t,n)}),r}if(K(e)){const r=[];for(let i=0;i>>1,r=we[s],i=Gt(r);i=Gt(n)?we.push(e):we.splice(Fl(t),0,e),e.flags|=1,Mi()}}function Mi(){An||(An=Oi.then(Pi))}function Hl(e){K(e)?At.push(...e):Qe&&e.id===-1?Qe.splice(wt+1,0,e):e.flags&1||(At.push(e),e.flags|=1),Mi()}function dr(e,t,n=Ve+1){for(;nGt(n)-Gt(s));if(At.length=0,Qe){Qe.push(...t);return}for(Qe=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Pi(e){try{for(Ve=0;Ve{s._d&&Cr(-1);const i=On(t);let o;try{o=e(...r)}finally{On(i),s._d&&Cr(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function bf(e,t){if(de===null)return e;const n=Gn(de),s=e.dirs||(e.dirs=[]);for(let r=0;re.__isTeleport,Vt=e=>e&&(e.disabled||e.disabled===""),Dl=e=>e&&(e.defer||e.defer===""),hr=e=>typeof SVGElement<"u"&&e instanceof SVGElement,pr=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,xs=(e,t)=>{const n=e&&e.to;return re(n)?t?t(n):null:n},jl={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,i,o,l,c,f){const{mc:a,pc:d,pbc:y,o:{insert:v,querySelector:S,createText:b,createComment:B}}=f,N=Vt(t.props);let{shapeFlag:j,children:p,dynamicChildren:g}=t;if(e==null){const M=t.el=b(""),F=t.anchor=b("");v(M,n,s),v(F,n,s);const $=(R,_)=>{j&16&&(r&&r.isCE&&(r.ce._teleportTarget=R),a(p,R,_,r,i,o,l,c))},V=()=>{const R=t.target=xs(t.props,S),_=Fi(R,t,b,v);R&&(o!=="svg"&&hr(R)?o="svg":o!=="mathml"&&pr(R)&&(o="mathml"),N||($(R,_),wn(t,!1)))};N&&($(n,F),wn(t,!0)),Dl(t.props)?xe(V,i):V()}else{t.el=e.el,t.targetStart=e.targetStart;const M=t.anchor=e.anchor,F=t.target=e.target,$=t.targetAnchor=e.targetAnchor,V=Vt(e.props),R=V?n:F,_=V?M:$;if(o==="svg"||hr(F)?o="svg":(o==="mathml"||pr(F))&&(o="mathml"),g?(y(e.dynamicChildren,g,R,r,i,o,l),Qs(e,t,!0)):c||d(e,t,R,_,r,i,o,l,!1),N)V?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):fn(t,n,M,f,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const I=t.target=xs(t.props,S);I&&fn(t,I,null,f,0)}else V&&fn(t,F,$,f,1);wn(t,N)}},remove(e,t,n,{um:s,o:{remove:r}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:f,targetAnchor:a,target:d,props:y}=e;if(d&&(r(f),r(a)),i&&r(c),o&16){const v=i||!Vt(y);for(let S=0;S{e.isMounted=!0}),ki(()=>{e.isUnmounting=!0}),e}const Re=[Function,Array],Hi={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},$i=e=>{const t=e.subTree;return t.component?$i(t.component):t},kl={name:"BaseTransition",props:Hi,setup(e,{slots:t}){const n=qn(),s=Ul();return()=>{const r=t.default&&Vi(t.default(),!0);if(!r||!r.length)return;const i=Di(r),o=J(e),{mode:l}=o;if(s.isLeaving)return ts(i);const c=gr(i);if(!c)return ts(i);let f=Es(c,o,s,n,y=>f=y);c.type!==ve&&Yt(c,f);const a=n.subTree,d=a&&gr(a);if(d&&d.type!==ve&&!ut(c,d)&&$i(n).type!==ve){const y=Es(d,o,s,n);if(Yt(d,y),l==="out-in"&&c.type!==ve)return s.isLeaving=!0,y.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete y.afterLeave},ts(i);l==="in-out"&&c.type!==ve&&(y.delayLeave=(v,S,b)=>{const B=ji(s,d);B[String(d.key)]=d,v[Ze]=()=>{S(),v[Ze]=void 0,delete f.delayedLeave},f.delayedLeave=b})}return i}}};function Di(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ve){t=n;break}}return t}const Bl=kl;function ji(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Es(e,t,n,s,r){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:f,onAfterEnter:a,onEnterCancelled:d,onBeforeLeave:y,onLeave:v,onAfterLeave:S,onLeaveCancelled:b,onBeforeAppear:B,onAppear:N,onAfterAppear:j,onAppearCancelled:p}=t,g=String(e.key),M=ji(n,e),F=(R,_)=>{R&&He(R,s,9,_)},$=(R,_)=>{const I=_[1];F(R,_),K(R)?R.every(E=>E.length<=1)&&I():R.length<=1&&I()},V={mode:o,persisted:l,beforeEnter(R){let _=c;if(!n.isMounted)if(i)_=B||c;else return;R[Ze]&&R[Ze](!0);const I=M[g];I&&ut(e,I)&&I.el[Ze]&&I.el[Ze](),F(_,[R])},enter(R){let _=f,I=a,E=d;if(!n.isMounted)if(i)_=N||f,I=j||a,E=p||d;else return;let W=!1;const se=R[un]=ae=>{W||(W=!0,ae?F(E,[R]):F(I,[R]),V.delayedLeave&&V.delayedLeave(),R[un]=void 0)};_?$(_,[R,se]):se()},leave(R,_){const I=String(e.key);if(R[un]&&R[un](!0),n.isUnmounting)return _();F(y,[R]);let E=!1;const W=R[Ze]=se=>{E||(E=!0,_(),se?F(b,[R]):F(S,[R]),R[Ze]=void 0,M[I]===e&&delete M[I])};M[I]=e,v?$(v,[R,W]):W()},clone(R){const _=Es(R,t,n,s,r);return r&&r(_),_}};return V}function ts(e){if(nn(e))return e=nt(e),e.children=null,e}function gr(e){if(!nn(e))return Ni(e.type)&&e.children?Di(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 Vi(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;iMn(S,t&&(K(t)?t[b]:t),n,s,r));return}if(pt(s)&&!r)return;const i=s.shapeFlag&4?Gn(s.component):s.el,o=r?null:i,{i:l,r:c}=e,f=t&&t.r,a=l.refs===Z?l.refs={}:l.refs,d=l.setupState,y=J(d),v=d===Z?()=>!1:S=>z(y,S);if(f!=null&&f!==c&&(re(f)?(a[f]=null,v(f)&&(d[f]=null)):fe(f)&&(f.value=null)),q(c))en(c,l,12,[o,a]);else{const S=re(c),b=fe(c);if(S||b){const B=()=>{if(e.f){const N=S?v(c)?d[c]:a[c]:c.value;r?K(N)&&Hs(N,i):K(N)?N.includes(i)||N.push(i):S?(a[c]=[i],v(c)&&(d[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else S?(a[c]=o,v(c)&&(d[c]=o)):b&&(c.value=o,e.k&&(a[e.k]=o))};o?(B.id=-1,xe(B,n)):B()}}}let mr=!1;const _t=()=>{mr||(console.error("Hydration completed but contains mismatches."),mr=!0)},Wl=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Kl=e=>e.namespaceURI.includes("MathML"),dn=e=>{if(e.nodeType===1){if(Wl(e))return"svg";if(Kl(e))return"mathml"}},xt=e=>e.nodeType===8;function ql(e){const{mt:t,p:n,o:{patchProp:s,createText:r,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:f}}=e,a=(p,g)=>{if(!g.hasChildNodes()){n(null,p,g),Rn(),g._vnode=p;return}d(g.firstChild,p,null,null,null),Rn(),g._vnode=p},d=(p,g,M,F,$,V=!1)=>{V=V||!!g.dynamicChildren;const R=xt(p)&&p.data==="[",_=()=>b(p,g,M,F,$,R),{type:I,ref:E,shapeFlag:W,patchFlag:se}=g;let ae=p.nodeType;g.el=p,se===-2&&(V=!1,g.dynamicChildren=null);let U=null;switch(I){case gt:ae!==3?g.children===""?(c(g.el=r(""),o(p),p),U=p):U=_():(p.data!==g.children&&(_t(),p.data=g.children),U=i(p));break;case ve:j(p)?(U=i(p),N(g.el=p.content.firstChild,p,M)):ae!==8||R?U=_():U=i(p);break;case kt:if(R&&(p=i(p),ae=p.nodeType),ae===1||ae===3){U=p;const Y=!g.children.length;for(let D=0;D{V=V||!!g.dynamicChildren;const{type:R,props:_,patchFlag:I,shapeFlag:E,dirs:W,transition:se}=g,ae=R==="input"||R==="option";if(ae||I!==-1){W&&Ue(g,null,M,"created");let U=!1;if(j(p)){U=io(null,se)&&M&&M.vnode.props&&M.vnode.props.appear;const D=p.content.firstChild;U&&se.beforeEnter(D),N(D,p,M),g.el=p=D}if(E&16&&!(_&&(_.innerHTML||_.textContent))){let D=v(p.firstChild,g,p,M,F,$,V);for(;D;){hn(p,1)||_t();const he=D;D=D.nextSibling,l(he)}}else if(E&8){let D=g.children;D[0]===` +`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&(D=D.slice(1)),p.textContent!==D&&(hn(p,0)||_t(),p.textContent=g.children)}if(_){if(ae||!V||I&48){const D=p.tagName.includes("-");for(const he in _)(ae&&(he.endsWith("value")||he==="indeterminate")||Zt(he)&&!Ct(he)||he[0]==="."||D)&&s(p,he,null,_[he],void 0,M)}else if(_.onClick)s(p,"onClick",null,_.onClick,void 0,M);else if(I&4&&ht(_.style))for(const D in _.style)_.style[D]}let Y;(Y=_&&_.onVnodeBeforeMount)&&Oe(Y,M,g),W&&Ue(g,null,M,"beforeMount"),((Y=_&&_.onVnodeMounted)||W||U)&&fo(()=>{Y&&Oe(Y,M,g),U&&se.enter(p),W&&Ue(g,null,M,"mounted")},F)}return p.nextSibling},v=(p,g,M,F,$,V,R)=>{R=R||!!g.dynamicChildren;const _=g.children,I=_.length;for(let E=0;E{const{slotScopeIds:R}=g;R&&($=$?$.concat(R):R);const _=o(p),I=v(i(p),g,_,M,F,$,V);return I&&xt(I)&&I.data==="]"?i(g.anchor=I):(_t(),c(g.anchor=f("]"),_,I),I)},b=(p,g,M,F,$,V)=>{if(hn(p.parentElement,1)||_t(),g.el=null,V){const I=B(p);for(;;){const E=i(p);if(E&&E!==I)l(E);else break}}const R=i(p),_=o(p);return l(p),n(null,g,_,R,M,F,dn(_),$),R},B=(p,g="[",M="]")=>{let F=0;for(;p;)if(p=i(p),p&&xt(p)&&(p.data===g&&F++,p.data===M)){if(F===0)return i(p);F--}return p},N=(p,g,M)=>{const F=g.parentNode;F&&F.replaceChild(p,g);let $=M;for(;$;)$.vnode.el===g&&($.vnode.el=$.subTree.el=p),$=$.parent},j=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,d]}const yr="data-allow-mismatch",Gl={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function hn(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(yr);)e=e.parentElement;const n=e&&e.getAttribute(yr);if(n==null)return!1;if(n==="")return!0;{const s=n.split(",");return t===0&&s.includes("children")?!0:n.split(",").includes(Gl[t])}}Hn().requestIdleCallback;Hn().cancelIdleCallback;function Yl(e,t){if(xt(e)&&e.data==="["){let n=1,s=e.nextSibling;for(;s;){if(s.nodeType===1){if(t(s)===!1)break}else if(xt(s))if(s.data==="]"){if(--n===0)break}else s.data==="["&&n++;s=s.nextSibling}}else t(e)}const pt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function wf(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:s,delay:r=200,hydrate:i,timeout:o,suspensible:l=!0,onError:c}=e;let f=null,a,d=0;const y=()=>(d++,f=null,v()),v=()=>{let S;return f||(S=f=t().catch(b=>{if(b=b instanceof Error?b:new Error(String(b)),c)return new Promise((B,N)=>{c(b,()=>B(y()),()=>N(b),d+1)});throw b}).then(b=>S!==f&&f?f:(b&&(b.__esModule||b[Symbol.toStringTag]==="Module")&&(b=b.default),a=b,b)))};return Ys({name:"AsyncComponentWrapper",__asyncLoader:v,__asyncHydrate(S,b,B){const N=i?()=>{const j=i(B,p=>Yl(S,p));j&&(b.bum||(b.bum=[])).push(j)}:B;a?N():v().then(()=>!b.isUnmounted&&N())},get __asyncResolved(){return a},setup(){const S=ue;if(Xs(S),a)return()=>ns(a,S);const b=p=>{f=null,tn(p,S,13,!s)};if(l&&S.suspense||Mt)return v().then(p=>()=>ns(p,S)).catch(p=>(b(p),()=>s?le(s,{error:p}):null));const B=oe(!1),N=oe(),j=oe(!!r);return r&&setTimeout(()=>{j.value=!1},r),o!=null&&setTimeout(()=>{if(!B.value&&!N.value){const p=new Error(`Async component timed out after ${o}ms.`);b(p),N.value=p}},o),v().then(()=>{B.value=!0,S.parent&&nn(S.parent.vnode)&&S.parent.update()}).catch(p=>{b(p),N.value=p}),()=>{if(B.value&&a)return ns(a,S);if(N.value&&s)return le(s,{error:N.value});if(n&&!j.value)return le(n)}}})}function ns(e,t){const{ref:n,props:s,children:r,ce:i}=t.vnode,o=le(e,s,r);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const nn=e=>e.type.__isKeepAlive;function Xl(e,t){Ui(e,"a",t)}function Jl(e,t){Ui(e,"da",t)}function Ui(e,t,n=ue){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(kn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)nn(r.parent.vnode)&&zl(s,t,n,r),r=r.parent}}function zl(e,t,n,s){const r=kn(t,e,s,!0);Bn(()=>{Hs(s[t],r)},n)}function kn(e,t,n=ue,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{rt();const l=sn(n),c=He(t,n,e,o);return l(),it(),c});return s?r.unshift(i):r.push(i),i}}const Xe=e=>(t,n=ue)=>{(!Mt||e==="sp")&&kn(e,(...s)=>t(...s),n)},Ql=Xe("bm"),Lt=Xe("m"),Zl=Xe("bu"),ec=Xe("u"),ki=Xe("bum"),Bn=Xe("um"),tc=Xe("sp"),nc=Xe("rtg"),sc=Xe("rtc");function rc(e,t=ue){kn("ec",e,t)}const Bi="components";function Sf(e,t){return Ki(Bi,e,!0,t)||e}const Wi=Symbol.for("v-ndc");function xf(e){return re(e)?Ki(Bi,e,!1)||e:e||Wi}function Ki(e,t,n=!0,s=!1){const r=de||ue;if(r){const i=r.type;{const l=Bc(i,!1);if(l&&(l===t||l===Le(t)||l===Fn(Le(t))))return i}const o=vr(r[e]||i[e],t)||vr(r.appContext[e],t);return!o&&s?i:o}}function vr(e,t){return e&&(e[t]||e[Le(t)]||e[Fn(Le(t))])}function Ef(e,t,n,s){let r;const i=n,o=K(e);if(o||re(e)){const l=o&&ht(e);let c=!1;l&&(c=!Pe(e),e=Dn(e)),r=new Array(e.length);for(let f=0,a=e.length;ft(l,c,void 0,i));else{const l=Object.keys(e);r=new Array(l.length);for(let c=0,f=l.length;cJt(t)?!(t.type===ve||t.type===Se&&!qi(t.children)):!0)?e:null}function Cf(e,t){const n={};for(const s in e)n[/[A-Z]/.test(s)?`on:${s}`:vn(s)]=e[s];return n}const Ts=e=>e?mo(e)?Gn(e):Ts(e.parent):null,Ut=ce(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=>Ts(e.parent),$root:e=>Ts(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Js(e),$forceUpdate:e=>e.f||(e.f=()=>{Gs(e.update)}),$nextTick:e=>e.n||(e.n=Un.bind(e.proxy)),$watch:e=>Cc.bind(e)}),ss=(e,t)=>e!==Z&&!e.__isScriptSetup&&z(e,t),ic={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const v=o[t];if(v!==void 0)switch(v){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(ss(s,t))return o[t]=1,s[t];if(r!==Z&&z(r,t))return o[t]=2,r[t];if((f=e.propsOptions[0])&&z(f,t))return o[t]=3,i[t];if(n!==Z&&z(n,t))return o[t]=4,n[t];Cs&&(o[t]=0)}}const a=Ut[t];let d,y;if(a)return t==="$attrs"&&me(e.attrs,"get",""),a(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==Z&&z(n,t))return o[t]=4,n[t];if(y=c.config.globalProperties,z(y,t))return y[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return ss(r,t)?(r[t]=n,!0):s!==Z&&z(s,t)?(s[t]=n,!0):z(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==Z&&z(e,o)||ss(t,o)||(l=i[0])&&z(l,o)||z(s,o)||z(Ut,o)||z(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:z(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Af(){return oc().slots}function oc(){const e=qn();return e.setupContext||(e.setupContext=vo(e))}function br(e){return K(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Cs=!0;function lc(e){const t=Js(e),n=e.proxy,s=e.ctx;Cs=!1,t.beforeCreate&&_r(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:c,inject:f,created:a,beforeMount:d,mounted:y,beforeUpdate:v,updated:S,activated:b,deactivated:B,beforeDestroy:N,beforeUnmount:j,destroyed:p,unmounted:g,render:M,renderTracked:F,renderTriggered:$,errorCaptured:V,serverPrefetch:R,expose:_,inheritAttrs:I,components:E,directives:W,filters:se}=t;if(f&&cc(f,s,null),o)for(const Y in o){const D=o[Y];q(D)&&(s[Y]=D.bind(n))}if(r){const Y=r.call(n,n);ne(Y)&&(e.data=jn(Y))}if(Cs=!0,i)for(const Y in i){const D=i[Y],he=q(D)?D.bind(n,n):q(D.get)?D.get.bind(n,n):ke,rn=!q(D)&&q(D.set)?D.set.bind(n):ke,ot=ie({get:he,set:rn});Object.defineProperty(s,Y,{enumerable:!0,configurable:!0,get:()=>ot.value,set:De=>ot.value=De})}if(l)for(const Y in l)Gi(l[Y],s,n,Y);if(c){const Y=q(c)?c.call(n):c;Reflect.ownKeys(Y).forEach(D=>{pc(D,Y[D])})}a&&_r(a,e,"c");function U(Y,D){K(D)?D.forEach(he=>Y(he.bind(n))):D&&Y(D.bind(n))}if(U(Ql,d),U(Lt,y),U(Zl,v),U(ec,S),U(Xl,b),U(Jl,B),U(rc,V),U(sc,F),U(nc,$),U(ki,j),U(Bn,g),U(tc,R),K(_))if(_.length){const Y=e.exposed||(e.exposed={});_.forEach(D=>{Object.defineProperty(Y,D,{get:()=>n[D],set:he=>n[D]=he})})}else e.exposed||(e.exposed={});M&&e.render===ke&&(e.render=M),I!=null&&(e.inheritAttrs=I),E&&(e.components=E),W&&(e.directives=W),R&&Xs(e)}function cc(e,t,n=ke){K(e)&&(e=As(e));for(const s in e){const r=e[s];let i;ne(r)?"default"in r?i=Ot(r.from||s,r.default,!0):i=Ot(r.from||s):i=Ot(r),fe(i)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[s]=i}}function _r(e,t,n){He(K(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Gi(e,t,n,s){let r=s.includes(".")?lo(n,s):()=>n[s];if(re(e)){const i=t[e];q(i)&&Fe(r,i)}else if(q(e))Fe(r,e.bind(n));else if(ne(e))if(K(e))e.forEach(i=>Gi(i,t,n,s));else{const i=q(e.handler)?e.handler.bind(n):t[e.handler];q(i)&&Fe(r,i,e)}}function Js(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Pn(c,f,o,!0)),Pn(c,t,o)),ne(t)&&i.set(t,c),c}function Pn(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&Pn(e,i,n,!0),r&&r.forEach(o=>Pn(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=ac[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const ac={data:wr,props:Sr,emits:Sr,methods:$t,computed:$t,beforeCreate:be,created:be,beforeMount:be,mounted:be,beforeUpdate:be,updated:be,beforeDestroy:be,beforeUnmount:be,destroyed:be,unmounted:be,activated:be,deactivated:be,errorCaptured:be,serverPrefetch:be,components:$t,directives:$t,watch:uc,provide:wr,inject:fc};function wr(e,t){return t?e?function(){return ce(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function fc(e,t){return $t(As(e),As(t))}function As(e){if(K(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(s&&s.proxy):t}}const Xi={},Ji=()=>Object.create(Xi),zi=e=>Object.getPrototypeOf(e)===Xi;function gc(e,t,n,s=!1){const r={},i=Ji();e.propsDefaults=Object.create(null),Qi(e,t,r,i);for(const o in e.propsOptions[0])o in r||(r[o]=void 0);n?e.props=s?r:wl(r):e.type.props?e.props=r:e.props=i,e.attrs=i}function mc(e,t,n,s){const{props:r,attrs:i,vnode:{patchFlag:o}}=e,l=J(r),[c]=e.propsOptions;let f=!1;if((s||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let d=0;d{c=!0;const[y,v]=Zi(d,t,!0);ce(o,y),v&&l.push(...v)};!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)&&s.set(e,Et),Et;if(K(i))for(let a=0;ae[0]==="_"||e==="$stable",zs=e=>K(e)?e.map(Me):[Me(e)],vc=(e,t,n)=>{if(t._n)return t;const s=$l((...r)=>zs(t(...r)),n);return s._c=!1,s},to=(e,t,n)=>{const s=e._ctx;for(const r in e){if(eo(r))continue;const i=e[r];if(q(i))t[r]=vc(r,i,s);else if(i!=null){const o=zs(i);t[r]=()=>o}}},no=(e,t)=>{const n=zs(t);e.slots.default=()=>n},so=(e,t,n)=>{for(const s in t)(n||s!=="_")&&(e[s]=t[s])},bc=(e,t,n)=>{const s=e.slots=Ji();if(e.vnode.shapeFlag&32){const r=t._;r?(so(s,t,n),n&&li(s,"_",r,!0)):to(t,s)}else t&&no(e,t)},_c=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=Z;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:so(r,t,n):(i=!t.$stable,to(t,r)),o=t}else t&&(no(e,t),o={default:1});if(i)for(const l in r)!eo(l)&&o[l]==null&&delete r[l]},xe=fo;function wc(e){return ro(e)}function Sc(e){return ro(e,ql)}function ro(e,t){const n=Hn();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:c,setText:f,setElementText:a,parentNode:d,nextSibling:y,setScopeId:v=ke,insertStaticContent:S}=e,b=(u,h,m,T=null,w=null,x=null,P=void 0,O=null,A=!!h.dynamicChildren)=>{if(u===h)return;u&&!ut(u,h)&&(T=on(u),De(u,w,x,!0),u=null),h.patchFlag===-2&&(A=!1,h.dynamicChildren=null);const{type:C,ref:k,shapeFlag:L}=h;switch(C){case gt:B(u,h,m,T);break;case ve:N(u,h,m,T);break;case kt:u==null&&j(h,m,T,P);break;case Se:E(u,h,m,T,w,x,P,O,A);break;default:L&1?M(u,h,m,T,w,x,P,O,A):L&6?W(u,h,m,T,w,x,P,O,A):(L&64||L&128)&&C.process(u,h,m,T,w,x,P,O,A,vt)}k!=null&&w&&Mn(k,u&&u.ref,x,h||u,!h)},B=(u,h,m,T)=>{if(u==null)s(h.el=l(h.children),m,T);else{const w=h.el=u.el;h.children!==u.children&&f(w,h.children)}},N=(u,h,m,T)=>{u==null?s(h.el=c(h.children||""),m,T):h.el=u.el},j=(u,h,m,T)=>{[u.el,u.anchor]=S(u.children,h,m,T,u.el,u.anchor)},p=({el:u,anchor:h},m,T)=>{let w;for(;u&&u!==h;)w=y(u),s(u,m,T),u=w;s(h,m,T)},g=({el:u,anchor:h})=>{let m;for(;u&&u!==h;)m=y(u),r(u),u=m;r(h)},M=(u,h,m,T,w,x,P,O,A)=>{h.type==="svg"?P="svg":h.type==="math"&&(P="mathml"),u==null?F(h,m,T,w,x,P,O,A):R(u,h,w,x,P,O,A)},F=(u,h,m,T,w,x,P,O)=>{let A,C;const{props:k,shapeFlag:L,transition:H,dirs:G}=u;if(A=u.el=o(u.type,x,k&&k.is,k),L&8?a(A,u.children):L&16&&V(u.children,A,null,T,w,rs(u,x),P,O),G&&Ue(u,null,T,"created"),$(A,u,u.scopeId,P,T),k){for(const ee in k)ee!=="value"&&!Ct(ee)&&i(A,ee,null,k[ee],x,T);"value"in k&&i(A,"value",null,k.value,x),(C=k.onVnodeBeforeMount)&&Oe(C,T,u)}G&&Ue(u,null,T,"beforeMount");const X=io(w,H);X&&H.beforeEnter(A),s(A,h,m),((C=k&&k.onVnodeMounted)||X||G)&&xe(()=>{C&&Oe(C,T,u),X&&H.enter(A),G&&Ue(u,null,T,"mounted")},w)},$=(u,h,m,T,w)=>{if(m&&v(u,m),T)for(let x=0;x{for(let C=A;C{const O=h.el=u.el;let{patchFlag:A,dynamicChildren:C,dirs:k}=h;A|=u.patchFlag&16;const L=u.props||Z,H=h.props||Z;let G;if(m&<(m,!1),(G=H.onVnodeBeforeUpdate)&&Oe(G,m,h,u),k&&Ue(h,u,m,"beforeUpdate"),m&<(m,!0),(L.innerHTML&&H.innerHTML==null||L.textContent&&H.textContent==null)&&a(O,""),C?_(u.dynamicChildren,C,O,m,T,rs(h,w),x):P||D(u,h,O,null,m,T,rs(h,w),x,!1),A>0){if(A&16)I(O,L,H,m,w);else if(A&2&&L.class!==H.class&&i(O,"class",null,H.class,w),A&4&&i(O,"style",L.style,H.style,w),A&8){const X=h.dynamicProps;for(let ee=0;ee{G&&Oe(G,m,h,u),k&&Ue(h,u,m,"updated")},T)},_=(u,h,m,T,w,x,P)=>{for(let O=0;O{if(h!==m){if(h!==Z)for(const x in h)!Ct(x)&&!(x in m)&&i(u,x,h[x],null,w,T);for(const x in m){if(Ct(x))continue;const P=m[x],O=h[x];P!==O&&x!=="value"&&i(u,x,O,P,w,T)}"value"in m&&i(u,"value",h.value,m.value,w)}},E=(u,h,m,T,w,x,P,O,A)=>{const C=h.el=u?u.el:l(""),k=h.anchor=u?u.anchor:l("");let{patchFlag:L,dynamicChildren:H,slotScopeIds:G}=h;G&&(O=O?O.concat(G):G),u==null?(s(C,m,T),s(k,m,T),V(h.children||[],m,k,w,x,P,O,A)):L>0&&L&64&&H&&u.dynamicChildren?(_(u.dynamicChildren,H,m,w,x,P,O),(h.key!=null||w&&h===w.subTree)&&Qs(u,h,!0)):D(u,h,m,k,w,x,P,O,A)},W=(u,h,m,T,w,x,P,O,A)=>{h.slotScopeIds=O,u==null?h.shapeFlag&512?w.ctx.activate(h,m,T,P,A):se(h,m,T,w,x,P,A):ae(u,h,A)},se=(u,h,m,T,w,x,P)=>{const O=u.component=jc(u,T,w);if(nn(u)&&(O.ctx.renderer=vt),Vc(O,!1,P),O.asyncDep){if(w&&w.registerDep(O,U,P),!u.el){const A=O.subTree=le(ve);N(null,A,h,m)}}else U(O,u,h,m,w,x,P)},ae=(u,h,m)=>{const T=h.component=u.component;if(Pc(u,h,m))if(T.asyncDep&&!T.asyncResolved){Y(T,h,m);return}else T.next=h,T.update();else h.el=u.el,T.vnode=h},U=(u,h,m,T,w,x,P)=>{const O=()=>{if(u.isMounted){let{next:L,bu:H,u:G,parent:X,vnode:ee}=u;{const Te=oo(u);if(Te){L&&(L.el=ee.el,Y(u,L,P)),Te.asyncDep.then(()=>{u.isUnmounted||O()});return}}let Q=L,Ee;lt(u,!1),L?(L.el=ee.el,Y(u,L,P)):L=ee,H&&bn(H),(Ee=L.props&&L.props.onVnodeBeforeUpdate)&&Oe(Ee,X,L,ee),lt(u,!0);const pe=is(u),Ie=u.subTree;u.subTree=pe,b(Ie,pe,d(Ie.el),on(Ie),u,w,x),L.el=pe.el,Q===null&&Lc(u,pe.el),G&&xe(G,w),(Ee=L.props&&L.props.onVnodeUpdated)&&xe(()=>Oe(Ee,X,L,ee),w)}else{let L;const{el:H,props:G}=h,{bm:X,m:ee,parent:Q,root:Ee,type:pe}=u,Ie=pt(h);if(lt(u,!1),X&&bn(X),!Ie&&(L=G&&G.onVnodeBeforeMount)&&Oe(L,Q,h),lt(u,!0),H&&Jn){const Te=()=>{u.subTree=is(u),Jn(H,u.subTree,u,w,null)};Ie&&pe.__asyncHydrate?pe.__asyncHydrate(H,u,Te):Te()}else{Ee.ce&&Ee.ce._injectChildStyle(pe);const Te=u.subTree=is(u);b(null,Te,m,T,u,w,x),h.el=Te.el}if(ee&&xe(ee,w),!Ie&&(L=G&&G.onVnodeMounted)){const Te=h;xe(()=>Oe(L,Q,Te),w)}(h.shapeFlag&256||Q&&pt(Q.vnode)&&Q.vnode.shapeFlag&256)&&u.a&&xe(u.a,w),u.isMounted=!0,h=m=T=null}};u.scope.on();const A=u.effect=new di(O);u.scope.off();const C=u.update=A.run.bind(A),k=u.job=A.runIfDirty.bind(A);k.i=u,k.id=u.uid,A.scheduler=()=>Gs(k),lt(u,!0),C()},Y=(u,h,m)=>{h.component=u;const T=u.vnode.props;u.vnode=h,u.next=null,mc(u,h.props,T,m),_c(u,h.children,m),rt(),dr(u),it()},D=(u,h,m,T,w,x,P,O,A=!1)=>{const C=u&&u.children,k=u?u.shapeFlag:0,L=h.children,{patchFlag:H,shapeFlag:G}=h;if(H>0){if(H&128){rn(C,L,m,T,w,x,P,O,A);return}else if(H&256){he(C,L,m,T,w,x,P,O,A);return}}G&8?(k&16&&It(C,w,x),L!==C&&a(m,L)):k&16?G&16?rn(C,L,m,T,w,x,P,O,A):It(C,w,x,!0):(k&8&&a(m,""),G&16&&V(L,m,T,w,x,P,O,A))},he=(u,h,m,T,w,x,P,O,A)=>{u=u||Et,h=h||Et;const C=u.length,k=h.length,L=Math.min(C,k);let H;for(H=0;Hk?It(u,w,x,!0,!1,L):V(h,m,T,w,x,P,O,A,L)},rn=(u,h,m,T,w,x,P,O,A)=>{let C=0;const k=h.length;let L=u.length-1,H=k-1;for(;C<=L&&C<=H;){const G=u[C],X=h[C]=A?et(h[C]):Me(h[C]);if(ut(G,X))b(G,X,m,null,w,x,P,O,A);else break;C++}for(;C<=L&&C<=H;){const G=u[L],X=h[H]=A?et(h[H]):Me(h[H]);if(ut(G,X))b(G,X,m,null,w,x,P,O,A);else break;L--,H--}if(C>L){if(C<=H){const G=H+1,X=GH)for(;C<=L;)De(u[C],w,x,!0),C++;else{const G=C,X=C,ee=new Map;for(C=X;C<=H;C++){const Ce=h[C]=A?et(h[C]):Me(h[C]);Ce.key!=null&&ee.set(Ce.key,C)}let Q,Ee=0;const pe=H-X+1;let Ie=!1,Te=0;const Nt=new Array(pe);for(C=0;C=pe){De(Ce,w,x,!0);continue}let je;if(Ce.key!=null)je=ee.get(Ce.key);else for(Q=X;Q<=H;Q++)if(Nt[Q-X]===0&&ut(Ce,h[Q])){je=Q;break}je===void 0?De(Ce,w,x,!0):(Nt[je-X]=C+1,je>=Te?Te=je:Ie=!0,b(Ce,h[je],m,null,w,x,P,O,A),Ee++)}const lr=Ie?xc(Nt):Et;for(Q=lr.length-1,C=pe-1;C>=0;C--){const Ce=X+C,je=h[Ce],cr=Ce+1{const{el:x,type:P,transition:O,children:A,shapeFlag:C}=u;if(C&6){ot(u.component.subTree,h,m,T);return}if(C&128){u.suspense.move(h,m,T);return}if(C&64){P.move(u,h,m,vt);return}if(P===Se){s(x,h,m);for(let L=0;LO.enter(x),w);else{const{leave:L,delayLeave:H,afterLeave:G}=O,X=()=>s(x,h,m),ee=()=>{L(x,()=>{X(),G&&G()})};H?H(x,X,ee):ee()}else s(x,h,m)},De=(u,h,m,T=!1,w=!1)=>{const{type:x,props:P,ref:O,children:A,dynamicChildren:C,shapeFlag:k,patchFlag:L,dirs:H,cacheIndex:G}=u;if(L===-2&&(w=!1),O!=null&&Mn(O,null,m,u,!0),G!=null&&(h.renderCache[G]=void 0),k&256){h.ctx.deactivate(u);return}const X=k&1&&H,ee=!pt(u);let Q;if(ee&&(Q=P&&P.onVnodeBeforeUnmount)&&Oe(Q,h,u),k&6)Vo(u.component,m,T);else{if(k&128){u.suspense.unmount(m,T);return}X&&Ue(u,null,h,"beforeUnmount"),k&64?u.type.remove(u,h,m,vt,T):C&&!C.hasOnce&&(x!==Se||L>0&&L&64)?It(C,h,m,!1,!0):(x===Se&&L&384||!w&&k&16)&&It(A,h,m),T&&ir(u)}(ee&&(Q=P&&P.onVnodeUnmounted)||X)&&xe(()=>{Q&&Oe(Q,h,u),X&&Ue(u,null,h,"unmounted")},m)},ir=u=>{const{type:h,el:m,anchor:T,transition:w}=u;if(h===Se){jo(m,T);return}if(h===kt){g(u);return}const x=()=>{r(m),w&&!w.persisted&&w.afterLeave&&w.afterLeave()};if(u.shapeFlag&1&&w&&!w.persisted){const{leave:P,delayLeave:O}=w,A=()=>P(m,x);O?O(u.el,x,A):A()}else x()},jo=(u,h)=>{let m;for(;u!==h;)m=y(u),r(u),u=m;r(h)},Vo=(u,h,m)=>{const{bum:T,scope:w,job:x,subTree:P,um:O,m:A,a:C}=u;Er(A),Er(C),T&&bn(T),w.stop(),x&&(x.flags|=8,De(P,u,h,m)),O&&xe(O,h),xe(()=>{u.isUnmounted=!0},h),h&&h.pendingBranch&&!h.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===h.pendingId&&(h.deps--,h.deps===0&&h.resolve())},It=(u,h,m,T=!1,w=!1,x=0)=>{for(let P=x;P{if(u.shapeFlag&6)return on(u.component.subTree);if(u.shapeFlag&128)return u.suspense.next();const h=y(u.anchor||u.el),m=h&&h[Ii];return m?y(m):h};let Yn=!1;const or=(u,h,m)=>{u==null?h._vnode&&De(h._vnode,null,null,!0):b(h._vnode||null,u,h,null,null,null,m),h._vnode=u,Yn||(Yn=!0,dr(),Rn(),Yn=!1)},vt={p:b,um:De,m:ot,r:ir,mt:se,mc:V,pc:D,pbc:_,n:on,o:e};let Xn,Jn;return t&&([Xn,Jn]=t(vt)),{render:or,hydrate:Xn,createApp:hc(or,Xn)}}function rs({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 lt({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function io(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Qs(e,t,n=!1){const s=e.children,r=t.children;if(K(s)&&K(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function oo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:oo(t)}function Er(e){if(e)for(let t=0;tOt(Ec);function Zs(e,t){return Wn(e,null,t)}function Rf(e,t){return Wn(e,null,{flush:"post"})}function Fe(e,t,n){return Wn(e,t,n)}function Wn(e,t,n=Z){const{immediate:s,deep:r,flush:i,once:o}=n,l=ce({},n),c=t&&s||!t&&i!=="post";let f;if(Mt){if(i==="sync"){const v=Tc();f=v.__watcherHandles||(v.__watcherHandles=[])}else if(!c){const v=()=>{};return v.stop=ke,v.resume=ke,v.pause=ke,v}}const a=ue;l.call=(v,S,b)=>He(v,a,S,b);let d=!1;i==="post"?l.scheduler=v=>{xe(v,a&&a.suspense)}:i!=="sync"&&(d=!0,l.scheduler=(v,S)=>{S?v():Gs(v)}),l.augmentJob=v=>{t&&(v.flags|=4),d&&(v.flags|=2,a&&(v.id=a.uid,v.i=a))};const y=Il(e,t,l);return Mt&&(f?f.push(y):c&&y()),y}function Cc(e,t,n){const s=this.proxy,r=re(e)?e.includes(".")?lo(s,e):()=>s[e]:e.bind(s,s);let i;q(t)?i=t:(i=t.handler,n=t);const o=sn(this),l=Wn(r,i.bind(s),n);return o(),l}function lo(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;rt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Le(t)}Modifiers`]||e[`${st(t)}Modifiers`];function Rc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||Z;let r=n;const i=t.startsWith("update:"),o=i&&Ac(s,t.slice(7));o&&(o.trim&&(r=n.map(a=>re(a)?a.trim():a)),o.number&&(r=n.map(vs)));let l,c=s[l=vn(t)]||s[l=vn(Le(t))];!c&&i&&(c=s[l=vn(st(t))]),c&&He(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,He(f,e,6,r)}}function co(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!q(e)){const c=f=>{const a=co(f,t,!0);a&&(l=!0,ce(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)&&s.set(e,null),null):(K(i)?i.forEach(c=>o[c]=null):ce(o,i),ne(e)&&s.set(e,o),o)}function Kn(e,t){return!e||!Zt(t)?!1:(t=t.slice(2).replace(/Once$/,""),z(e,t[0].toLowerCase()+t.slice(1))||z(e,st(t))||z(e,t))}function is(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[i],slots:o,attrs:l,emit:c,render:f,renderCache:a,props:d,data:y,setupState:v,ctx:S,inheritAttrs:b}=e,B=On(e);let N,j;try{if(n.shapeFlag&4){const g=r||s,M=g;N=Me(f.call(M,g,a,d,v,y,S)),j=l}else{const g=t;N=Me(g.length>1?g(d,{attrs:l,slots:o,emit:c}):g(d,null)),j=t.props?l:Oc(l)}}catch(g){Bt.length=0,tn(g,e,1),N=le(ve)}let p=N;if(j&&b!==!1){const g=Object.keys(j),{shapeFlag:M}=p;g.length&&M&7&&(i&&g.some(Fs)&&(j=Mc(j,i)),p=nt(p,j,!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,On(B),N}const Oc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Zt(n))&&((t||(t={}))[n]=e[n]);return t},Mc=(e,t)=>{const n={};for(const s in e)(!Fs(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Pc(e,t,n){const{props:s,children:r,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 s?Tr(s,o,f):!!o;if(c&8){const a=t.dynamicProps;for(let d=0;de.__isSuspense;function fo(e,t){t&&t.pendingBranch?K(e)?t.effects.push(...e):t.effects.push(e):Hl(e)}const Se=Symbol.for("v-fgt"),gt=Symbol.for("v-txt"),ve=Symbol.for("v-cmt"),kt=Symbol.for("v-stc"),Bt=[];let Ae=null;function Os(e=!1){Bt.push(Ae=e?null:[])}function Ic(){Bt.pop(),Ae=Bt[Bt.length-1]||null}let Xt=1;function Cr(e){Xt+=e,e<0&&Ae&&(Ae.hasOnce=!0)}function uo(e){return e.dynamicChildren=Xt>0?Ae||Et:null,Ic(),Xt>0&&Ae&&Ae.push(e),e}function Of(e,t,n,s,r,i){return uo(po(e,t,n,s,r,i,!0))}function Ms(e,t,n,s,r){return uo(le(e,t,n,s,r,!0))}function Jt(e){return e?e.__v_isVNode===!0:!1}function ut(e,t){return e.type===t.type&&e.key===t.key}const ho=({key:e})=>e??null,Sn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?re(e)||fe(e)||q(e)?{i:de,r:e,k:t,f:!!n}:e:null);function po(e,t=null,n=null,s=0,r=null,i=e===Se?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ho(t),ref:t&&Sn(t),scopeId:Li,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:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:de};return l?(er(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=re(n)?8:16),Xt>0&&!o&&Ae&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Ae.push(c),c}const le=Nc;function Nc(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===Wi)&&(e=ve),Jt(e)){const l=nt(e,t,!0);return n&&er(l,n),Xt>0&&!i&&Ae&&(l.shapeFlag&6?Ae[Ae.indexOf(e)]=l:Ae.push(l)),l.patchFlag=-2,l}if(Wc(e)&&(e=e.__vccOpts),t){t=Fc(t);let{class:l,style:c}=t;l&&!re(l)&&(t.class=js(l)),ne(c)&&(Ks(c)&&!K(c)&&(c=ce({},c)),t.style=Ds(c))}const o=re(e)?1:ao(e)?128:Ni(e)?64:ne(e)?4:q(e)?2:0;return po(e,t,n,s,r,o,i,!0)}function Fc(e){return e?Ks(e)||zi(e)?ce({},e):e:null}function nt(e,t,n=!1,s=!1){const{props:r,ref:i,patchFlag:o,children:l,transition:c}=e,f=t?Hc(r||{},t):r,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&ho(f),ref:t&&t.ref?n&&i?K(i)?i.concat(Sn(t)):[i,Sn(t)]:Sn(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&&s&&Yt(a,c.clone(a)),a}function go(e=" ",t=0){return le(gt,null,e,t)}function Mf(e,t){const n=le(kt,null,e);return n.staticCount=t,n}function Pf(e="",t=!1){return t?(Os(),Ms(ve,null,e)):le(ve,null,e)}function Me(e){return e==null||typeof e=="boolean"?le(ve):K(e)?le(Se,null,e.slice()):Jt(e)?et(e):le(gt,null,String(e))}function et(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:nt(e)}function er(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(K(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),er(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!zi(t)?t._ctx=de:r===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),s&64?(n=16,t=[go(t)]):n=8);e.children=t,e.shapeFlag|=n}function Hc(...e){const t={};for(let n=0;nue||de;let Ln,Ps;{const e=Hn(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),i=>{r.length>1?r.forEach(o=>o(i)):r[0](i)}};Ln=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Ps=t("__VUE_SSR_SETTERS__",n=>Mt=n)}const sn=e=>{const t=ue;return Ln(e),e.scope.on(),()=>{e.scope.off(),Ln(t)}},Ar=()=>{ue&&ue.scope.off(),Ln(null)};function mo(e){return e.vnode.shapeFlag&4}let Mt=!1;function Vc(e,t=!1,n=!1){t&&Ps(t);const{props:s,children:r}=e.vnode,i=mo(e);gc(e,s,i,t),bc(e,r,n);const o=i?Uc(e,t):void 0;return t&&Ps(!1),o}function Uc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,ic);const{setup:s}=n;if(s){rt();const r=e.setupContext=s.length>1?vo(e):null,i=sn(e),o=en(s,e,0,[e.props,r]),l=ri(o);if(it(),i(),(l||e.sp)&&!pt(e)&&Xs(e),l){if(o.then(Ar,Ar),t)return o.then(c=>{Rr(e,c,t)}).catch(c=>{tn(c,e,0)});e.asyncDep=o}else Rr(e,o,t)}else yo(e,t)}function Rr(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ne(t)&&(e.setupState=Ri(t)),yo(e,n)}let Or;function yo(e,t,n){const s=e.type;if(!e.render){if(!t&&Or&&!s.render){const r=s.template||Js(e).template;if(r){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,f=ce(ce({isCustomElement:i,delimiters:l},o),c);s.render=Or(r,f)}}e.render=s.render||ke}{const r=sn(e);rt();try{lc(e)}finally{it(),r()}}}const kc={get(e,t){return me(e,"get",""),e[t]}};function vo(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,kc),slots:e.slots,emit:e.emit,expose:t}}function Gn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Ri(_n(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Ut)return Ut[n](e)},has(t,n){return n in t||n in Ut}})):e.proxy}function Bc(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function Wc(e){return q(e)&&"__vccOpts"in e}const ie=(e,t)=>Pl(e,t,Mt);function Ls(e,t,n){const s=arguments.length;return s===2?ne(t)&&!K(t)?Jt(t)?le(e,null,[t]):le(e,t):le(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Jt(n)&&(n=[n]),le(e,t,n))}const Kc="3.5.12";/** +* @vue/runtime-dom v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Is;const Mr=typeof window<"u"&&window.trustedTypes;if(Mr)try{Is=Mr.createPolicy("vue",{createHTML:e=>e})}catch{}const bo=Is?e=>Is.createHTML(e):e=>e,qc="http://www.w3.org/2000/svg",Gc="http://www.w3.org/1998/Math/MathML",Ke=typeof document<"u"?document:null,Pr=Ke&&Ke.createElement("template"),Yc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Ke.createElementNS(qc,e):t==="mathml"?Ke.createElementNS(Gc,e):n?Ke.createElement(e,{is:n}):Ke.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},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,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{Pr.innerHTML=bo(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=Pr.content;if(s==="svg"||s==="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]}},Je="transition",Ht="animation",zt=Symbol("_vtc"),_o={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},Xc=ce({},Hi,_o),Jc=e=>(e.displayName="Transition",e.props=Xc,e),Lf=Jc((e,{slots:t})=>Ls(Bl,zc(e),t)),ct=(e,t=[])=>{K(e)?e.forEach(n=>n(...t)):e&&e(...t)},Lr=e=>e?K(e)?e.some(t=>t.length>1):e.length>1:!1;function zc(e){const t={};for(const E in e)E in _o||(t[E]=e[E]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,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:d=`${n}-leave-from`,leaveActiveClass:y=`${n}-leave-active`,leaveToClass:v=`${n}-leave-to`}=e,S=Qc(r),b=S&&S[0],B=S&&S[1],{onBeforeEnter:N,onEnter:j,onEnterCancelled:p,onLeave:g,onLeaveCancelled:M,onBeforeAppear:F=N,onAppear:$=j,onAppearCancelled:V=p}=t,R=(E,W,se)=>{at(E,W?a:l),at(E,W?f:o),se&&se()},_=(E,W)=>{E._isLeaving=!1,at(E,d),at(E,v),at(E,y),W&&W()},I=E=>(W,se)=>{const ae=E?$:j,U=()=>R(W,E,se);ct(ae,[W,U]),Ir(()=>{at(W,E?c:i),ze(W,E?a:l),Lr(ae)||Nr(W,s,b,U)})};return ce(t,{onBeforeEnter(E){ct(N,[E]),ze(E,i),ze(E,o)},onBeforeAppear(E){ct(F,[E]),ze(E,c),ze(E,f)},onEnter:I(!1),onAppear:I(!0),onLeave(E,W){E._isLeaving=!0;const se=()=>_(E,W);ze(E,d),ze(E,y),ta(),Ir(()=>{E._isLeaving&&(at(E,d),ze(E,v),Lr(g)||Nr(E,s,B,se))}),ct(g,[E,se])},onEnterCancelled(E){R(E,!1),ct(p,[E])},onAppearCancelled(E){R(E,!0),ct(V,[E])},onLeaveCancelled(E){_(E),ct(M,[E])}})}function Qc(e){if(e==null)return null;if(ne(e))return[os(e.enter),os(e.leave)];{const t=os(e);return[t,t]}}function os(e){return qo(e)}function ze(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[zt]||(e[zt]=new Set)).add(t)}function at(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[zt];n&&(n.delete(t),n.size||(e[zt]=void 0))}function Ir(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Zc=0;function Nr(e,t,n,s){const r=e._endId=++Zc,i=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=ea(e,t);if(!o)return s();const f=o+"end";let a=0;const d=()=>{e.removeEventListener(f,y),i()},y=v=>{v.target===e&&++a>=c&&d()};setTimeout(()=>{a(n[S]||"").split(", "),r=s(`${Je}Delay`),i=s(`${Je}Duration`),o=Fr(r,i),l=s(`${Ht}Delay`),c=s(`${Ht}Duration`),f=Fr(l,c);let a=null,d=0,y=0;t===Je?o>0&&(a=Je,d=o,y=i.length):t===Ht?f>0&&(a=Ht,d=f,y=c.length):(d=Math.max(o,f),a=d>0?o>f?Je:Ht:null,y=a?a===Je?i.length:c.length:0);const v=a===Je&&/\b(transform|all)(,|$)/.test(s(`${Je}Property`).toString());return{type:a,timeout:d,propCount:y,hasTransform:v}}function Fr(e,t){for(;e.lengthHr(n)+Hr(e[s])))}function Hr(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ta(){return document.body.offsetHeight}function na(e,t,n){const s=e[zt];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const $r=Symbol("_vod"),sa=Symbol("_vsh"),ra=Symbol(""),ia=/(^|;)\s*display\s*:/;function oa(e,t,n){const s=e.style,r=re(n);let i=!1;if(n&&!r){if(t)if(re(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&xn(s,l,"")}else for(const o in t)n[o]==null&&xn(s,o,"");for(const o in n)o==="display"&&(i=!0),xn(s,o,n[o])}else if(r){if(t!==n){const o=s[ra];o&&(n+=";"+o),s.cssText=n,i=ia.test(n)}}else t&&e.removeAttribute("style");$r in e&&(e[$r]=i?s.display:"",e[sa]&&(s.display="none"))}const Dr=/\s*!important$/;function xn(e,t,n){if(K(n))n.forEach(s=>xn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=la(e,t);Dr.test(n)?e.setProperty(st(s),n.replace(Dr,""),"important"):e[s]=n}}const jr=["Webkit","Moz","ms"],ls={};function la(e,t){const n=ls[t];if(n)return n;let s=Le(t);if(s!=="filter"&&s in e)return ls[t]=s;s=Fn(s);for(let r=0;rcs||(ua.then(()=>cs=0),cs=Date.now());function ha(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;He(pa(s,n.value),t,5,[s])};return n.value=e,n.attached=da(),n}function pa(e,t){if(K(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Kr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,ga=(e,t,n,s,r,i)=>{const o=r==="svg";t==="class"?na(e,s,o):t==="style"?oa(e,n,s):Zt(t)?Fs(t)||aa(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ma(e,t,s,o))?(kr(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Ur(e,t,s,o,i,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!re(s))?kr(e,Le(t),s,i,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Ur(e,t,s,o))};function ma(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&Kr(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 r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return Kr(t)&&re(n)?!1:t in e}const qr=e=>{const t=e.props["onUpdate:modelValue"]||!1;return K(t)?n=>bn(t,n):t};function ya(e){e.target.composing=!0}function Gr(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const as=Symbol("_assign"),If={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[as]=qr(r);const i=s||r.props&&r.props.type==="number";St(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=vs(l)),e[as](l)}),n&&St(e,"change",()=>{e.value=e.value.trim()}),t||(St(e,"compositionstart",ya),St(e,"compositionend",Gr),St(e,"change",Gr))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:i}},o){if(e[as]=qr(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?vs(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===c)||(e.value=c))}},va=["ctrl","shift","alt","meta"],ba={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)=>va.some(n=>e[`${n}Key`]&&!t.includes(n))},Nf=(e,t)=>{const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(r,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=r=>{if(!("key"in r))return;const i=st(r.key);if(t.some(o=>o===i||_a[o]===i))return e(r)})},wo=ce({patchProp:ga},Yc);let Wt,Yr=!1;function wa(){return Wt||(Wt=wc(wo))}function Sa(){return Wt=Yr?Wt:Sc(wo),Yr=!0,Wt}const Hf=(...e)=>{const t=wa().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=xo(s);if(!r)return;const i=t._component;!q(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const o=n(r,!1,So(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),o},t},$f=(...e)=>{const t=Sa().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=xo(s);if(r)return n(r,!0,So(r))},t};function So(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function xo(e){return re(e)?document.querySelector(e):e}const Df=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},xa=window.__VP_SITE_DATA__;function tr(e){return ui()?(tl(e),!0):!1}function Be(e){return typeof e=="function"?e():Ai(e)}const Eo=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const jf=e=>e!=null,Ea=Object.prototype.toString,Ta=e=>Ea.call(e)==="[object Object]",Qt=()=>{},Xr=Ca();function Ca(){var e,t;return Eo&&((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 Aa(e,t){function n(...s){return new Promise((r,i)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(r).catch(i)})}return n}const To=e=>e();function Ra(e,t={}){let n,s,r=Qt;const i=l=>{clearTimeout(l),r(),r=Qt};return l=>{const c=Be(e),f=Be(t.maxWait);return n&&i(n),c<=0||f!==void 0&&f<=0?(s&&(i(s),s=null),Promise.resolve(l())):new Promise((a,d)=>{r=t.rejectOnCancel?d:a,f&&!s&&(s=setTimeout(()=>{n&&i(n),s=null,a(l())},f)),n=setTimeout(()=>{s&&i(s),s=null,a(l())},c)})}}function Oa(e=To){const t=oe(!0);function n(){t.value=!1}function s(){t.value=!0}const r=(...i)=>{t.value&&e(...i)};return{isActive:Vn(t),pause:n,resume:s,eventFilter:r}}function Ma(e){return qn()}function Co(...e){if(e.length!==1)return Rl(...e);const t=e[0];return typeof t=="function"?Vn(Tl(()=>({get:t,set:Qt}))):oe(t)}function Ao(e,t,n={}){const{eventFilter:s=To,...r}=n;return Fe(e,Aa(s,t),r)}function Pa(e,t,n={}){const{eventFilter:s,...r}=n,{eventFilter:i,pause:o,resume:l,isActive:c}=Oa(s);return{stop:Ao(e,t,{...r,eventFilter:i}),pause:o,resume:l,isActive:c}}function nr(e,t=!0,n){Ma()?Lt(e,n):t?e():Un(e)}function Vf(e,t,n={}){const{debounce:s=0,maxWait:r=void 0,...i}=n;return Ao(e,t,{...i,eventFilter:Ra(s,{maxWait:r})})}function Uf(e,t,n){let s;fe(n)?s={evaluating:n}:s={};const{lazy:r=!1,evaluating:i=void 0,shallow:o=!0,onError:l=Qt}=s,c=oe(!r),f=o?qs(t):oe(t);let a=0;return Zs(async d=>{if(!c.value)return;a++;const y=a;let v=!1;i&&Promise.resolve().then(()=>{i.value=!0});try{const S=await e(b=>{d(()=>{i&&(i.value=!1),v||b()})});y===a&&(f.value=S)}catch(S){l(S)}finally{i&&y===a&&(i.value=!1),v=!0}}),r?ie(()=>(c.value=!0,f.value)):f}const $e=Eo?window:void 0;function Ro(e){var t;const n=Be(e);return(t=n==null?void 0:n.$el)!=null?t:n}function Pt(...e){let t,n,s,r;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,s,r]=e,t=$e):[t,n,s,r]=e,!t)return Qt;Array.isArray(n)||(n=[n]),Array.isArray(s)||(s=[s]);const i=[],o=()=>{i.forEach(a=>a()),i.length=0},l=(a,d,y,v)=>(a.addEventListener(d,y,v),()=>a.removeEventListener(d,y,v)),c=Fe(()=>[Ro(t),Be(r)],([a,d])=>{if(o(),!a)return;const y=Ta(d)?{...d}:d;i.push(...n.flatMap(v=>s.map(S=>l(a,v,S,y))))},{immediate:!0,flush:"post"}),f=()=>{c(),o()};return tr(f),f}function La(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function kf(...e){let t,n,s={};e.length===3?(t=e[0],n=e[1],s=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],s=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:r=$e,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=s,c=La(t);return Pt(r,i,a=>{a.repeat&&Be(l)||c(a)&&n(a)},o)}function Ia(){const e=oe(!1),t=qn();return t&&Lt(()=>{e.value=!0},t),e}function Na(e){const t=Ia();return ie(()=>(t.value,!!e()))}function Oo(e,t={}){const{window:n=$e}=t,s=Na(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let r;const i=oe(!1),o=f=>{i.value=f.matches},l=()=>{r&&("removeEventListener"in r?r.removeEventListener("change",o):r.removeListener(o))},c=Zs(()=>{s.value&&(l(),r=n.matchMedia(Be(e)),"addEventListener"in r?r.addEventListener("change",o):r.addListener(o),i.value=r.matches)});return tr(()=>{c(),l(),r=void 0}),i}const pn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},gn="__vueuse_ssr_handlers__",Fa=Ha();function Ha(){return gn in pn||(pn[gn]=pn[gn]||{}),pn[gn]}function Mo(e,t){return Fa[e]||t}function sr(e){return Oo("(prefers-color-scheme: dark)",e)}function $a(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 Da={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()}},Jr="vueuse-storage";function rr(e,t,n,s={}){var r;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:f=!1,shallow:a,window:d=$e,eventFilter:y,onError:v=_=>{console.error(_)},initOnMounted:S}=s,b=(a?qs:oe)(typeof t=="function"?t():t);if(!n)try{n=Mo("getDefaultStorage",()=>{var _;return(_=$e)==null?void 0:_.localStorage})()}catch(_){v(_)}if(!n)return b;const B=Be(t),N=$a(B),j=(r=s.serializer)!=null?r:Da[N],{pause:p,resume:g}=Pa(b,()=>F(b.value),{flush:i,deep:o,eventFilter:y});d&&l&&nr(()=>{n instanceof Storage?Pt(d,"storage",V):Pt(d,Jr,R),S&&V()}),S||V();function M(_,I){if(d){const E={key:e,oldValue:_,newValue:I,storageArea:n};d.dispatchEvent(n instanceof Storage?new StorageEvent("storage",E):new CustomEvent(Jr,{detail:E}))}}function F(_){try{const I=n.getItem(e);if(_==null)M(I,null),n.removeItem(e);else{const E=j.write(_);I!==E&&(n.setItem(e,E),M(I,E))}}catch(I){v(I)}}function $(_){const I=_?_.newValue:n.getItem(e);if(I==null)return c&&B!=null&&n.setItem(e,j.write(B)),B;if(!_&&f){const E=j.read(I);return typeof f=="function"?f(E,B):N==="object"&&!Array.isArray(E)?{...B,...E}:E}else return typeof I!="string"?I:j.read(I)}function V(_){if(!(_&&_.storageArea!==n)){if(_&&_.key==null){b.value=B;return}if(!(_&&_.key!==e)){p();try{(_==null?void 0:_.newValue)!==j.write(b.value)&&(b.value=$(_))}catch(I){v(I)}finally{_?Un(g):g()}}}}function R(_){V(_.detail)}return b}const ja="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Va(e={}){const{selector:t="html",attribute:n="class",initialValue:s="auto",window:r=$e,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:f,disableTransition:a=!0}=e,d={auto:"",light:"light",dark:"dark",...e.modes||{}},y=sr({window:r}),v=ie(()=>y.value?"dark":"light"),S=c||(o==null?Co(s):rr(o,s,i,{window:r,listenToStorageChanges:l})),b=ie(()=>S.value==="auto"?v.value:S.value),B=Mo("updateHTMLAttrs",(g,M,F)=>{const $=typeof g=="string"?r==null?void 0:r.document.querySelector(g):Ro(g);if(!$)return;const V=new Set,R=new Set;let _=null;if(M==="class"){const E=F.split(/\s/g);Object.values(d).flatMap(W=>(W||"").split(/\s/g)).filter(Boolean).forEach(W=>{E.includes(W)?V.add(W):R.add(W)})}else _={key:M,value:F};if(V.size===0&&R.size===0&&_===null)return;let I;a&&(I=r.document.createElement("style"),I.appendChild(document.createTextNode(ja)),r.document.head.appendChild(I));for(const E of V)$.classList.add(E);for(const E of R)$.classList.remove(E);_&&$.setAttribute(_.key,_.value),a&&(r.getComputedStyle(I).opacity,document.head.removeChild(I))});function N(g){var M;B(t,n,(M=d[g])!=null?M:g)}function j(g){e.onChanged?e.onChanged(g,N):N(g)}Fe(b,j,{flush:"post",immediate:!0}),nr(()=>j(b.value));const p=ie({get(){return f?S.value:b.value},set(g){S.value=g}});try{return Object.assign(p,{store:S,system:v,state:b})}catch{return p}}function Ua(e={}){const{valueDark:t="dark",valueLight:n="",window:s=$e}=e,r=Va({...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(()=>r.system?r.system.value:sr({window:s}).value?"dark":"light");return ie({get(){return r.value==="dark"},set(l){const c=l?"dark":"light";i.value===c?r.value="auto":r.value=c}})}function fs(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function Bf(e,t,n={}){const{window:s=$e}=n;return rr(e,t,s==null?void 0:s.localStorage,n)}function Po(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 us=new WeakMap;function Wf(e,t=!1){const n=oe(t);let s=null,r="";Fe(Co(e),l=>{const c=fs(Be(l));if(c){const f=c;if(us.get(f)||us.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(r=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=fs(Be(e));!l||n.value||(Xr&&(s=Pt(l,"touchmove",c=>{ka(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=fs(Be(e));!l||!n.value||(Xr&&(s==null||s()),l.style.overflow=r,us.delete(l),n.value=!1)};return tr(o),ie({get(){return n.value},set(l){l?i():o()}})}function Kf(e,t,n={}){const{window:s=$e}=n;return rr(e,t,s==null?void 0:s.sessionStorage,n)}function qf(e={}){const{window:t=$e,behavior:n="auto"}=e;if(!t)return{x:oe(0),y:oe(0)};const s=oe(t.scrollX),r=oe(t.scrollY),i=ie({get(){return s.value},set(l){scrollTo({left:l,behavior:n})}}),o=ie({get(){return r.value},set(l){scrollTo({top:l,behavior:n})}});return Pt(t,"scroll",()=>{s.value=t.scrollX,r.value=t.scrollY},{capture:!1,passive:!0}),{x:i,y:o}}function Gf(e={}){const{window:t=$e,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:s=Number.POSITIVE_INFINITY,listenOrientation:r=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=oe(n),c=oe(s),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(),nr(f),Pt("resize",f,{passive:!0}),r){const a=Oo("(orientation: portrait)");Fe(a,()=>f())}return{width:l,height:c}}const ds={BASE_URL:"/Rasters.jl/previews/PR807/",DEV:!1,MODE:"production",PROD:!0,SSR:!1};var hs={};const Lo=/^(?:[a-z]+:|\/\/)/i,Ba="vitepress-theme-appearance",Wa=/#.*$/,Ka=/[?#].*$/,qa=/(?:(^|\/)index)?\.(?:md|html)$/,ge=typeof document<"u",Io={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function Ga(e,t,n=!1){if(t===void 0)return!1;if(e=zr(`/${e}`),n)return new RegExp(t).test(e);if(zr(t)!==e)return!1;const s=t.match(Wa);return s?(ge?location.hash:"")===s[0]:!0}function zr(e){return decodeURI(e).replace(Ka,"").replace(qa,"$1")}function Ya(e){return Lo.test(e)}function Xa(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!Ya(n)&&Ga(t,`/${n}/`,!0))||"root"}function Ja(e,t){var s,r,i,o,l,c,f;const n=Xa(e,t);return Object.assign({},e,{localeIndex:n,lang:((s=e.locales[n])==null?void 0:s.lang)??e.lang,dir:((r=e.locales[n])==null?void 0:r.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:Fo(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function No(e,t){const n=t.title||e.title,s=t.titleTemplate??e.titleTemplate;if(typeof s=="string"&&s.includes(":title"))return s.replace(/:title/g,n);const r=za(e.title,s);return n===r.slice(3)?n:`${n}${r}`}function za(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function Qa(e,t){const[n,s]=t;if(n!=="meta")return!1;const r=Object.entries(s)[0];return r==null?!1:e.some(([i,o])=>i===n&&o[r[0]]===r[1])}function Fo(e,t){return[...e.filter(n=>!Qa(t,n)),...t]}const Za=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,ef=/^[a-z]:/i;function Qr(e){const t=ef.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(Za,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const ps=new Set;function tf(e){if(ps.size===0){const n=typeof process=="object"&&(hs==null?void 0:hs.VITE_EXTRA_EXTENSIONS)||(ds==null?void 0:ds.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(s=>ps.add(s))}const t=e.split(".").pop();return t==null||!ps.has(t.toLowerCase())}function Yf(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const nf=Symbol(),mt=qs(xa);function Xf(e){const t=ie(()=>Ja(mt.value,e.data.relativePath)),n=t.value.appearance,s=n==="force-dark"?oe(!0):n==="force-auto"?sr():n?Ua({storageKey:Ba,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):oe(!1),r=oe(ge?location.hash:"");return ge&&window.addEventListener("hashchange",()=>{r.value=location.hash}),Fe(()=>e.data,()=>{r.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(()=>No(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:s,hash:ie(()=>r.value)}}function sf(){const e=Ot(nf);if(!e)throw new Error("vitepress data not properly injected in app");return e}function rf(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function Zr(e){return Lo.test(e)||!e.startsWith("/")?e:rf(mt.value.base,e)}function of(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ge){const n="/Rasters.jl/previews/PR807/";t=Qr(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let s=__VP_HASH_MAP__[t.toLowerCase()];if(s||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",s=__VP_HASH_MAP__[t.toLowerCase()]),!s)return null;t=`${n}assets/${t}.${s}.js`}else t=`./${Qr(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let En=[];function Jf(e){En.push(e),Bn(()=>{En=En.filter(t=>t!==e)})}function lf(){let e=mt.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=ei(e,n);else if(Array.isArray(e))for(const s of e){const r=ei(s,n);if(r){t=r;break}}return t}function ei(e,t){const n=document.querySelector(e);if(!n)return 0;const s=n.getBoundingClientRect().bottom;return s<0?0:s+t}const cf=Symbol(),Ho="http://a.com",af=()=>({path:"/",component:null,data:Io});function zf(e,t){const n=jn(af()),s={route:n,go:r};async function r(l=ge?location.href:"/"){var c,f;l=gs(l),await((c=s.onBeforeRouteChange)==null?void 0:c.call(s,l))!==!1&&(ge&&l!==gs(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((f=s.onAfterRouteChanged)==null?void 0:f.call(s,l)))}let i=null;async function o(l,c=0,f=!1){var y,v;if(await((y=s.onBeforePageLoad)==null?void 0:y.call(s,l))===!1)return;const a=new URL(l,Ho),d=i=a.pathname;try{let S=await e(d);if(!S)throw new Error(`Page not found: ${d}`);if(i===d){i=null;const{default:b,__pageData:B}=S;if(!b)throw new Error(`Invalid route component: ${b}`);await((v=s.onAfterPageLoad)==null?void 0:v.call(s,l)),n.path=ge?d:Zr(d),n.component=_n(b),n.data=_n(B),ge&&Un(()=>{let N=mt.value.base+B.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!mt.value.cleanUrls&&!N.endsWith("/")&&(N+=".html"),N!==a.pathname&&(a.pathname=N,l=N+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let j=null;try{j=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(p){console.warn(p)}if(j){ti(j,a.hash);return}}window.scrollTo(0,c)})}}catch(S){if(!/fetch|Page not found/.test(S.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(S),!f)try{const b=await fetch(mt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await b.json(),await o(l,c,!0);return}catch{}if(i===d){i=null,n.path=ge?d:Zr(d),n.component=t?_n(t):null;const b=ge?d.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={...Io,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:d,pathname:y,hash:v,search:S}=new URL(f,c.baseURI),b=new URL(location.href);d===b.origin&&tf(y)&&(l.preventDefault(),y===b.pathname&&S===b.search?(v!==b.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:b.href,newURL:a}))),v?ti(c,v,c.classList.contains("header-anchor")):window.scrollTo(0,0)):r(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var c;l.state!==null&&(await o(gs(location.href),l.state&&l.state.scrollPosition||0),(c=s.onAfterRouteChanged)==null||c.call(s,location.href))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),s}function ff(){const e=Ot(cf);if(!e)throw new Error("useRouter() is called without provider.");return e}function $o(){return ff().route}function ti(e,t,n=!1){let s=null;try{s=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(r){console.warn(r)}if(s){let r=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(s).paddingTop,10),o=window.scrollY+s.getBoundingClientRect().top-lf()+i;requestAnimationFrame(r)}}function gs(e){const t=new URL(e,Ho);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),mt.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 mn=()=>En.forEach(e=>e()),Qf=Ys({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=$o(),{frontmatter:n,site:s}=sf();return Fe(n,mn,{deep:!0,flush:"post"}),()=>Ls(e.as,s.value.contentProps??{style:{position:"relative"}},[t.component?Ls(t.component,{onVnodeMounted:mn,onVnodeUpdated:mn,onVnodeUnmounted:mn}):"404 Page Not Found"])}}),uf="modulepreload",df=function(e){return"/Rasters.jl/previews/PR807/"+e},ni={},Zf=function(t,n,s){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));r=Promise.allSettled(n.map(c=>{if(c=df(c),c in ni)return;ni[c]=!0;const f=c.endsWith(".css"),a=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${a}`))return;const d=document.createElement("link");if(d.rel=f?"stylesheet":uf,f||(d.as="script"),d.crossOrigin="",d.href=c,l&&d.setAttribute("nonce",l),document.head.appendChild(d),f)return new Promise((y,v)=>{d.addEventListener("load",y),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return r.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},eu=Ys({setup(e,{slots:t}){const n=oe(!1);return Lt(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function tu(){ge&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const s=(n=t.parentElement)==null?void 0:n.parentElement;if(!s)return;const r=Array.from(s.querySelectorAll("input")).indexOf(t);if(r<0)return;const i=s.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(f=>f.classList.contains("active"));if(!o)return;const l=i.children[r];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=s==null?void 0:s.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function nu(){if(ge){const e=new WeakMap;window.addEventListener("click",t=>{var s;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const r=n.parentElement,i=(s=n.nextElementSibling)==null?void 0:s.nextElementSibling;if(!r||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(r.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()),hf(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 hf(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 s=document.getSelection(),r=s?s.rangeCount>0&&s.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),r&&(s.removeAllRanges(),s.addRange(r)),n&&n.focus()}}function su(e,t){let n=!0,s=[];const r=i=>{if(n){n=!1,i.forEach(l=>{const c=ms(l);for(const f of document.head.children)if(f.isEqualNode(c)){s.push(f);return}});return}const o=i.map(ms);s.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 s[c])}),o.forEach(l=>l&&document.head.appendChild(l)),s=[...s,...o].filter(Boolean)};Zs(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],f=No(o,i);f!==document.title&&(document.title=f);const a=l||o.description;let d=document.querySelector("meta[name=description]");d?d.getAttribute("content")!==a&&d.setAttribute("content",a):ms(["meta",{name:"description",content:a}]),r(Fo(o.head,gf(c)))})}function ms([e,t,n]){const s=document.createElement(e);for(const r in t)s.setAttribute(r,t[r]);return n&&(s.innerHTML=n),e==="script"&&t.async==null&&(s.async=!1),s}function pf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function gf(e){return e.filter(t=>!pf(t))}const ys=new Set,Do=()=>document.createElement("link"),mf=e=>{const t=Do();t.rel="prefetch",t.href=e,document.head.appendChild(t)},yf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let yn;const vf=ge&&(yn=Do())&&yn.relList&&yn.relList.supports&&yn.relList.supports("prefetch")?mf:yf;function ru(){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 s=()=>{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(!ys.has(c)){ys.add(c);const f=of(c);f&&vf(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):ys.add(l))})})};Lt(s);const r=$o();Fe(()=>r.path,s),Bn(()=>{n&&n.disconnect()})}export{ki as $,lf as A,Sf as B,Ef as C,qs as D,Jf as E,Se as F,le as G,xf as H,Lo as I,$o as J,Hc as K,Ot as L,Gf as M,Ds as N,kf as O,Un as P,qf as Q,ge as R,Vn as S,Lf as T,wf as U,Zf as V,Wf as W,pc as X,Ff as Y,Cf as Z,Df as _,go as a,Nf as a0,Af as a1,jn as a2,Rl as a3,Ls as a4,Mf as a5,su as a6,cf as a7,Xf as a8,nf as a9,Qf as aa,eu as ab,mt as ac,$f as ad,zf as ae,of as af,ru as ag,nu as ah,tu as ai,Be as aj,Ro as ak,jf as al,tr as am,Uf as an,Kf as ao,Bf as ap,Vf as aq,ff as ar,Pt as as,bf as at,If as au,fe as av,_f as aw,_n as ax,Hf as ay,Yf as az,Ms as b,Of as c,Ys as d,Pf as e,tf as f,Zr as g,ie as h,Ya as i,po as j,Ai as k,Ga as l,Oo as m,js as n,Os as o,oe as p,Fe as q,Tf as r,Zs as s,Zo as t,sf as u,Lt as v,$l as w,Bn as x,Rf as y,ec as z}; diff --git a/previews/PR807/assets/chunks/theme.CJjspAw-.js b/previews/PR807/assets/chunks/theme.CJjspAw-.js new file mode 100644 index 00000000..6f310717 --- /dev/null +++ b/previews/PR807/assets/chunks/theme.CJjspAw-.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/VPLocalSearchBox.eYTovQk2.js","assets/chunks/framework.Cl7EIXwS.js"])))=>i.map(i=>d[i]); +import{d as m,o as a,c as u,r as c,n as I,a as z,t as w,b as g,w as f,e as h,T as de,_ as $,u as Ge,i as je,f as ze,g as ve,h as y,j as p,k as r,l as K,m as re,p as T,q as F,s as Z,v as j,x as pe,y as fe,z as Ke,A as Re,B as R,F as M,C as B,D as Le,E as x,G as k,H as E,I as Ve,J as ee,K as G,L as W,M as qe,N as Te,O as ie,P as Ne,Q as we,R as te,S as We,U as Je,V as Ye,W as Ie,X as he,Y as Xe,Z as Qe,$ as Ze,a0 as xe,a1 as Me,a2 as et,a3 as tt,a4 as nt}from"./framework.Cl7EIXwS.js";const st=m({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(o){return(e,t)=>(a(),u("span",{class:I(["VPBadge",e.type])},[c(e.$slots,"default",{},()=>[z(w(e.text),1)])],2))}}),ot={key:0,class:"VPBackdrop"},at=m({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(o){return(e,t)=>(a(),g(de,{name:"fade"},{default:f(()=>[e.show?(a(),u("div",ot)):h("",!0)]),_:1}))}}),rt=$(at,[["__scopeId","data-v-b06cdb19"]]),V=Ge;function it(o,e){let t,s=!1;return()=>{t&&clearTimeout(t),s?t=setTimeout(o,e):(o(),(s=!0)&&setTimeout(()=>s=!1,e))}}function le(o){return/^\//.test(o)?o:`/${o}`}function me(o){const{pathname:e,search:t,hash:s,protocol:n}=new URL(o,"http://a.com");if(je(o)||o.startsWith("#")||!n.startsWith("http")||!ze(e))return o;const{site:i}=V(),l=e.endsWith("/")||e.endsWith(".html")?o:o.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${t}${s}`);return ve(l)}function Y({correspondingLink:o=!1}={}){const{site:e,localeIndex:t,page:s,theme:n,hash:i}=V(),l=y(()=>{var v,b;return{label:(v=e.value.locales[t.value])==null?void 0:v.label,link:((b=e.value.locales[t.value])==null?void 0:b.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:y(()=>Object.entries(e.value.locales).flatMap(([v,b])=>l.value.label===b.label?[]:{text:b.label,link:lt(b.link||(v==="root"?"/":`/${v}/`),n.value.i18nRouting!==!1&&o,s.value.relativePath.slice(l.value.link.length-1),!e.value.cleanUrls)+i.value})),currentLang:l}}function lt(o,e,t,s){return e?o.replace(/\/$/,"")+le(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,s?".html":"")):o}const ct={class:"NotFound"},ut={class:"code"},dt={class:"title"},vt={class:"quote"},pt={class:"action"},ft=["href","aria-label"],ht=m({__name:"NotFound",setup(o){const{theme:e}=V(),{currentLang:t}=Y();return(s,n)=>{var i,l,d,v,b;return a(),u("div",ct,[p("p",ut,w(((i=r(e).notFound)==null?void 0:i.code)??"404"),1),p("h1",dt,w(((l=r(e).notFound)==null?void 0:l.title)??"PAGE NOT FOUND"),1),n[0]||(n[0]=p("div",{class:"divider"},null,-1)),p("blockquote",vt,w(((d=r(e).notFound)==null?void 0:d.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),p("div",pt,[p("a",{class:"link",href:r(ve)(r(t).link),"aria-label":((v=r(e).notFound)==null?void 0:v.linkLabel)??"go to home"},w(((b=r(e).notFound)==null?void 0:b.linkText)??"Take me home"),9,ft)])])}}}),mt=$(ht,[["__scopeId","data-v-951cab6c"]]);function Ae(o,e){if(Array.isArray(o))return X(o);if(o==null)return[];e=le(e);const t=Object.keys(o).sort((n,i)=>i.split("/").length-n.split("/").length).find(n=>e.startsWith(le(n))),s=t?o[t]:[];return Array.isArray(s)?X(s):X(s.items,s.base)}function _t(o){const e=[];let t=0;for(const s in o){const n=o[s];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function bt(o){const e=[];function t(s){for(const n of s)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(o),e}function ce(o,e){return Array.isArray(e)?e.some(t=>ce(o,t)):K(o,e.link)?!0:e.items?ce(o,e.items):!1}function X(o,e){return[...o].map(t=>{const s={...t},n=s.base||e;return n&&s.link&&(s.link=n+s.link),s.items&&(s.items=X(s.items,n)),s})}function O(){const{frontmatter:o,page:e,theme:t}=V(),s=re("(min-width: 960px)"),n=T(!1),i=y(()=>{const C=t.value.sidebar,N=e.value.relativePath;return C?Ae(C,N):[]}),l=T(i.value);F(i,(C,N)=>{JSON.stringify(C)!==JSON.stringify(N)&&(l.value=i.value)});const d=y(()=>o.value.sidebar!==!1&&l.value.length>0&&o.value.layout!=="home"),v=y(()=>b?o.value.aside==null?t.value.aside==="left":o.value.aside==="left":!1),b=y(()=>o.value.layout==="home"?!1:o.value.aside!=null?!!o.value.aside:t.value.aside!==!1),L=y(()=>d.value&&s.value),_=y(()=>d.value?_t(l.value):[]);function P(){n.value=!0}function S(){n.value=!1}function A(){n.value?S():P()}return{isOpen:n,sidebar:l,sidebarGroups:_,hasSidebar:d,hasAside:b,leftAside:v,isSidebarEnabled:L,open:P,close:S,toggle:A}}function kt(o,e){let t;Z(()=>{t=o.value?document.activeElement:void 0}),j(()=>{window.addEventListener("keyup",s)}),pe(()=>{window.removeEventListener("keyup",s)});function s(n){n.key==="Escape"&&o.value&&(e(),t==null||t.focus())}}function gt(o){const{page:e,hash:t}=V(),s=T(!1),n=y(()=>o.value.collapsed!=null),i=y(()=>!!o.value.link),l=T(!1),d=()=>{l.value=K(e.value.relativePath,o.value.link)};F([e,o,t],d),j(d);const v=y(()=>l.value?!0:o.value.items?ce(e.value.relativePath,o.value.items):!1),b=y(()=>!!(o.value.items&&o.value.items.length));Z(()=>{s.value=!!(n.value&&o.value.collapsed)}),fe(()=>{(l.value||v.value)&&(s.value=!1)});function L(){n.value&&(s.value=!s.value)}return{collapsed:s,collapsible:n,isLink:i,isActiveLink:l,hasActiveLink:v,hasChildren:b,toggle:L}}function $t(){const{hasSidebar:o}=O(),e=re("(min-width: 960px)"),t=re("(min-width: 1280px)");return{isAsideEnabled:y(()=>!t.value&&!e.value?!1:o.value?t.value:e.value)}}const ue=[];function Ce(o){return typeof o.outline=="object"&&!Array.isArray(o.outline)&&o.outline.label||o.outlineTitle||"On this page"}function _e(o){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const s=Number(t.tagName[1]);return{element:t,title:yt(t),link:"#"+t.id,level:s}});return Pt(e,o)}function yt(o){let e="";for(const t of o.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(o,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[s,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;return Vt(o,s,n)}function St(o,e){const{isAsideEnabled:t}=$t(),s=it(i,100);let n=null;j(()=>{requestAnimationFrame(i),window.addEventListener("scroll",s)}),Ke(()=>{l(location.hash)}),pe(()=>{window.removeEventListener("scroll",s)});function i(){if(!t.value)return;const d=window.scrollY,v=window.innerHeight,b=document.body.offsetHeight,L=Math.abs(d+v-b)<1,_=ue.map(({element:S,link:A})=>({link:A,top:Lt(S)})).filter(({top:S})=>!Number.isNaN(S)).sort((S,A)=>S.top-A.top);if(!_.length){l(null);return}if(d<1){l(null);return}if(L){l(_[_.length-1].link);return}let P=null;for(const{link:S,top:A}of _){if(A>d+Re()+4)break;P=S}l(P)}function l(d){n&&n.classList.remove("active"),d==null?n=null:n=o.value.querySelector(`a[href="${decodeURIComponent(d)}"]`);const v=n;v?(v.classList.add("active"),e.value.style.top=v.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function Lt(o){let e=0;for(;o!==document.body;){if(o===null)return NaN;e+=o.offsetTop,o=o.offsetParent}return e}function Vt(o,e,t){ue.length=0;const s=[],n=[];return o.forEach(i=>{const l={...i,children:[]};let d=n[n.length-1];for(;d&&d.level>=l.level;)n.pop(),d=n[n.length-1];if(l.element.classList.contains("ignore-header")||d&&"shouldIgnore"in d){n.push({level:l.level,shouldIgnore:!0});return}l.level>t||l.level{const n=R("VPDocOutlineItem",!0);return a(),u("ul",{class:I(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),u(M,null,B(t.headers,({children:i,link:l,title:d})=>(a(),u("li",null,[p("a",{class:"outline-link",href:l,onClick:e,title:d},w(d),9,Tt),i!=null&&i.length?(a(),g(n,{key:0,headers:i},null,8,["headers"])):h("",!0)]))),256))],2)}}}),Be=$(Nt,[["__scopeId","data-v-3f927ebe"]]),wt={class:"content"},It={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},Mt=m({__name:"VPDocAsideOutline",setup(o){const{frontmatter:e,theme:t}=V(),s=Le([]);x(()=>{s.value=_e(e.value.outline??t.value.outline)});const n=T(),i=T();return St(n,i),(l,d)=>(a(),u("nav",{"aria-labelledby":"doc-outline-aria-label",class:I(["VPDocAsideOutline",{"has-outline":s.value.length>0}]),ref_key:"container",ref:n},[p("div",wt,[p("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),p("div",It,w(r(Ce)(r(t))),1),k(Be,{headers:s.value,root:!0},null,8,["headers"])])],2))}}),At=$(Mt,[["__scopeId","data-v-b38bf2ff"]]),Ct={class:"VPDocAsideCarbonAds"},Bt=m({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(o){const e=()=>null;return(t,s)=>(a(),u("div",Ct,[k(r(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Ht={class:"VPDocAside"},Et=m({__name:"VPDocAside",setup(o){const{theme:e}=V();return(t,s)=>(a(),u("div",Ht,[c(t.$slots,"aside-top",{},void 0,!0),c(t.$slots,"aside-outline-before",{},void 0,!0),k(At),c(t.$slots,"aside-outline-after",{},void 0,!0),s[0]||(s[0]=p("div",{class:"spacer"},null,-1)),c(t.$slots,"aside-ads-before",{},void 0,!0),r(e).carbonAds?(a(),g(Bt,{key:0,"carbon-ads":r(e).carbonAds},null,8,["carbon-ads"])):h("",!0),c(t.$slots,"aside-ads-after",{},void 0,!0),c(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Dt=$(Et,[["__scopeId","data-v-6d7b3c46"]]);function Ft(){const{theme:o,page:e}=V();return y(()=>{const{text:t="Edit this page",pattern:s=""}=o.value.editLink||{};let n;return typeof s=="function"?n=s(e.value):n=s.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function Ot(){const{page:o,theme:e,frontmatter:t}=V();return y(()=>{var b,L,_,P,S,A,C,N;const s=Ae(e.value.sidebar,o.value.relativePath),n=bt(s),i=Ut(n,H=>H.link.replace(/[?#].*$/,"")),l=i.findIndex(H=>K(o.value.relativePath,H.link)),d=((b=e.value.docFooter)==null?void 0:b.prev)===!1&&!t.value.prev||t.value.prev===!1,v=((L=e.value.docFooter)==null?void 0:L.next)===!1&&!t.value.next||t.value.next===!1;return{prev:d?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((_=i[l-1])==null?void 0:_.docFooterText)??((P=i[l-1])==null?void 0:P.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((S=i[l-1])==null?void 0:S.link)},next:v?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=i[l+1])==null?void 0:A.docFooterText)??((C=i[l+1])==null?void 0:C.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((N=i[l+1])==null?void 0:N.link)}}})}function Ut(o,e){const t=new Set;return o.filter(s=>{const n=e(s);return t.has(n)?!1:t.add(n)})}const D=m({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(o){const e=o,t=y(()=>e.tag??(e.href?"a":"span")),s=y(()=>e.href&&Ve.test(e.href)||e.target==="_blank");return(n,i)=>(a(),g(E(t.value),{class:I(["VPLink",{link:n.href,"vp-external-link-icon":s.value,"no-icon":n.noIcon}]),href:n.href?r(me)(n.href):void 0,target:n.target??(s.value?"_blank":void 0),rel:n.rel??(s.value?"noreferrer":void 0)},{default:f(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Gt={class:"VPLastUpdated"},jt=["datetime"],zt=m({__name:"VPDocFooterLastUpdated",setup(o){const{theme:e,page:t,lang:s}=V(),n=y(()=>new Date(t.value.lastUpdated)),i=y(()=>n.value.toISOString()),l=T("");return j(()=>{Z(()=>{var d,v,b;l.value=new Intl.DateTimeFormat((v=(d=e.value.lastUpdated)==null?void 0:d.formatOptions)!=null&&v.forceLocale?s.value:void 0,((b=e.value.lastUpdated)==null?void 0:b.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(n.value)})}),(d,v)=>{var b;return a(),u("p",Gt,[z(w(((b=r(e).lastUpdated)==null?void 0:b.text)||r(e).lastUpdatedText||"Last updated")+": ",1),p("time",{datetime:i.value},w(l.value),9,jt)])}}}),Kt=$(zt,[["__scopeId","data-v-475f71b8"]]),Rt={key:0,class:"VPDocFooter"},qt={key:0,class:"edit-info"},Wt={key:0,class:"edit-link"},Jt={key:1,class:"last-updated"},Yt={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},Xt={class:"pager"},Qt=["innerHTML"],Zt=["innerHTML"],xt={class:"pager"},en=["innerHTML"],tn=["innerHTML"],nn=m({__name:"VPDocFooter",setup(o){const{theme:e,page:t,frontmatter:s}=V(),n=Ft(),i=Ot(),l=y(()=>e.value.editLink&&s.value.editLink!==!1),d=y(()=>t.value.lastUpdated),v=y(()=>l.value||d.value||i.value.prev||i.value.next);return(b,L)=>{var _,P,S,A;return v.value?(a(),u("footer",Rt,[c(b.$slots,"doc-footer-before",{},void 0,!0),l.value||d.value?(a(),u("div",qt,[l.value?(a(),u("div",Wt,[k(D,{class:"edit-link-button",href:r(n).url,"no-icon":!0},{default:f(()=>[L[0]||(L[0]=p("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),z(" "+w(r(n).text),1)]),_:1},8,["href"])])):h("",!0),d.value?(a(),u("div",Jt,[k(Kt)])):h("",!0)])):h("",!0),(_=r(i).prev)!=null&&_.link||(P=r(i).next)!=null&&P.link?(a(),u("nav",Yt,[L[1]||(L[1]=p("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),p("div",Xt,[(S=r(i).prev)!=null&&S.link?(a(),g(D,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:f(()=>{var C;return[p("span",{class:"desc",innerHTML:((C=r(e).docFooter)==null?void 0:C.prev)||"Previous page"},null,8,Qt),p("span",{class:"title",innerHTML:r(i).prev.text},null,8,Zt)]}),_:1},8,["href"])):h("",!0)]),p("div",xt,[(A=r(i).next)!=null&&A.link?(a(),g(D,{key:0,class:"pager-link next",href:r(i).next.link},{default:f(()=>{var C;return[p("span",{class:"desc",innerHTML:((C=r(e).docFooter)==null?void 0:C.next)||"Next page"},null,8,en),p("span",{class:"title",innerHTML:r(i).next.text},null,8,tn)]}),_:1},8,["href"])):h("",!0)])])):h("",!0)])):h("",!0)}}}),sn=$(nn,[["__scopeId","data-v-4f9813fa"]]),on={class:"container"},an={class:"aside-container"},rn={class:"aside-content"},ln={class:"content"},cn={class:"content-container"},un={class:"main"},dn=m({__name:"VPDoc",setup(o){const{theme:e}=V(),t=ee(),{hasSidebar:s,hasAside:n,leftAside:i}=O(),l=y(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(d,v)=>{const b=R("Content");return a(),u("div",{class:I(["VPDoc",{"has-sidebar":r(s),"has-aside":r(n)}])},[c(d.$slots,"doc-top",{},void 0,!0),p("div",on,[r(n)?(a(),u("div",{key:0,class:I(["aside",{"left-aside":r(i)}])},[v[0]||(v[0]=p("div",{class:"aside-curtain"},null,-1)),p("div",an,[p("div",rn,[k(Dt,null,{"aside-top":f(()=>[c(d.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(d.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(d.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(d.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(d.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(d.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):h("",!0),p("div",ln,[p("div",cn,[c(d.$slots,"doc-before",{},void 0,!0),p("main",un,[k(b,{class:I(["vp-doc",[l.value,r(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),k(sn,null,{"doc-footer-before":f(()=>[c(d.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(d.$slots,"doc-after",{},void 0,!0)])])]),c(d.$slots,"doc-bottom",{},void 0,!0)],2)}}}),vn=$(dn,[["__scopeId","data-v-83890dd9"]]),pn=m({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(o){const e=o,t=y(()=>e.href&&Ve.test(e.href)),s=y(()=>e.tag||(e.href?"a":"button"));return(n,i)=>(a(),g(E(s.value),{class:I(["VPButton",[n.size,n.theme]]),href:n.href?r(me)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:f(()=>[z(w(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),fn=$(pn,[["__scopeId","data-v-906d7fb4"]]),hn=["src","alt"],mn=m({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(o){return(e,t)=>{const s=R("VPImage",!0);return e.image?(a(),u(M,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),u("img",G({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:r(ve)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,hn)):(a(),u(M,{key:1},[k(s,G({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),k(s,G({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):h("",!0)}}}),Q=$(mn,[["__scopeId","data-v-35a7d0b8"]]),_n={class:"container"},bn={class:"main"},kn={key:0,class:"name"},gn=["innerHTML"],$n=["innerHTML"],yn=["innerHTML"],Pn={key:0,class:"actions"},Sn={key:0,class:"image"},Ln={class:"image-container"},Vn=m({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(o){const e=W("hero-image-slot-exists");return(t,s)=>(a(),u("div",{class:I(["VPHero",{"has-image":t.image||r(e)}])},[p("div",_n,[p("div",bn,[c(t.$slots,"home-hero-info-before",{},void 0,!0),c(t.$slots,"home-hero-info",{},()=>[t.name?(a(),u("h1",kn,[p("span",{innerHTML:t.name,class:"clip"},null,8,gn)])):h("",!0),t.text?(a(),u("p",{key:1,innerHTML:t.text,class:"text"},null,8,$n)):h("",!0),t.tagline?(a(),u("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,yn)):h("",!0)],!0),c(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),u("div",Pn,[(a(!0),u(M,null,B(t.actions,n=>(a(),u("div",{key:n.link,class:"action"},[k(fn,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):h("",!0),c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||r(e)?(a(),u("div",Sn,[p("div",Ln,[s[0]||(s[0]=p("div",{class:"image-bg"},null,-1)),c(t.$slots,"home-hero-image",{},()=>[t.image?(a(),g(Q,{key:0,class:"image-src",image:t.image},null,8,["image"])):h("",!0)],!0)])])):h("",!0)])],2))}}),Tn=$(Vn,[["__scopeId","data-v-955009fc"]]),Nn=m({__name:"VPHomeHero",setup(o){const{frontmatter:e}=V();return(t,s)=>r(e).hero?(a(),g(Tn,{key:0,class:"VPHomeHero",name:r(e).hero.name,text:r(e).hero.text,tagline:r(e).hero.tagline,image:r(e).hero.image,actions:r(e).hero.actions},{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before")]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info")]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after")]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):h("",!0)}}),wn={class:"box"},In={key:0,class:"icon"},Mn=["innerHTML"],An=["innerHTML"],Cn=["innerHTML"],Bn={key:4,class:"link-text"},Hn={class:"link-text-value"},En=m({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(o){return(e,t)=>(a(),g(D,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:f(()=>[p("article",wn,[typeof e.icon=="object"&&e.icon.wrap?(a(),u("div",In,[k(Q,{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"?(a(),g(Q,{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?(a(),u("div",{key:2,class:"icon",innerHTML:e.icon},null,8,Mn)):h("",!0),p("h2",{class:"title",innerHTML:e.title},null,8,An),e.details?(a(),u("p",{key:3,class:"details",innerHTML:e.details},null,8,Cn)):h("",!0),e.linkText?(a(),u("div",Bn,[p("p",Hn,[z(w(e.linkText)+" ",1),t[0]||(t[0]=p("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):h("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Dn=$(En,[["__scopeId","data-v-f5e9645b"]]),Fn={key:0,class:"VPFeatures"},On={class:"container"},Un={class:"items"},Gn=m({__name:"VPFeatures",props:{features:{}},setup(o){const e=o,t=y(()=>{const s=e.features.length;if(s){if(s===2)return"grid-2";if(s===3)return"grid-3";if(s%3===0)return"grid-6";if(s>3)return"grid-4"}else return});return(s,n)=>s.features?(a(),u("div",Fn,[p("div",On,[p("div",Un,[(a(!0),u(M,null,B(s.features,i=>(a(),u("div",{key:i.title,class:I(["item",[t.value]])},[k(Dn,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):h("",!0)}}),jn=$(Gn,[["__scopeId","data-v-d0a190d7"]]),zn=m({__name:"VPHomeFeatures",setup(o){const{frontmatter:e}=V();return(t,s)=>r(e).features?(a(),g(jn,{key:0,class:"VPHomeFeatures",features:r(e).features},null,8,["features"])):h("",!0)}}),Kn=m({__name:"VPHomeContent",setup(o){const{width:e}=qe({initialWidth:0,includeScrollbar:!1});return(t,s)=>(a(),u("div",{class:"vp-doc container",style:Te(r(e)?{"--vp-offset":`calc(50% - ${r(e)/2}px)`}:{})},[c(t.$slots,"default",{},void 0,!0)],4))}}),Rn=$(Kn,[["__scopeId","data-v-7a48a447"]]),qn={class:"VPHome"},Wn=m({__name:"VPHome",setup(o){const{frontmatter:e}=V();return(t,s)=>{const n=R("Content");return a(),u("div",qn,[c(t.$slots,"home-hero-before",{},void 0,!0),k(Nn,null,{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(t.$slots,"home-hero-after",{},void 0,!0),c(t.$slots,"home-features-before",{},void 0,!0),k(zn),c(t.$slots,"home-features-after",{},void 0,!0),r(e).markdownStyles!==!1?(a(),g(Rn,{key:0},{default:f(()=>[k(n)]),_:1})):(a(),g(n,{key:1}))])}}}),Jn=$(Wn,[["__scopeId","data-v-cbb6ec48"]]),Yn={},Xn={class:"VPPage"};function Qn(o,e){const t=R("Content");return a(),u("div",Xn,[c(o.$slots,"page-top"),k(t),c(o.$slots,"page-bottom")])}const Zn=$(Yn,[["render",Qn]]),xn=m({__name:"VPContent",setup(o){const{page:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,i)=>(a(),u("div",{class:I(["VPContent",{"has-sidebar":r(s),"is-home":r(t).layout==="home"}]),id:"VPContent"},[r(e).isNotFound?c(n.$slots,"not-found",{key:0},()=>[k(mt)],!0):r(t).layout==="page"?(a(),g(Zn,{key:1},{"page-top":f(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(t).layout==="home"?(a(),g(Jn,{key:2},{"home-hero-before":f(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(t).layout&&r(t).layout!=="doc"?(a(),g(E(r(t).layout),{key:3})):(a(),g(vn,{key:4},{"doc-top":f(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":f(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":f(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":f(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":f(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),es=$(xn,[["__scopeId","data-v-91765379"]]),ts={class:"container"},ns=["innerHTML"],ss=["innerHTML"],os=m({__name:"VPFooter",setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O();return(n,i)=>r(e).footer&&r(t).footer!==!1?(a(),u("footer",{key:0,class:I(["VPFooter",{"has-sidebar":r(s)}])},[p("div",ts,[r(e).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:r(e).footer.message},null,8,ns)):h("",!0),r(e).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:r(e).footer.copyright},null,8,ss)):h("",!0)])],2)):h("",!0)}}),as=$(os,[["__scopeId","data-v-c970a860"]]);function rs(){const{theme:o,frontmatter:e}=V(),t=Le([]),s=y(()=>t.value.length>0);return x(()=>{t.value=_e(e.value.outline??o.value.outline)}),{headers:t,hasLocalNav:s}}const is={class:"menu-text"},ls={class:"header"},cs={class:"outline"},us=m({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(o){const e=o,{theme:t}=V(),s=T(!1),n=T(0),i=T(),l=T();function d(_){var P;(P=i.value)!=null&&P.contains(_.target)||(s.value=!1)}F(s,_=>{if(_){document.addEventListener("click",d);return}document.removeEventListener("click",d)}),ie("Escape",()=>{s.value=!1}),x(()=>{s.value=!1});function v(){s.value=!s.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function b(_){_.target.classList.contains("outline-link")&&(l.value&&(l.value.style.transition="none"),Ne(()=>{s.value=!1}))}function L(){s.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(_,P)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Te({"--vp-vh":n.value+"px"}),ref_key:"main",ref:i},[_.headers.length>0?(a(),u("button",{key:0,onClick:v,class:I({open:s.value})},[p("span",is,w(r(Ce)(r(t))),1),P[0]||(P[0]=p("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(a(),u("button",{key:1,onClick:L},w(r(t).returnToTopLabel||"Return to top"),1)),k(de,{name:"flyout"},{default:f(()=>[s.value?(a(),u("div",{key:0,ref_key:"items",ref:l,class:"items",onClick:b},[p("div",ls,[p("a",{class:"top-link",href:"#",onClick:L},w(r(t).returnToTopLabel||"Return to top"),1)]),p("div",cs,[k(Be,{headers:_.headers},null,8,["headers"])])],512)):h("",!0)]),_:1})],4))}}),ds=$(us,[["__scopeId","data-v-bc9dc845"]]),vs={class:"container"},ps=["aria-expanded"],fs={class:"menu-text"},hs=m({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(o){const{theme:e,frontmatter:t}=V(),{hasSidebar:s}=O(),{headers:n}=rs(),{y:i}=we(),l=T(0);j(()=>{l.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),x(()=>{n.value=_e(t.value.outline??e.value.outline)});const d=y(()=>n.value.length===0),v=y(()=>d.value&&!s.value),b=y(()=>({VPLocalNav:!0,"has-sidebar":s.value,empty:d.value,fixed:v.value}));return(L,_)=>r(t).layout!=="home"&&(!v.value||r(i)>=l.value)?(a(),u("div",{key:0,class:I(b.value)},[p("div",vs,[r(s)?(a(),u("button",{key:0,class:"menu","aria-expanded":L.open,"aria-controls":"VPSidebarNav",onClick:_[0]||(_[0]=P=>L.$emit("open-menu"))},[_[1]||(_[1]=p("span",{class:"vpi-align-left menu-icon"},null,-1)),p("span",fs,w(r(e).sidebarMenuLabel||"Menu"),1)],8,ps)):h("",!0),k(ds,{headers:r(n),navHeight:l.value},null,8,["headers","navHeight"])])],2)):h("",!0)}}),ms=$(hs,[["__scopeId","data-v-070ab83d"]]);function _s(){const o=T(!1);function e(){o.value=!0,window.addEventListener("resize",n)}function t(){o.value=!1,window.removeEventListener("resize",n)}function s(){o.value?t():e()}function n(){window.outerWidth>=768&&t()}const i=ee();return F(()=>i.path,t),{isScreenOpen:o,openScreen:e,closeScreen:t,toggleScreen:s}}const bs={},ks={class:"VPSwitch",type:"button",role:"switch"},gs={class:"check"},$s={key:0,class:"icon"};function ys(o,e){return a(),u("button",ks,[p("span",gs,[o.$slots.default?(a(),u("span",$s,[c(o.$slots,"default",{},void 0,!0)])):h("",!0)])])}const Ps=$(bs,[["render",ys],["__scopeId","data-v-4a1c76db"]]),Ss=m({__name:"VPSwitchAppearance",setup(o){const{isDark:e,theme:t}=V(),s=W("toggle-appearance",()=>{e.value=!e.value}),n=T("");return fe(()=>{n.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(i,l)=>(a(),g(Ps,{title:n.value,class:"VPSwitchAppearance","aria-checked":r(e),onClick:r(s)},{default:f(()=>l[0]||(l[0]=[p("span",{class:"vpi-sun sun"},null,-1),p("span",{class:"vpi-moon moon"},null,-1)])),_:1},8,["title","aria-checked","onClick"]))}}),be=$(Ss,[["__scopeId","data-v-e40a8bb6"]]),Ls={key:0,class:"VPNavBarAppearance"},Vs=m({__name:"VPNavBarAppearance",setup(o){const{site:e}=V();return(t,s)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Ls,[k(be)])):h("",!0)}}),Ts=$(Vs,[["__scopeId","data-v-af096f4a"]]),ke=T();let He=!1,ae=0;function Ns(o){const e=T(!1);if(te){!He&&ws(),ae++;const t=F(ke,s=>{var n,i,l;s===o.el.value||(n=o.el.value)!=null&&n.contains(s)?(e.value=!0,(i=o.onFocus)==null||i.call(o)):(e.value=!1,(l=o.onBlur)==null||l.call(o))});pe(()=>{t(),ae--,ae||Is()})}return We(e)}function ws(){document.addEventListener("focusin",Ee),He=!0,ke.value=document.activeElement}function Is(){document.removeEventListener("focusin",Ee)}function Ee(){ke.value=document.activeElement}const Ms={class:"VPMenuLink"},As=["innerHTML"],Cs=m({__name:"VPMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),u("div",Ms,[k(D,{class:I({active:r(K)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon},{default:f(()=>[p("span",{innerHTML:t.item.text},null,8,As)]),_:1},8,["class","href","target","rel","no-icon"])]))}}),ne=$(Cs,[["__scopeId","data-v-acbfed09"]]),Bs={class:"VPMenuGroup"},Hs={key:0,class:"title"},Es=m({__name:"VPMenuGroup",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),u("div",Bs,[e.text?(a(),u("p",Hs,w(e.text),1)):h("",!0),(a(!0),u(M,null,B(e.items,s=>(a(),u(M,null,["link"in s?(a(),g(ne,{key:0,item:s},null,8,["item"])):h("",!0)],64))),256))]))}}),Ds=$(Es,[["__scopeId","data-v-48c802d0"]]),Fs={class:"VPMenu"},Os={key:0,class:"items"},Us=m({__name:"VPMenu",props:{items:{}},setup(o){return(e,t)=>(a(),u("div",Fs,[e.items?(a(),u("div",Os,[(a(!0),u(M,null,B(e.items,s=>(a(),u(M,{key:JSON.stringify(s)},["link"in s?(a(),g(ne,{key:0,item:s},null,8,["item"])):"component"in s?(a(),g(E(s.component),G({key:1,ref_for:!0},s.props),null,16)):(a(),g(Ds,{key:2,text:s.text,items:s.items},null,8,["text","items"]))],64))),128))])):h("",!0),c(e.$slots,"default",{},void 0,!0)]))}}),Gs=$(Us,[["__scopeId","data-v-7dd3104a"]]),js=["aria-expanded","aria-label"],zs={key:0,class:"text"},Ks=["innerHTML"],Rs={key:1,class:"vpi-more-horizontal icon"},qs={class:"menu"},Ws=m({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(o){const e=T(!1),t=T();Ns({el:t,onBlur:s});function s(){e.value=!1}return(n,i)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:i[1]||(i[1]=l=>e.value=!0),onMouseleave:i[2]||(i[2]=l=>e.value=!1)},[p("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:i[0]||(i[0]=l=>e.value=!e.value)},[n.button||n.icon?(a(),u("span",zs,[n.icon?(a(),u("span",{key:0,class:I([n.icon,"option-icon"])},null,2)):h("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,Ks)):h("",!0),i[3]||(i[3]=p("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(a(),u("span",Rs))],8,js),p("div",qs,[k(Gs,{items:n.items},{default:f(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),ge=$(Ws,[["__scopeId","data-v-04f5c5e9"]]),Js=["href","aria-label","innerHTML"],Ys=m({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(o){const e=o,t=y(()=>typeof e.icon=="object"?e.icon.svg:``);return(s,n)=>(a(),u("a",{class:"VPSocialLink no-icon",href:s.link,"aria-label":s.ariaLabel??(typeof s.icon=="string"?s.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,Js))}}),Xs=$(Ys,[["__scopeId","data-v-717b8b75"]]),Qs={class:"VPSocialLinks"},Zs=m({__name:"VPSocialLinks",props:{links:{}},setup(o){return(e,t)=>(a(),u("div",Qs,[(a(!0),u(M,null,B(e.links,({link:s,icon:n,ariaLabel:i})=>(a(),g(Xs,{key:s,icon:n,link:s,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),$e=$(Zs,[["__scopeId","data-v-ee7a9424"]]),xs={key:0,class:"group translations"},eo={class:"trans-title"},to={key:1,class:"group"},no={class:"item appearance"},so={class:"label"},oo={class:"appearance-action"},ao={key:2,class:"group"},ro={class:"item social-links"},io=m({__name:"VPNavBarExtra",setup(o){const{site:e,theme:t}=V(),{localeLinks:s,currentLang:n}=Y({correspondingLink:!0}),i=y(()=>s.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(l,d)=>i.value?(a(),g(ge,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:f(()=>[r(s).length&&r(n).label?(a(),u("div",xs,[p("p",eo,w(r(n).label),1),(a(!0),u(M,null,B(r(s),v=>(a(),g(ne,{key:v.link,item:v},null,8,["item"]))),128))])):h("",!0),r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",to,[p("div",no,[p("p",so,w(r(t).darkModeSwitchLabel||"Appearance"),1),p("div",oo,[k(be)])])])):h("",!0),r(t).socialLinks?(a(),u("div",ao,[p("div",ro,[k($e,{class:"social-links-list",links:r(t).socialLinks},null,8,["links"])])])):h("",!0)]),_:1})):h("",!0)}}),lo=$(io,[["__scopeId","data-v-925effce"]]),co=["aria-expanded"],uo=m({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(o){return(e,t)=>(a(),u("button",{type:"button",class:I(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=s=>e.$emit("click"))},t[1]||(t[1]=[p("span",{class:"container"},[p("span",{class:"top"}),p("span",{class:"middle"}),p("span",{class:"bottom"})],-1)]),10,co))}}),vo=$(uo,[["__scopeId","data-v-5dea55bf"]]),po=["innerHTML"],fo=m({__name:"VPNavBarMenuLink",props:{item:{}},setup(o){const{page:e}=V();return(t,s)=>(a(),g(D,{class:I({VPNavBarMenuLink:!0,active:r(K)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,tabindex:"0"},{default:f(()=>[p("span",{innerHTML:t.item.text},null,8,po)]),_:1},8,["class","href","target","rel","no-icon"]))}}),ho=$(fo,[["__scopeId","data-v-956ec74c"]]),mo=m({__name:"VPNavBarMenuGroup",props:{item:{}},setup(o){const e=o,{page:t}=V(),s=i=>"component"in i?!1:"link"in i?K(t.value.relativePath,i.link,!!e.item.activeMatch):i.items.some(s),n=y(()=>s(e.item));return(i,l)=>(a(),g(ge,{class:I({VPNavBarMenuGroup:!0,active:r(K)(r(t).relativePath,i.item.activeMatch,!!i.item.activeMatch)||n.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),_o={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},bo=m({__name:"VPNavBarMenu",setup(o){const{theme:e}=V();return(t,s)=>r(e).nav?(a(),u("nav",_o,[s[0]||(s[0]=p("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(a(!0),u(M,null,B(r(e).nav,n=>(a(),u(M,{key:JSON.stringify(n)},["link"in n?(a(),g(ho,{key:0,item:n},null,8,["item"])):"component"in n?(a(),g(E(n.component),G({key:1,ref_for:!0},n.props),null,16)):(a(),g(mo,{key:2,item:n},null,8,["item"]))],64))),128))])):h("",!0)}}),ko=$(bo,[["__scopeId","data-v-e6d46098"]]);function go(o){const{localeIndex:e,theme:t}=V();function s(n){var A,C,N;const i=n.split("."),l=(A=t.value.search)==null?void 0:A.options,d=l&&typeof l=="object",v=d&&((N=(C=l.locales)==null?void 0:C[e.value])==null?void 0:N.translations)||null,b=d&&l.translations||null;let L=v,_=b,P=o;const S=i.pop();for(const H of i){let U=null;const q=P==null?void 0:P[H];q&&(U=P=q);const se=_==null?void 0:_[H];se&&(U=_=se);const oe=L==null?void 0:L[H];oe&&(U=L=oe),q||(P=U),se||(_=U),oe||(L=U)}return(L==null?void 0:L[S])??(_==null?void 0:_[S])??(P==null?void 0:P[S])??""}return s}const $o=["aria-label"],yo={class:"DocSearch-Button-Container"},Po={class:"DocSearch-Button-Placeholder"},ye=m({__name:"VPNavBarSearchButton",setup(o){const t=go({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(s,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(t)("button.buttonAriaLabel")},[p("span",yo,[n[0]||(n[0]=p("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),p("span",Po,w(r(t)("button.buttonText")),1)]),n[1]||(n[1]=p("span",{class:"DocSearch-Button-Keys"},[p("kbd",{class:"DocSearch-Button-Key"}),p("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,$o))}}),So={class:"VPNavBarSearch"},Lo={id:"local-search"},Vo={key:1,id:"docsearch"},To=m({__name:"VPNavBarSearch",setup(o){const e=Je(()=>Ye(()=>import("./VPLocalSearchBox.eYTovQk2.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:s}=V(),n=T(!1),i=T(!1);j(()=>{});function l(){n.value||(n.value=!0,setTimeout(d,16))}function d(){const _=new Event("keydown");_.key="k",_.metaKey=!0,window.dispatchEvent(_),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||d()},16)}function v(_){const P=_.target,S=P.tagName;return P.isContentEditable||S==="INPUT"||S==="SELECT"||S==="TEXTAREA"}const b=T(!1);ie("k",_=>{(_.ctrlKey||_.metaKey)&&(_.preventDefault(),b.value=!0)}),ie("/",_=>{v(_)||(_.preventDefault(),b.value=!0)});const L="local";return(_,P)=>{var S;return a(),u("div",So,[r(L)==="local"?(a(),u(M,{key:0},[b.value?(a(),g(r(e),{key:0,onClose:P[0]||(P[0]=A=>b.value=!1)})):h("",!0),p("div",Lo,[k(ye,{onClick:P[1]||(P[1]=A=>b.value=!0)})])],64)):r(L)==="algolia"?(a(),u(M,{key:1},[n.value?(a(),g(r(t),{key:0,algolia:((S=r(s).search)==null?void 0:S.options)??r(s).algolia,onVnodeBeforeMount:P[2]||(P[2]=A=>i.value=!0)},null,8,["algolia"])):h("",!0),i.value?h("",!0):(a(),u("div",Vo,[k(ye,{onClick:l})]))],64)):h("",!0)])}}}),No=m({__name:"VPNavBarSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>r(e).socialLinks?(a(),g($e,{key:0,class:"VPNavBarSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),wo=$(No,[["__scopeId","data-v-164c457f"]]),Io=["href","rel","target"],Mo={key:1},Ao={key:2},Co=m({__name:"VPNavBarTitle",setup(o){const{site:e,theme:t}=V(),{hasSidebar:s}=O(),{currentLang:n}=Y(),i=y(()=>{var v;return typeof t.value.logoLink=="string"?t.value.logoLink:(v=t.value.logoLink)==null?void 0:v.link}),l=y(()=>{var v;return typeof t.value.logoLink=="string"||(v=t.value.logoLink)==null?void 0:v.rel}),d=y(()=>{var v;return typeof t.value.logoLink=="string"||(v=t.value.logoLink)==null?void 0:v.target});return(v,b)=>(a(),u("div",{class:I(["VPNavBarTitle",{"has-sidebar":r(s)}])},[p("a",{class:"title",href:i.value??r(me)(r(n).link),rel:l.value,target:d.value},[c(v.$slots,"nav-bar-title-before",{},void 0,!0),r(t).logo?(a(),g(Q,{key:0,class:"logo",image:r(t).logo},null,8,["image"])):h("",!0),r(t).siteTitle?(a(),u("span",Mo,w(r(t).siteTitle),1)):r(t).siteTitle===void 0?(a(),u("span",Ao,w(r(e).title),1)):h("",!0),c(v.$slots,"nav-bar-title-after",{},void 0,!0)],8,Io)],2))}}),Bo=$(Co,[["__scopeId","data-v-28a961f9"]]),Ho={class:"items"},Eo={class:"title"},Do=m({__name:"VPNavBarTranslations",setup(o){const{theme:e}=V(),{localeLinks:t,currentLang:s}=Y({correspondingLink:!0});return(n,i)=>r(t).length&&r(s).label?(a(),g(ge,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:r(e).langMenuLabel||"Change language"},{default:f(()=>[p("div",Ho,[p("p",Eo,w(r(s).label),1),(a(!0),u(M,null,B(r(t),l=>(a(),g(ne,{key:l.link,item:l},null,8,["item"]))),128))])]),_:1},8,["label"])):h("",!0)}}),Fo=$(Do,[["__scopeId","data-v-c80d9ad0"]]),Oo={class:"wrapper"},Uo={class:"container"},Go={class:"title"},jo={class:"content"},zo={class:"content-body"},Ko=m({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(o){const e=o,{y:t}=we(),{hasSidebar:s}=O(),{frontmatter:n}=V(),i=T({});return fe(()=>{i.value={"has-sidebar":s.value,home:n.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(l,d)=>(a(),u("div",{class:I(["VPNavBar",i.value])},[p("div",Oo,[p("div",Uo,[p("div",Go,[k(Bo,null,{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),p("div",jo,[p("div",zo,[c(l.$slots,"nav-bar-content-before",{},void 0,!0),k(To,{class:"search"}),k(ko,{class:"menu"}),k(Fo,{class:"translations"}),k(Ts,{class:"appearance"}),k(wo,{class:"social-links"}),k(lo,{class:"extra"}),c(l.$slots,"nav-bar-content-after",{},void 0,!0),k(vo,{class:"hamburger",active:l.isScreenOpen,onClick:d[0]||(d[0]=v=>l.$emit("toggle-screen"))},null,8,["active"])])])])]),d[1]||(d[1]=p("div",{class:"divider"},[p("div",{class:"divider-line"})],-1))],2))}}),Ro=$(Ko,[["__scopeId","data-v-822684d1"]]),qo={key:0,class:"VPNavScreenAppearance"},Wo={class:"text"},Jo=m({__name:"VPNavScreenAppearance",setup(o){const{site:e,theme:t}=V();return(s,n)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",qo,[p("p",Wo,w(r(t).darkModeSwitchLabel||"Appearance"),1),k(be)])):h("",!0)}}),Yo=$(Jo,[["__scopeId","data-v-ffb44008"]]),Xo=["innerHTML"],Qo=m({__name:"VPNavScreenMenuLink",props:{item:{}},setup(o){const e=W("close-screen");return(t,s)=>(a(),g(D,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[p("span",{innerHTML:t.item.text},null,8,Xo)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),Zo=$(Qo,[["__scopeId","data-v-735512b8"]]),xo=["innerHTML"],ea=m({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(o){const e=W("close-screen");return(t,s)=>(a(),g(D,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[p("span",{innerHTML:t.item.text},null,8,xo)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),De=$(ea,[["__scopeId","data-v-372ae7c0"]]),ta={class:"VPNavScreenMenuGroupSection"},na={key:0,class:"title"},sa=m({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(o){return(e,t)=>(a(),u("div",ta,[e.text?(a(),u("p",na,w(e.text),1)):h("",!0),(a(!0),u(M,null,B(e.items,s=>(a(),g(De,{key:s.text,item:s},null,8,["item"]))),128))]))}}),oa=$(sa,[["__scopeId","data-v-4b8941ac"]]),aa=["aria-controls","aria-expanded"],ra=["innerHTML"],ia=["id"],la={key:0,class:"item"},ca={key:1,class:"item"},ua={key:2,class:"group"},da=m({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(o){const e=o,t=T(!1),s=y(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(i,l)=>(a(),u("div",{class:I(["VPNavScreenMenuGroup",{open:t.value}])},[p("button",{class:"button","aria-controls":s.value,"aria-expanded":t.value,onClick:n},[p("span",{class:"button-text",innerHTML:i.text},null,8,ra),l[0]||(l[0]=p("span",{class:"vpi-plus button-icon"},null,-1))],8,aa),p("div",{id:s.value,class:"items"},[(a(!0),u(M,null,B(i.items,d=>(a(),u(M,{key:JSON.stringify(d)},["link"in d?(a(),u("div",la,[k(De,{item:d},null,8,["item"])])):"component"in d?(a(),u("div",ca,[(a(),g(E(d.component),G({ref_for:!0},d.props,{"screen-menu":""}),null,16))])):(a(),u("div",ua,[k(oa,{text:d.text,items:d.items},null,8,["text","items"])]))],64))),128))],8,ia)],2))}}),va=$(da,[["__scopeId","data-v-875057a5"]]),pa={key:0,class:"VPNavScreenMenu"},fa=m({__name:"VPNavScreenMenu",setup(o){const{theme:e}=V();return(t,s)=>r(e).nav?(a(),u("nav",pa,[(a(!0),u(M,null,B(r(e).nav,n=>(a(),u(M,{key:JSON.stringify(n)},["link"in n?(a(),g(Zo,{key:0,item:n},null,8,["item"])):"component"in n?(a(),g(E(n.component),G({key:1,ref_for:!0},n.props,{"screen-menu":""}),null,16)):(a(),g(va,{key:2,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):h("",!0)}}),ha=m({__name:"VPNavScreenSocialLinks",setup(o){const{theme:e}=V();return(t,s)=>r(e).socialLinks?(a(),g($e,{key:0,class:"VPNavScreenSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),ma={class:"list"},_a=m({__name:"VPNavScreenTranslations",setup(o){const{localeLinks:e,currentLang:t}=Y({correspondingLink:!0}),s=T(!1);function n(){s.value=!s.value}return(i,l)=>r(e).length&&r(t).label?(a(),u("div",{key:0,class:I(["VPNavScreenTranslations",{open:s.value}])},[p("button",{class:"title",onClick:n},[l[0]||(l[0]=p("span",{class:"vpi-languages icon lang"},null,-1)),z(" "+w(r(t).label)+" ",1),l[1]||(l[1]=p("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),p("ul",ma,[(a(!0),u(M,null,B(r(e),d=>(a(),u("li",{key:d.link,class:"item"},[k(D,{class:"link",href:d.link},{default:f(()=>[z(w(d.text),1)]),_:2},1032,["href"])]))),128))])],2)):h("",!0)}}),ba=$(_a,[["__scopeId","data-v-362991c2"]]),ka={class:"container"},ga=m({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(o){const e=T(null),t=Ie(te?document.body:null);return(s,n)=>(a(),g(de,{name:"fade",onEnter:n[0]||(n[0]=i=>t.value=!0),onAfterLeave:n[1]||(n[1]=i=>t.value=!1)},{default:f(()=>[s.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[p("div",ka,[c(s.$slots,"nav-screen-content-before",{},void 0,!0),k(fa,{class:"menu"}),k(ba,{class:"translations"}),k(Yo,{class:"appearance"}),k(ha,{class:"social-links"}),c(s.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):h("",!0)]),_:3}))}}),$a=$(ga,[["__scopeId","data-v-833aabba"]]),ya={key:0,class:"VPNav"},Pa=m({__name:"VPNav",setup(o){const{isScreenOpen:e,closeScreen:t,toggleScreen:s}=_s(),{frontmatter:n}=V(),i=y(()=>n.value.navbar!==!1);return he("close-screen",t),Z(()=>{te&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(l,d)=>i.value?(a(),u("header",ya,[k(Ro,{"is-screen-open":r(e),onToggleScreen:r(s)},{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(l.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),k($a,{open:r(e)},{"nav-screen-content-before":f(()=>[c(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):h("",!0)}}),Sa=$(Pa,[["__scopeId","data-v-f1e365da"]]),La=["role","tabindex"],Va={key:1,class:"items"},Ta=m({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(o){const e=o,{collapsed:t,collapsible:s,isLink:n,isActiveLink:i,hasActiveLink:l,hasChildren:d,toggle:v}=gt(y(()=>e.item)),b=y(()=>d.value?"section":"div"),L=y(()=>n.value?"a":"div"),_=y(()=>d.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),P=y(()=>n.value?void 0:"button"),S=y(()=>[[`level-${e.depth}`],{collapsible:s.value},{collapsed:t.value},{"is-link":n.value},{"is-active":i.value},{"has-active":l.value}]);function A(N){"key"in N&&N.key!=="Enter"||!e.item.link&&v()}function C(){e.item.link&&v()}return(N,H)=>{const U=R("VPSidebarItem",!0);return a(),g(E(b.value),{class:I(["VPSidebarItem",S.value])},{default:f(()=>[N.item.text?(a(),u("div",G({key:0,class:"item",role:P.value},Qe(N.item.items?{click:A,keydown:A}:{},!0),{tabindex:N.item.items&&0}),[H[1]||(H[1]=p("div",{class:"indicator"},null,-1)),N.item.link?(a(),g(D,{key:0,tag:L.value,class:"link",href:N.item.link,rel:N.item.rel,target:N.item.target},{default:f(()=>[(a(),g(E(_.value),{class:"text",innerHTML:N.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),g(E(_.value),{key:1,class:"text",innerHTML:N.item.text},null,8,["innerHTML"])),N.item.collapsed!=null&&N.item.items&&N.item.items.length?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:C,onKeydown:Xe(C,["enter"]),tabindex:"0"},H[0]||(H[0]=[p("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):h("",!0)],16,La)):h("",!0),N.item.items&&N.item.items.length?(a(),u("div",Va,[N.depth<5?(a(!0),u(M,{key:0},B(N.item.items,q=>(a(),g(U,{key:q.text,item:q,depth:N.depth+1},null,8,["item","depth"]))),128)):h("",!0)])):h("",!0)]),_:1},8,["class"])}}}),Na=$(Ta,[["__scopeId","data-v-196b2e5f"]]),wa=m({__name:"VPSidebarGroup",props:{items:{}},setup(o){const e=T(!0);let t=null;return j(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),Ze(()=>{t!=null&&(clearTimeout(t),t=null)}),(s,n)=>(a(!0),u(M,null,B(s.items,i=>(a(),u("div",{key:i.text,class:I(["group",{"no-transition":e.value}])},[k(Na,{item:i,depth:0},null,8,["item"])],2))),128))}}),Ia=$(wa,[["__scopeId","data-v-9e426adc"]]),Ma={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},Aa=m({__name:"VPSidebar",props:{open:{type:Boolean}},setup(o){const{sidebarGroups:e,hasSidebar:t}=O(),s=o,n=T(null),i=Ie(te?document.body:null);F([s,n],()=>{var d;s.open?(i.value=!0,(d=n.value)==null||d.focus()):i.value=!1},{immediate:!0,flush:"post"});const l=T(0);return F(e,()=>{l.value+=1},{deep:!0}),(d,v)=>r(t)?(a(),u("aside",{key:0,class:I(["VPSidebar",{open:d.open}]),ref_key:"navEl",ref:n,onClick:v[0]||(v[0]=xe(()=>{},["stop"]))},[v[2]||(v[2]=p("div",{class:"curtain"},null,-1)),p("nav",Ma,[v[1]||(v[1]=p("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),c(d.$slots,"sidebar-nav-before",{},void 0,!0),(a(),g(Ia,{items:r(e),key:l.value},null,8,["items"])),c(d.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):h("",!0)}}),Ca=$(Aa,[["__scopeId","data-v-18756405"]]),Ba=m({__name:"VPSkipLink",setup(o){const e=ee(),t=T();F(()=>e.path,()=>t.value.focus());function s({target:n}){const i=document.getElementById(decodeURIComponent(n.hash).slice(1));if(i){const l=()=>{i.removeAttribute("tabindex"),i.removeEventListener("blur",l)};i.setAttribute("tabindex","-1"),i.addEventListener("blur",l),i.focus(),window.scrollTo(0,0)}}return(n,i)=>(a(),u(M,null,[p("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),p("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:s}," Skip to content ")],64))}}),Ha=$(Ba,[["__scopeId","data-v-c3508ec8"]]),Ea=m({__name:"Layout",setup(o){const{isOpen:e,open:t,close:s}=O(),n=ee();F(()=>n.path,s),kt(e,s);const{frontmatter:i}=V(),l=Me(),d=y(()=>!!l["home-hero-image"]);return he("hero-image-slot-exists",d),(v,b)=>{const L=R("Content");return r(i).layout!==!1?(a(),u("div",{key:0,class:I(["Layout",r(i).pageClass])},[c(v.$slots,"layout-top",{},void 0,!0),k(Ha),k(rt,{class:"backdrop",show:r(e),onClick:r(s)},null,8,["show","onClick"]),k(Sa,null,{"nav-bar-title-before":f(()=>[c(v.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(v.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(v.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(v.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":f(()=>[c(v.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(v.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),k(ms,{open:r(e),onOpenMenu:r(t)},null,8,["open","onOpenMenu"]),k(Ca,{open:r(e)},{"sidebar-nav-before":f(()=>[c(v.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":f(()=>[c(v.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),k(es,null,{"page-top":f(()=>[c(v.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(v.$slots,"page-bottom",{},void 0,!0)]),"not-found":f(()=>[c(v.$slots,"not-found",{},void 0,!0)]),"home-hero-before":f(()=>[c(v.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(v.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(v.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(v.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(v.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(v.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(v.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(v.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(v.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":f(()=>[c(v.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(v.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(v.$slots,"doc-after",{},void 0,!0)]),"doc-top":f(()=>[c(v.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(v.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":f(()=>[c(v.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(v.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(v.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(v.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(v.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(v.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),k(as),c(v.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),g(L,{key:1}))}}}),Da=$(Ea,[["__scopeId","data-v-a9a9e638"]]),Pe={Layout:Da,enhanceApp:({app:o})=>{o.component("Badge",st)}},Fa=o=>{if(typeof document>"u")return{stabilizeScrollPosition:n=>async(...i)=>n(...i)};const e=document.documentElement;return{stabilizeScrollPosition:s=>async(...n)=>{const i=s(...n),l=o.value;if(!l)return i;const d=l.offsetTop-e.scrollTop;return await Ne(),e.scrollTop=l.offsetTop-d,i}}},Fe="vitepress:tabSharedState",J=typeof localStorage<"u"?localStorage:null,Oe="vitepress:tabsSharedState",Oa=()=>{const o=J==null?void 0:J.getItem(Oe);if(o)try{return JSON.parse(o)}catch{}return{}},Ua=o=>{J&&J.setItem(Oe,JSON.stringify(o))},Ga=o=>{const e=et({});F(()=>e.content,(t,s)=>{t&&s&&Ua(t)},{deep:!0}),o.provide(Fe,e)},ja=(o,e)=>{const t=W(Fe);if(!t)throw new Error("[vitepress-plugin-tabs] TabsSharedState should be injected");j(()=>{t.content||(t.content=Oa())});const s=T(),n=y({get(){var v;const l=e.value,d=o.value;if(l){const b=(v=t.content)==null?void 0:v[l];if(b&&d.includes(b))return b}else{const b=s.value;if(b)return b}return d[0]},set(l){const d=e.value;d?t.content&&(t.content[d]=l):s.value=l}});return{selected:n,select:l=>{n.value=l}}};let Se=0;const za=()=>(Se++,""+Se);function Ka(){const o=Me();return y(()=>{var s;const t=(s=o.default)==null?void 0:s.call(o);return t?t.filter(n=>typeof n.type=="object"&&"__name"in n.type&&n.type.__name==="PluginTabsTab"&&n.props).map(n=>{var i;return(i=n.props)==null?void 0:i.label}):[]})}const Ue="vitepress:tabSingleState",Ra=o=>{he(Ue,o)},qa=()=>{const o=W(Ue);if(!o)throw new Error("[vitepress-plugin-tabs] TabsSingleState should be injected");return o},Wa={class:"plugin-tabs"},Ja=["id","aria-selected","aria-controls","tabindex","onClick"],Ya=m({__name:"PluginTabs",props:{sharedStateKey:{}},setup(o){const e=o,t=Ka(),{selected:s,select:n}=ja(t,tt(e,"sharedStateKey")),i=T(),{stabilizeScrollPosition:l}=Fa(i),d=l(n),v=T([]),b=_=>{var A;const P=t.value.indexOf(s.value);let S;_.key==="ArrowLeft"?S=P>=1?P-1:t.value.length-1:_.key==="ArrowRight"&&(S=P(a(),u("div",Wa,[p("div",{ref_key:"tablist",ref:i,class:"plugin-tabs--tab-list",role:"tablist",onKeydown:b},[(a(!0),u(M,null,B(r(t),S=>(a(),u("button",{id:`tab-${S}-${r(L)}`,ref_for:!0,ref_key:"buttonRefs",ref:v,key:S,role:"tab",class:"plugin-tabs--tab","aria-selected":S===r(s),"aria-controls":`panel-${S}-${r(L)}`,tabindex:S===r(s)?0:-1,onClick:()=>r(d)(S)},w(S),9,Ja))),128))],544),c(_.$slots,"default")]))}}),Xa=["id","aria-labelledby"],Qa=m({__name:"PluginTabsTab",props:{label:{}},setup(o){const{uid:e,selected:t}=qa();return(s,n)=>r(t)===s.label?(a(),u("div",{key:0,id:`panel-${s.label}-${r(e)}`,class:"plugin-tabs--content",role:"tabpanel",tabindex:"0","aria-labelledby":`tab-${s.label}-${r(e)}`},[c(s.$slots,"default",{},void 0,!0)],8,Xa)):h("",!0)}}),Za=$(Qa,[["__scopeId","data-v-9b0d03d2"]]),xa=o=>{Ga(o),o.component("PluginTabs",Ya),o.component("PluginTabsTab",Za)},tr={extends:Pe,Layout(){return nt(Pe.Layout,null,{})},enhanceApp({app:o,router:e,siteData:t}){xa(o)}};export{tr as R,go as c,V as u}; diff --git a/previews/PR807/assets/classify_bang_example.Ch0DZvbI.png b/previews/PR807/assets/classify_bang_example.Ch0DZvbI.png new file mode 100644 index 00000000..df329a15 Binary files /dev/null and b/previews/PR807/assets/classify_bang_example.Ch0DZvbI.png differ diff --git a/previews/PR807/assets/classify_example.CA_6ItEA.png b/previews/PR807/assets/classify_example.CA_6ItEA.png new file mode 100644 index 00000000..f90273d3 Binary files /dev/null and b/previews/PR807/assets/classify_example.CA_6ItEA.png differ diff --git a/previews/PR807/assets/data_sources.md.Dcl5DOui.js b/previews/PR807/assets/data_sources.md.Dcl5DOui.js new file mode 100644 index 00000000..2f4406ef --- /dev/null +++ b/previews/PR807/assets/data_sources.md.Dcl5DOui.js @@ -0,0 +1,4 @@ +import{_ as a,c as s,a5 as t,o as i}from"./chunks/framework.Cl7EIXwS.js";const o="/Rasters.jl/previews/PR807/assets/itwpihm.CBMwZ7qg.png",m=JSON.parse('{"title":"Data sources","description":"","frontmatter":{},"headers":[],"relativePath":"data_sources.md","filePath":"data_sources.md","lastUpdated":null}'),r={name:"data_sources.md"};function n(d,e,l,c,h,p){return i(),s("div",null,e[0]||(e[0]=[t(`

Data sources

Rasters.jl uses a number of backends to load raster data. Raster, RasterStack and RasterSeries will detect which backend to use for you, automatically.

GRD

R GRD files can be loaded natively, using Julias MMap - which means they are very fast, but are not compressed. They are always 3 dimensional, and have Y, X and Band dimensions.

NetCDF

NetCDF .nc files are loaded using NCDatasets.jl. Layers from files can be loaded as Raster("filename.nc"; name=:layername). Without name the first layer is used. RasterStack("filename.nc") will use all netcdf variables in the file that are not dimensions as layers.

NetCDF layers can have arbitrary dimensions. Known, common dimension names are converted to X, Y Z, and Ti, otherwise Dim{:layername} is used. Layers in the same file may also have different dimensions.

NetCDF files still have issues loading directly from disk for some operations. Using read(ncstack) may help.

GDAL

All files GDAL can access, such as .tiff and .asc files, can be loaded, using ArchGDAL.jl. These are generally best loaded as Raster("filename.tif"), but can be loaded as RasterStack("filename.tif"; layersfrom=Band), taking layers from the Band dimension, which is also the default.

SMAP

The Soil Moisture Active-Passive dataset provides global layers of soil moisture, temperature and other related data, in a custom HDF5 format. Layers are always 2 dimensional, with Y and X dimensions.

These can be loaded as multi-layered RasterStack("filename.h5"). Individual layers can be loaded as Raster("filename.h5"; name=:layername), without name the first layer is used.

julia
using Rasters

Missing docstring.

Missing docstring for smapseries. Check Documenter's build log for details.

Writing file formats to disk

Files can be written to disk in all formats other than SMAP HDF5 using write("filename.ext", A). See the docs for write. They can (with some caveats) be written to different formats than they were loaded in as, providing file-type conversion for spatial data.

Some metadata may be lost in formats that store little metadata, or where metadata conversion has not been completely implemented.

RasterDataSources.jl integration

RasterDataSources.jl standardises the download of common raster data sources, with a focus on datasets used in ecology and the environmental sciences. RasterDataSources.jl is tightly integrated into Rasters.jl, so that datsets and keywords can be used directly to download and load data as a Raster, RasterStack, or RasterSeries.

julia
using Rasters, CairoMakie, Dates
+using RasterDataSources
+A = Raster(WorldClim{Climate}, :tavg; month=June)
+Makie.plot(A)

See the docs for Raster, RasterStack and RasterSeries, and the docs for RasterDataSources.getraster for syntax to specify various data sources.

',23)]))}const k=a(r,[["render",n]]);export{m as __pageData,k as default}; diff --git a/previews/PR807/assets/data_sources.md.Dcl5DOui.lean.js b/previews/PR807/assets/data_sources.md.Dcl5DOui.lean.js new file mode 100644 index 00000000..2f4406ef --- /dev/null +++ b/previews/PR807/assets/data_sources.md.Dcl5DOui.lean.js @@ -0,0 +1,4 @@ +import{_ as a,c as s,a5 as t,o as i}from"./chunks/framework.Cl7EIXwS.js";const o="/Rasters.jl/previews/PR807/assets/itwpihm.CBMwZ7qg.png",m=JSON.parse('{"title":"Data sources","description":"","frontmatter":{},"headers":[],"relativePath":"data_sources.md","filePath":"data_sources.md","lastUpdated":null}'),r={name:"data_sources.md"};function n(d,e,l,c,h,p){return i(),s("div",null,e[0]||(e[0]=[t(`

Data sources

Rasters.jl uses a number of backends to load raster data. Raster, RasterStack and RasterSeries will detect which backend to use for you, automatically.

GRD

R GRD files can be loaded natively, using Julias MMap - which means they are very fast, but are not compressed. They are always 3 dimensional, and have Y, X and Band dimensions.

NetCDF

NetCDF .nc files are loaded using NCDatasets.jl. Layers from files can be loaded as Raster("filename.nc"; name=:layername). Without name the first layer is used. RasterStack("filename.nc") will use all netcdf variables in the file that are not dimensions as layers.

NetCDF layers can have arbitrary dimensions. Known, common dimension names are converted to X, Y Z, and Ti, otherwise Dim{:layername} is used. Layers in the same file may also have different dimensions.

NetCDF files still have issues loading directly from disk for some operations. Using read(ncstack) may help.

GDAL

All files GDAL can access, such as .tiff and .asc files, can be loaded, using ArchGDAL.jl. These are generally best loaded as Raster("filename.tif"), but can be loaded as RasterStack("filename.tif"; layersfrom=Band), taking layers from the Band dimension, which is also the default.

SMAP

The Soil Moisture Active-Passive dataset provides global layers of soil moisture, temperature and other related data, in a custom HDF5 format. Layers are always 2 dimensional, with Y and X dimensions.

These can be loaded as multi-layered RasterStack("filename.h5"). Individual layers can be loaded as Raster("filename.h5"; name=:layername), without name the first layer is used.

julia
using Rasters

Missing docstring.

Missing docstring for smapseries. Check Documenter's build log for details.

Writing file formats to disk

Files can be written to disk in all formats other than SMAP HDF5 using write("filename.ext", A). See the docs for write. They can (with some caveats) be written to different formats than they were loaded in as, providing file-type conversion for spatial data.

Some metadata may be lost in formats that store little metadata, or where metadata conversion has not been completely implemented.

RasterDataSources.jl integration

RasterDataSources.jl standardises the download of common raster data sources, with a focus on datasets used in ecology and the environmental sciences. RasterDataSources.jl is tightly integrated into Rasters.jl, so that datsets and keywords can be used directly to download and load data as a Raster, RasterStack, or RasterSeries.

julia
using Rasters, CairoMakie, Dates
+using RasterDataSources
+A = Raster(WorldClim{Climate}, :tavg; month=June)
+Makie.plot(A)

See the docs for Raster, RasterStack and RasterSeries, and the docs for RasterDataSources.getraster for syntax to specify various data sources.

',23)]))}const k=a(r,[["render",n]]);export{m as __pageData,k as default}; diff --git a/previews/PR807/assets/edcrsgk.2YhfOv1i.png b/previews/PR807/assets/edcrsgk.2YhfOv1i.png new file mode 100644 index 00000000..68177e08 Binary files /dev/null and b/previews/PR807/assets/edcrsgk.2YhfOv1i.png differ diff --git a/previews/PR807/assets/eqdfnkz.8o5RdXOt.png b/previews/PR807/assets/eqdfnkz.8o5RdXOt.png new file mode 100644 index 00000000..243878be Binary files /dev/null and b/previews/PR807/assets/eqdfnkz.8o5RdXOt.png differ diff --git a/previews/PR807/assets/extend_example.DNJ4wwKN.png b/previews/PR807/assets/extend_example.DNJ4wwKN.png new file mode 100644 index 00000000..6e71c96d Binary files /dev/null and b/previews/PR807/assets/extend_example.DNJ4wwKN.png differ diff --git a/previews/PR807/assets/fzzzwbh.ALj2aDbZ.png b/previews/PR807/assets/fzzzwbh.ALj2aDbZ.png new file mode 100644 index 00000000..f4cee49b Binary files /dev/null and b/previews/PR807/assets/fzzzwbh.ALj2aDbZ.png differ diff --git a/previews/PR807/assets/gbif_wflow.md.B-xemxXG.js b/previews/PR807/assets/gbif_wflow.md.B-xemxXG.js new file mode 100644 index 00000000..c34cf7f3 --- /dev/null +++ b/previews/PR807/assets/gbif_wflow.md.B-xemxXG.js @@ -0,0 +1,67 @@ +import{_ as a,c as i,a5 as n,o as p}from"./chunks/framework.Cl7EIXwS.js";const t="/Rasters.jl/previews/PR807/assets/olovemv.CVwZE_Z9.png",g=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"gbif_wflow.md","filePath":"gbif_wflow.md","lastUpdated":null}'),l={name:"gbif_wflow.md"};function e(h,s,k,d,r,o){return p(),i("div",null,s[0]||(s[0]=[n(`

Load occurrences for the Mountain Pygmy Possum using GBIF.jl

Load GBIF

julia
using Rasters, GBIF2
+using RasterDataSources
+const RS = Rasters
Rasters
julia
records = GBIF2.occurrence_search("Burramys parvus"; limit=300)
300-element GBIF2.Table{GBIF2.Occurrence, JSON3.Array{JSON3.Object, Vector{UInt8}, SubArray{UInt64, 1, Vector{UInt64}, Tuple{UnitRange{Int64}}, true}}}┌──────────────────────────┬─────────┬─────────┬─────────┬──────────┬───────────
+│                 geometry │    year │   month │     day │  kingdom │   phylum ⋯
+│ Tuple{Float64, Float64}? │  Int64? │  Int64? │  Int64? │  String? │  String? ⋯
+├──────────────────────────┼─────────┼─────────┼─────────┼──────────┼───────────
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │    2021 │       1 │       6 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.391, -36.3036) │    2015 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.333, -36.4333) │    2011 │      11 │      21 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.396, -36.3818) │    2016 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.347, -36.5047) │    2012 │      11 │      22 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (147.096, -36.9357) │    2020 │       2 │      10 │ Animalia │ Chordata ⋯
+│      (148.329, -36.4317) │    2016 │       1 │       3 │ Animalia │ Chordata ⋯
+│      (148.241, -36.4001) │    2011 │      11 │      18 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.236, -36.5249) │    2012 │      11 │      23 │ Animalia │ Chordata ⋯
+│            ⋮             │    ⋮    │    ⋮    │    ⋮    │    ⋮     │    ⋮     ⋱
+└──────────────────────────┴─────────┴─────────┴─────────┴──────────┴───────────
+                                                 78 columns and 285 rows omitted

Extract coordinates

Extract the longitude/latitude value to a Vector of points (a Tuple counts as a (x, y) point in GeoInterface.jl):

julia
coords = [(r.decimalLongitude, r.decimalLatitude) for r in records if !ismissing(r.decimalLatitude)]
256-element Vector{Tuple{Float64, Float64}}:
+ (148.391097, -36.30362)
+ (148.332969, -36.433349)
+ (148.396453, -36.381847)
+ (148.347186, -36.504673)
+ (147.096394, -36.935687)
+ (148.328896, -36.431684)
+ (148.240881, -36.400058)
+ (148.235596, -36.524924)
+ (148.338776, -36.430986)
+ (147.1, -37.0)
+
+ (148.391682, -36.373215)
+ (148.394749, -36.284565)
+ (148.333783, -36.432552)
+ (148.333783, -36.432552)
+ (148.377673, -36.418261)
+ (148.328025, -36.437709)
+ (148.398438, -36.382602)
+ (148.310064, -36.448374)
+ (148.259489, -36.490719)

Get layer / Band

Get BioClim layers and subset to south-east Australia

julia
A = RasterStack(WorldClim{BioClim}, (1, 3, 7, 12))
+se_aus = A[X(138 .. 155), Y(-40 .. -25), RS.Band(1)]
╭────────────────────╮
+│ 102×89 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(138.0, 154.83333333333331, 102) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-25.16666666666667, -39.83333333333333, 89) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :bio1  eltype: Float32 dims: X, Y size: 102×89
+  :bio3  eltype: Float32 dims: X, Y size: 102×89
+  :bio7  eltype: Float32 dims: X, Y size: 102×89
+  :bio12 eltype: Float32 dims: X, Y size: 102×89
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (138.0, 154.99999999999997), Y = (-39.83333333333333, -25.000000000000004))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plot BioClim predictors and scatter occurrence points on all subplots

julia
using Plots
+p = plot(se_aus);
+kw = (legend=:none, opacity=0.5, markershape=:cross, markercolor=:black)
+foreach(i -> scatter!(p, coords; subplot=i, kw...), 1:4)
+p

Then extract predictor variables and write to CSV.

julia
using CSV
+predictors = collect(extract(se_aus, coords))
+CSV.write("burramys_parvus_predictors.csv", predictors)
"burramys_parvus_predictors.csv"

Or convert them to a DataFrame:

julia
using DataFrames
+df = DataFrame(predictors)
+df[1:5,:]
`,22)]))}const E=a(l,[["render",e]]);export{g as __pageData,E as default}; diff --git a/previews/PR807/assets/gbif_wflow.md.B-xemxXG.lean.js b/previews/PR807/assets/gbif_wflow.md.B-xemxXG.lean.js new file mode 100644 index 00000000..c34cf7f3 --- /dev/null +++ b/previews/PR807/assets/gbif_wflow.md.B-xemxXG.lean.js @@ -0,0 +1,67 @@ +import{_ as a,c as i,a5 as n,o as p}from"./chunks/framework.Cl7EIXwS.js";const t="/Rasters.jl/previews/PR807/assets/olovemv.CVwZE_Z9.png",g=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"gbif_wflow.md","filePath":"gbif_wflow.md","lastUpdated":null}'),l={name:"gbif_wflow.md"};function e(h,s,k,d,r,o){return p(),i("div",null,s[0]||(s[0]=[n(`

Load occurrences for the Mountain Pygmy Possum using GBIF.jl

Load GBIF

julia
using Rasters, GBIF2
+using RasterDataSources
+const RS = Rasters
Rasters
julia
records = GBIF2.occurrence_search("Burramys parvus"; limit=300)
300-element GBIF2.Table{GBIF2.Occurrence, JSON3.Array{JSON3.Object, Vector{UInt8}, SubArray{UInt64, 1, Vector{UInt64}, Tuple{UnitRange{Int64}}, true}}}┌──────────────────────────┬─────────┬─────────┬─────────┬──────────┬───────────
+│                 geometry │    year │   month │     day │  kingdom │   phylum ⋯
+│ Tuple{Float64, Float64}? │  Int64? │  Int64? │  Int64? │  String? │  String? ⋯
+├──────────────────────────┼─────────┼─────────┼─────────┼──────────┼───────────
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │    2021 │       1 │       6 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.391, -36.3036) │    2015 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.333, -36.4333) │    2011 │      11 │      21 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.396, -36.3818) │    2016 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.347, -36.5047) │    2012 │      11 │      22 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (147.096, -36.9357) │    2020 │       2 │      10 │ Animalia │ Chordata ⋯
+│      (148.329, -36.4317) │    2016 │       1 │       3 │ Animalia │ Chordata ⋯
+│      (148.241, -36.4001) │    2011 │      11 │      18 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.236, -36.5249) │    2012 │      11 │      23 │ Animalia │ Chordata ⋯
+│            ⋮             │    ⋮    │    ⋮    │    ⋮    │    ⋮     │    ⋮     ⋱
+└──────────────────────────┴─────────┴─────────┴─────────┴──────────┴───────────
+                                                 78 columns and 285 rows omitted

Extract coordinates

Extract the longitude/latitude value to a Vector of points (a Tuple counts as a (x, y) point in GeoInterface.jl):

julia
coords = [(r.decimalLongitude, r.decimalLatitude) for r in records if !ismissing(r.decimalLatitude)]
256-element Vector{Tuple{Float64, Float64}}:
+ (148.391097, -36.30362)
+ (148.332969, -36.433349)
+ (148.396453, -36.381847)
+ (148.347186, -36.504673)
+ (147.096394, -36.935687)
+ (148.328896, -36.431684)
+ (148.240881, -36.400058)
+ (148.235596, -36.524924)
+ (148.338776, -36.430986)
+ (147.1, -37.0)
+
+ (148.391682, -36.373215)
+ (148.394749, -36.284565)
+ (148.333783, -36.432552)
+ (148.333783, -36.432552)
+ (148.377673, -36.418261)
+ (148.328025, -36.437709)
+ (148.398438, -36.382602)
+ (148.310064, -36.448374)
+ (148.259489, -36.490719)

Get layer / Band

Get BioClim layers and subset to south-east Australia

julia
A = RasterStack(WorldClim{BioClim}, (1, 3, 7, 12))
+se_aus = A[X(138 .. 155), Y(-40 .. -25), RS.Band(1)]
╭────────────────────╮
+│ 102×89 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(138.0, 154.83333333333331, 102) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-25.16666666666667, -39.83333333333333, 89) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :bio1  eltype: Float32 dims: X, Y size: 102×89
+  :bio3  eltype: Float32 dims: X, Y size: 102×89
+  :bio7  eltype: Float32 dims: X, Y size: 102×89
+  :bio12 eltype: Float32 dims: X, Y size: 102×89
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (138.0, 154.99999999999997), Y = (-39.83333333333333, -25.000000000000004))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plot BioClim predictors and scatter occurrence points on all subplots

julia
using Plots
+p = plot(se_aus);
+kw = (legend=:none, opacity=0.5, markershape=:cross, markercolor=:black)
+foreach(i -> scatter!(p, coords; subplot=i, kw...), 1:4)
+p

Then extract predictor variables and write to CSV.

julia
using CSV
+predictors = collect(extract(se_aus, coords))
+CSV.write("burramys_parvus_predictors.csv", predictors)
"burramys_parvus_predictors.csv"

Or convert them to a DataFrame:

julia
using DataFrames
+df = DataFrame(predictors)
+df[1:5,:]
`,22)]))}const E=a(l,[["render",e]]);export{g as __pageData,E as default}; diff --git a/previews/PR807/assets/get_started.md.CRLYYECF.js b/previews/PR807/assets/get_started.md.CRLYYECF.js new file mode 100644 index 00000000..8e762bd2 --- /dev/null +++ b/previews/PR807/assets/get_started.md.CRLYYECF.js @@ -0,0 +1,95 @@ +import{_ as a,c as i,a5 as n,o as e}from"./chunks/framework.Cl7EIXwS.js";const t="/Rasters.jl/previews/PR807/assets/vjnjunt.DojgcnZi.png",g=JSON.parse('{"title":"Quick start","description":"","frontmatter":{},"headers":[],"relativePath":"get_started.md","filePath":"get_started.md","lastUpdated":null}'),p={name:"get_started.md"};function l(h,s,d,k,r,o){return e(),i("div",null,s[0]||(s[0]=[n(`

Quick start

Install the package by typing:

julia
] 
+add Rasters

then do

julia
using Rasters

Using Rasters to read GeoTiff or NetCDF files will output something similar to the following toy examples. This is possible because Rasters.jl extends DimensionalData.jl so that spatial data can be indexed using named dimensions like X, Y and Ti (time) and e.g. spatial coordinates.

julia
using Rasters, Dates
+
+lon, lat = X(25:1:30), Y(25:1:30)
+ti = Ti(DateTime(2001):Month(1):DateTime(2002))
+ras = Raster(rand(lon, lat, ti)) # this generates random numbers with the dimensions given
╭──────────────────────────╮
+│ 6×6×13 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2002-01-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Getting the lookup array from dimensions

julia
lon = lookup(ras, X) # if X is longitude
+lat = lookup(ras, Y) # if Y is latitude
Sampled{Int64} ForwardOrdered Regular Points
+wrapping: 25:1:30

Select by index

Selecting a time slice by index is done via

julia
ras[Ti(1)]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

also

julia
ras[Ti=1]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

or and interval of indices using the syntax =a:b or (a:b)

julia
ras[Ti(1:10)]
╭──────────────────────────╮
+│ 6×6×10 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2001-10-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2001-10-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Select by value

julia
ras[Ti=At(DateTime(2001))]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

More options are available, like Near, Contains and Where.

Dimensions

Rasters uses X, Y, and Z dimensions from DimensionalData to represent spatial directions like longitude, latitude and the vertical dimension, and subset data with them. Ti is used for time, and Band represent bands. Other dimensions can have arbitrary names, but will be treated generically. See DimensionalData for more details on how they work.

Lookup Arrays

These specify properties of the index associated with e.g. the X and Y dimension. Rasters.jl defines additional lookup arrays: Projected to handle dimensions with projections, and Mapped where the projection is mapped to another projection like EPSG(4326). Mapped is largely designed to handle NetCDF dimensions, especially with Explicit spans.

Subsetting an object

Regular getindex (e.g. A[1:100, :]) and view work on all objects just as with an Array. view is always lazy, and reads from disk are deferred until getindex is used. DimensionalData.jl Dimensions and Selectors are the other way to subset an object, making use of the objects index to find values at e.g. certain X/Y coordinates. The available selectors are listed here:

SelectorsDescription
At(x)get the index exactly matching the passed in value(s).
Near(x)get the closest index to the passed in value(s).
Where(f::Function)filter the array axis by a function of the dimension index values.
a..b/Between(a, b)get all indices between two values, excluding the high value.
Contains(x)get indices where the value x falls within an interval.

Info

  • Use the .. selector to take a view of madagascar:
julia
using Rasters, RasterDataSources
+const RS = Rasters
+using CairoMakie
+CairoMakie.activate!()
+
+A = Raster(WorldClim{BioClim}, 5)
+madagascar = view(A, X(43.25 .. 50.48), Y(-25.61 .. -12.04))
+# Note the space between .. -12
+Makie.plot(madagascar)

',33)]))}const E=a(p,[["render",l]]);export{g as __pageData,E as default}; diff --git a/previews/PR807/assets/get_started.md.CRLYYECF.lean.js b/previews/PR807/assets/get_started.md.CRLYYECF.lean.js new file mode 100644 index 00000000..8e762bd2 --- /dev/null +++ b/previews/PR807/assets/get_started.md.CRLYYECF.lean.js @@ -0,0 +1,95 @@ +import{_ as a,c as i,a5 as n,o as e}from"./chunks/framework.Cl7EIXwS.js";const t="/Rasters.jl/previews/PR807/assets/vjnjunt.DojgcnZi.png",g=JSON.parse('{"title":"Quick start","description":"","frontmatter":{},"headers":[],"relativePath":"get_started.md","filePath":"get_started.md","lastUpdated":null}'),p={name:"get_started.md"};function l(h,s,d,k,r,o){return e(),i("div",null,s[0]||(s[0]=[n(`

Quick start

Install the package by typing:

julia
] 
+add Rasters

then do

julia
using Rasters

Using Rasters to read GeoTiff or NetCDF files will output something similar to the following toy examples. This is possible because Rasters.jl extends DimensionalData.jl so that spatial data can be indexed using named dimensions like X, Y and Ti (time) and e.g. spatial coordinates.

julia
using Rasters, Dates
+
+lon, lat = X(25:1:30), Y(25:1:30)
+ti = Ti(DateTime(2001):Month(1):DateTime(2002))
+ras = Raster(rand(lon, lat, ti)) # this generates random numbers with the dimensions given
╭──────────────────────────╮
+│ 6×6×13 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2002-01-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Getting the lookup array from dimensions

julia
lon = lookup(ras, X) # if X is longitude
+lat = lookup(ras, Y) # if Y is latitude
Sampled{Int64} ForwardOrdered Regular Points
+wrapping: 25:1:30

Select by index

Selecting a time slice by index is done via

julia
ras[Ti(1)]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

also

julia
ras[Ti=1]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

or and interval of indices using the syntax =a:b or (a:b)

julia
ras[Ti(1:10)]
╭──────────────────────────╮
+│ 6×6×10 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2001-10-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2001-10-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Select by value

julia
ras[Ti=At(DateTime(2001))]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

More options are available, like Near, Contains and Where.

Dimensions

Rasters uses X, Y, and Z dimensions from DimensionalData to represent spatial directions like longitude, latitude and the vertical dimension, and subset data with them. Ti is used for time, and Band represent bands. Other dimensions can have arbitrary names, but will be treated generically. See DimensionalData for more details on how they work.

Lookup Arrays

These specify properties of the index associated with e.g. the X and Y dimension. Rasters.jl defines additional lookup arrays: Projected to handle dimensions with projections, and Mapped where the projection is mapped to another projection like EPSG(4326). Mapped is largely designed to handle NetCDF dimensions, especially with Explicit spans.

Subsetting an object

Regular getindex (e.g. A[1:100, :]) and view work on all objects just as with an Array. view is always lazy, and reads from disk are deferred until getindex is used. DimensionalData.jl Dimensions and Selectors are the other way to subset an object, making use of the objects index to find values at e.g. certain X/Y coordinates. The available selectors are listed here:

SelectorsDescription
At(x)get the index exactly matching the passed in value(s).
Near(x)get the closest index to the passed in value(s).
Where(f::Function)filter the array axis by a function of the dimension index values.
a..b/Between(a, b)get all indices between two values, excluding the high value.
Contains(x)get indices where the value x falls within an interval.

Info

  • Use the .. selector to take a view of madagascar:
julia
using Rasters, RasterDataSources
+const RS = Rasters
+using CairoMakie
+CairoMakie.activate!()
+
+A = Raster(WorldClim{BioClim}, 5)
+madagascar = view(A, X(43.25 .. 50.48), Y(-25.61 .. -12.04))
+# Note the space between .. -12
+Makie.plot(madagascar)

',33)]))}const E=a(p,[["render",l]]);export{g as __pageData,E as default}; diff --git a/previews/PR807/assets/huuwpka.CVxd1wxn.png b/previews/PR807/assets/huuwpka.CVxd1wxn.png new file mode 100644 index 00000000..43cf8b0b Binary files /dev/null and b/previews/PR807/assets/huuwpka.CVxd1wxn.png differ diff --git a/previews/PR807/assets/index.md.CYSmGW74.js b/previews/PR807/assets/index.md.CYSmGW74.js new file mode 100644 index 00000000..d5980064 --- /dev/null +++ b/previews/PR807/assets/index.md.CYSmGW74.js @@ -0,0 +1 @@ +import{_ as a,c as t,a5 as s,o as i}from"./chunks/framework.Cl7EIXwS.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Rasters.jl","tagline":"Manipulating rasterized spatial data","image":{"src":"/logo.png","alt":"Rasters"},"actions":[{"theme":"brand","text":"Get Started","link":"/get_started"},{"theme":"alt","text":"View on Github","link":"https://github.com/rafaqz/Rasters.jl"},{"theme":"alt","text":"API Reference","link":"/api"}]},"features":[{"title":"Rasters.jl","details":"Defines common types and methods for reading, writing and manipulating rasterized spatial data.","link":"/markdown-examples"},{"title":"Data Formats","details":"These currently include raster arrays like GeoTIF and NetCDF, R grd files, multi-layered stacks, and multi-file series of arrays and stacks."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}'),o={name:"index.md"};function n(l,e,r,d,c,p){return i(),t("div",null,e[0]||(e[0]=[s('

Data-source abstraction

Rasters provides a standardised interface that allows many source data types to be used with identical syntax.

  • Scripts and packages building on Rasters.jl can treat Raster, RasterStack, and RasterSeries as black boxes.

  • The data could hold GeoTiff or NetCDF files, Arrays in memory or CuArrays on the GPU - they will all behave in the same way.

  • RasterStack can be backed by a Netcdf or HDF5 file, or a NamedTuple of Raster holding .tif files, or all Raster in memory.

  • Users do not have to deal with the specifics of spatial file types.

  • Projected lookups with Cylindrical projections can by indexed using other Cylindrical projections by setting the mappedcrs keyword on construction. You don't need to know the underlying projection, the conversion is handled automatically. This means lat/lon EPSG(4326) can be used seamlessly if you need that.

Installation

julia
] add Rasters

Packages extensions

Packages extensions and Rasters 0.8 and onwards

On Julia 1.9 we can put additional packages in extensions, so the code only loads when you load a specific package. Rasters.jl was always intended to work like this, and its finally possible. This reduced package using time from many seconds to well under a second.

But, it means you have to manually load packages you need for each backend or additional functionality.

For example, to use the GDAL backend, and download files, you now need to do:

julia
using Rasters, ArchGDAL, RasterDataSources

where previously it was just using Rasters.

Sources and packages needed:

  • :gdal: using ArchGDAL

  • :netcdf: using NCDatasets

  • :grd: built-in.

  • :smap: using HDF5

  • :grib: not yet finished.

Other functionality in extensions:

  • Raster data downloads, like Worldclim{Climate}: using RasterDataSources

  • Makie plots: using Makie

  • Coordinate transformations for gdal rasters: using CoordinateTransformations

Bugs and errors

Bugs, errors and making issues for Rasters.jl

Raster data is complicated and there are many places for subtle or not-so-subtle bugs to creep in.

We need bug reports to reduce how often they occur over time. But also, we need issues that are easy to reproduce or it isn't practically possible to fix them.

Because there are so many raster file types and variations of them, most of the time we need the exact file that caused your problem to know how to fix it, and be sure that we have actually fixed it when we are done. So fixing a Rasters.jl bug nearly always involves downloading some file and running some code that breaks with it (if you can trigger the bug without a file, that's great! but its not always possible).

To make an issue we can fix quickly (or at all) there are three key steps:

  1. Include the file in an accessible place on web without authentication or any other work on our part, so we can just get it and find your bug. You can put it on a file hosting platform (e.g. google drive, drop box, whatever you use) and share the url.

  2. Add a minimum working example to the issue template that first downloads the file, then runs the function that triggers the bug.

  3. Paste the complete stack trace of the error it produces, right to the bottom, into the issue template. Then we can be sure we reproduced the same problem.

Good issues are really appreciated, but they do take just a little extra effort with Rasters.jl because of this need for files.

',14)]))}const g=a(o,[["render",n]]);export{h as __pageData,g as default}; diff --git a/previews/PR807/assets/index.md.CYSmGW74.lean.js b/previews/PR807/assets/index.md.CYSmGW74.lean.js new file mode 100644 index 00000000..d5980064 --- /dev/null +++ b/previews/PR807/assets/index.md.CYSmGW74.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,a5 as s,o as i}from"./chunks/framework.Cl7EIXwS.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Rasters.jl","tagline":"Manipulating rasterized spatial data","image":{"src":"/logo.png","alt":"Rasters"},"actions":[{"theme":"brand","text":"Get Started","link":"/get_started"},{"theme":"alt","text":"View on Github","link":"https://github.com/rafaqz/Rasters.jl"},{"theme":"alt","text":"API Reference","link":"/api"}]},"features":[{"title":"Rasters.jl","details":"Defines common types and methods for reading, writing and manipulating rasterized spatial data.","link":"/markdown-examples"},{"title":"Data Formats","details":"These currently include raster arrays like GeoTIF and NetCDF, R grd files, multi-layered stacks, and multi-file series of arrays and stacks."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":null}'),o={name:"index.md"};function n(l,e,r,d,c,p){return i(),t("div",null,e[0]||(e[0]=[s('

Data-source abstraction

Rasters provides a standardised interface that allows many source data types to be used with identical syntax.

  • Scripts and packages building on Rasters.jl can treat Raster, RasterStack, and RasterSeries as black boxes.

  • The data could hold GeoTiff or NetCDF files, Arrays in memory or CuArrays on the GPU - they will all behave in the same way.

  • RasterStack can be backed by a Netcdf or HDF5 file, or a NamedTuple of Raster holding .tif files, or all Raster in memory.

  • Users do not have to deal with the specifics of spatial file types.

  • Projected lookups with Cylindrical projections can by indexed using other Cylindrical projections by setting the mappedcrs keyword on construction. You don't need to know the underlying projection, the conversion is handled automatically. This means lat/lon EPSG(4326) can be used seamlessly if you need that.

Installation

julia
] add Rasters

Packages extensions

Packages extensions and Rasters 0.8 and onwards

On Julia 1.9 we can put additional packages in extensions, so the code only loads when you load a specific package. Rasters.jl was always intended to work like this, and its finally possible. This reduced package using time from many seconds to well under a second.

But, it means you have to manually load packages you need for each backend or additional functionality.

For example, to use the GDAL backend, and download files, you now need to do:

julia
using Rasters, ArchGDAL, RasterDataSources

where previously it was just using Rasters.

Sources and packages needed:

  • :gdal: using ArchGDAL

  • :netcdf: using NCDatasets

  • :grd: built-in.

  • :smap: using HDF5

  • :grib: not yet finished.

Other functionality in extensions:

  • Raster data downloads, like Worldclim{Climate}: using RasterDataSources

  • Makie plots: using Makie

  • Coordinate transformations for gdal rasters: using CoordinateTransformations

Bugs and errors

Bugs, errors and making issues for Rasters.jl

Raster data is complicated and there are many places for subtle or not-so-subtle bugs to creep in.

We need bug reports to reduce how often they occur over time. But also, we need issues that are easy to reproduce or it isn't practically possible to fix them.

Because there are so many raster file types and variations of them, most of the time we need the exact file that caused your problem to know how to fix it, and be sure that we have actually fixed it when we are done. So fixing a Rasters.jl bug nearly always involves downloading some file and running some code that breaks with it (if you can trigger the bug without a file, that's great! but its not always possible).

To make an issue we can fix quickly (or at all) there are three key steps:

  1. Include the file in an accessible place on web without authentication or any other work on our part, so we can just get it and find your bug. You can put it on a file hosting platform (e.g. google drive, drop box, whatever you use) and share the url.

  2. Add a minimum working example to the issue template that first downloads the file, then runs the function that triggers the bug.

  3. Paste the complete stack trace of the error it produces, right to the bottom, into the issue template. Then we can be sure we reproduced the same problem.

Good issues are really appreciated, but they do take just a little extra effort with Rasters.jl because of this need for files.

',14)]))}const g=a(o,[["render",n]]);export{h as __pageData,g as default}; diff --git a/previews/PR807/assets/indonesia_rasterized.CAASrLmh.png b/previews/PR807/assets/indonesia_rasterized.CAASrLmh.png new file mode 100644 index 00000000..5773fea7 Binary files /dev/null and b/previews/PR807/assets/indonesia_rasterized.CAASrLmh.png differ diff --git a/previews/PR807/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 b/previews/PR807/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 new file mode 100644 index 00000000..b6b603d5 Binary files /dev/null and b/previews/PR807/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 differ diff --git a/previews/PR807/assets/inter-italic-cyrillic.By2_1cv3.woff2 b/previews/PR807/assets/inter-italic-cyrillic.By2_1cv3.woff2 new file mode 100644 index 00000000..def40a4f Binary files /dev/null and b/previews/PR807/assets/inter-italic-cyrillic.By2_1cv3.woff2 differ diff --git a/previews/PR807/assets/inter-italic-greek-ext.1u6EdAuj.woff2 b/previews/PR807/assets/inter-italic-greek-ext.1u6EdAuj.woff2 new file mode 100644 index 00000000..e070c3d3 Binary files /dev/null and b/previews/PR807/assets/inter-italic-greek-ext.1u6EdAuj.woff2 differ diff --git a/previews/PR807/assets/inter-italic-greek.DJ8dCoTZ.woff2 b/previews/PR807/assets/inter-italic-greek.DJ8dCoTZ.woff2 new file mode 100644 index 00000000..a3c16ca4 Binary files /dev/null and b/previews/PR807/assets/inter-italic-greek.DJ8dCoTZ.woff2 differ diff --git a/previews/PR807/assets/inter-italic-latin-ext.CN1xVJS-.woff2 b/previews/PR807/assets/inter-italic-latin-ext.CN1xVJS-.woff2 new file mode 100644 index 00000000..2210a899 Binary files /dev/null and b/previews/PR807/assets/inter-italic-latin-ext.CN1xVJS-.woff2 differ diff --git a/previews/PR807/assets/inter-italic-latin.C2AdPX0b.woff2 b/previews/PR807/assets/inter-italic-latin.C2AdPX0b.woff2 new file mode 100644 index 00000000..790d62dc Binary files /dev/null and b/previews/PR807/assets/inter-italic-latin.C2AdPX0b.woff2 differ diff --git a/previews/PR807/assets/inter-italic-vietnamese.BSbpV94h.woff2 b/previews/PR807/assets/inter-italic-vietnamese.BSbpV94h.woff2 new file mode 100644 index 00000000..1eec0775 Binary files /dev/null and b/previews/PR807/assets/inter-italic-vietnamese.BSbpV94h.woff2 differ diff --git a/previews/PR807/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 b/previews/PR807/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 new file mode 100644 index 00000000..2cfe6153 Binary files /dev/null and b/previews/PR807/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 differ diff --git a/previews/PR807/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 b/previews/PR807/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 new file mode 100644 index 00000000..e3886dd1 Binary files /dev/null and b/previews/PR807/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 differ diff --git a/previews/PR807/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 b/previews/PR807/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 new file mode 100644 index 00000000..36d67487 Binary files /dev/null and b/previews/PR807/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 differ diff --git a/previews/PR807/assets/inter-roman-greek.BBVDIX6e.woff2 b/previews/PR807/assets/inter-roman-greek.BBVDIX6e.woff2 new file mode 100644 index 00000000..2bed1e85 Binary files /dev/null and b/previews/PR807/assets/inter-roman-greek.BBVDIX6e.woff2 differ diff --git a/previews/PR807/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 b/previews/PR807/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 new file mode 100644 index 00000000..9a8d1e2b Binary files /dev/null and b/previews/PR807/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 differ diff --git a/previews/PR807/assets/inter-roman-latin.Di8DUHzh.woff2 b/previews/PR807/assets/inter-roman-latin.Di8DUHzh.woff2 new file mode 100644 index 00000000..07d3c53a Binary files /dev/null and b/previews/PR807/assets/inter-roman-latin.Di8DUHzh.woff2 differ diff --git a/previews/PR807/assets/inter-roman-vietnamese.BjW4sHH5.woff2 b/previews/PR807/assets/inter-roman-vietnamese.BjW4sHH5.woff2 new file mode 100644 index 00000000..57bdc22a Binary files /dev/null and b/previews/PR807/assets/inter-roman-vietnamese.BjW4sHH5.woff2 differ diff --git a/previews/PR807/assets/itwpihm.CBMwZ7qg.png b/previews/PR807/assets/itwpihm.CBMwZ7qg.png new file mode 100644 index 00000000..288a96b7 Binary files /dev/null and b/previews/PR807/assets/itwpihm.CBMwZ7qg.png differ diff --git a/previews/PR807/assets/maoowux.CO0mgiME.png b/previews/PR807/assets/maoowux.CO0mgiME.png new file mode 100644 index 00000000..5d70e1e6 Binary files /dev/null and b/previews/PR807/assets/maoowux.CO0mgiME.png differ diff --git a/previews/PR807/assets/methods.md.tEJSj4eC.js b/previews/PR807/assets/methods.md.tEJSj4eC.js new file mode 100644 index 00000000..d1cd47d2 --- /dev/null +++ b/previews/PR807/assets/methods.md.tEJSj4eC.js @@ -0,0 +1 @@ +import{_ as e,c as a,a5 as s,o as r}from"./chunks/framework.Cl7EIXwS.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"methods.md","filePath":"methods.md","lastUpdated":null}'),o={name:"methods.md"};function l(d,t,i,n,c,h){return r(),a("div",null,t[0]||(t[0]=[s('

Methods that change the resolution or extent of an object

Click through to the function documentation for more in-depth descriptions and examples.

MethodsDescription
aggregateaggregate data by the same or different amounts for each axis.
disaggregatesimilarly disaggregate data.
mosaicjoin rasters covering different extents into a single array or file.
cropshrink objects to specific dimension sizes or the extent of another object.
extendextend objects to specific dimension sizes or the extent of another object.
trimtrims areas of missing values for arrays and across stack layers.
resampleresample data to a different size and projection, or snap to another object.
warpuse gdalwarp on any object, e.g. a multidimensional NetCDF stack.

Methods that change an objects values

Info

Note that most regular Julia methods, such as replace, work as for a standard Array. These additional methods are commonly required in GIS applications.

MethodsDescription
classifyclassify values into categories.
maskmask an object by a polygon or Raster along X/Y, or other dimensions.
replace_missingreplace all missing values in an object and update missingval.

Point, polygon and table operation

MethodsDescription
rasterizerasterize points and geometries.
extractextract values from points or geometries.
zonalcalculate zonal statistics for an object masked by geometries.

Methods to load, write and modify data sources

MethodsDescription
modifyreplace the data in objects. Useful to e.g. move objects to/from a GPU.
readread data to memory if it is on disk.
read!read data to predefined memory.
openopen the underlying data for manually reading or writing.
writewrite objects to file.
',10)]))}const g=e(o,[["render",l]]);export{p as __pageData,g as default}; diff --git a/previews/PR807/assets/methods.md.tEJSj4eC.lean.js b/previews/PR807/assets/methods.md.tEJSj4eC.lean.js new file mode 100644 index 00000000..d1cd47d2 --- /dev/null +++ b/previews/PR807/assets/methods.md.tEJSj4eC.lean.js @@ -0,0 +1 @@ +import{_ as e,c as a,a5 as s,o as r}from"./chunks/framework.Cl7EIXwS.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"methods.md","filePath":"methods.md","lastUpdated":null}'),o={name:"methods.md"};function l(d,t,i,n,c,h){return r(),a("div",null,t[0]||(t[0]=[s('

Methods that change the resolution or extent of an object

Click through to the function documentation for more in-depth descriptions and examples.

MethodsDescription
aggregateaggregate data by the same or different amounts for each axis.
disaggregatesimilarly disaggregate data.
mosaicjoin rasters covering different extents into a single array or file.
cropshrink objects to specific dimension sizes or the extent of another object.
extendextend objects to specific dimension sizes or the extent of another object.
trimtrims areas of missing values for arrays and across stack layers.
resampleresample data to a different size and projection, or snap to another object.
warpuse gdalwarp on any object, e.g. a multidimensional NetCDF stack.

Methods that change an objects values

Info

Note that most regular Julia methods, such as replace, work as for a standard Array. These additional methods are commonly required in GIS applications.

MethodsDescription
classifyclassify values into categories.
maskmask an object by a polygon or Raster along X/Y, or other dimensions.
replace_missingreplace all missing values in an object and update missingval.

Point, polygon and table operation

MethodsDescription
rasterizerasterize points and geometries.
extractextract values from points or geometries.
zonalcalculate zonal statistics for an object masked by geometries.

Methods to load, write and modify data sources

MethodsDescription
modifyreplace the data in objects. Useful to e.g. move objects to/from a GPU.
readread data to memory if it is on disk.
read!read data to predefined memory.
openopen the underlying data for manually reading or writing.
writewrite objects to file.
',10)]))}const g=e(o,[["render",l]]);export{p as __pageData,g as default}; diff --git a/previews/PR807/assets/mosaic_bang_example.ptHNiUCT.png b/previews/PR807/assets/mosaic_bang_example.ptHNiUCT.png new file mode 100644 index 00000000..974dd8e4 Binary files /dev/null and b/previews/PR807/assets/mosaic_bang_example.ptHNiUCT.png differ diff --git a/previews/PR807/assets/mosaic_example_africa.Dpr9JnNl.png b/previews/PR807/assets/mosaic_example_africa.Dpr9JnNl.png new file mode 100644 index 00000000..95db5ce0 Binary files /dev/null and b/previews/PR807/assets/mosaic_example_africa.Dpr9JnNl.png differ diff --git a/previews/PR807/assets/mosaic_example_aus.3EfcKnQU.png b/previews/PR807/assets/mosaic_example_aus.3EfcKnQU.png new file mode 100644 index 00000000..694a77d9 Binary files /dev/null and b/previews/PR807/assets/mosaic_example_aus.3EfcKnQU.png differ diff --git a/previews/PR807/assets/mosaic_example_combined.XY5Q_nfP.png b/previews/PR807/assets/mosaic_example_combined.XY5Q_nfP.png new file mode 100644 index 00000000..94005ed4 Binary files /dev/null and b/previews/PR807/assets/mosaic_example_combined.XY5Q_nfP.png differ diff --git a/previews/PR807/assets/motceku.oyWWmvC1.png b/previews/PR807/assets/motceku.oyWWmvC1.png new file mode 100644 index 00000000..40438a0c Binary files /dev/null and b/previews/PR807/assets/motceku.oyWWmvC1.png differ diff --git a/previews/PR807/assets/nuekexd.BRgQ_uqM.png b/previews/PR807/assets/nuekexd.BRgQ_uqM.png new file mode 100644 index 00000000..fc0327dd Binary files /dev/null and b/previews/PR807/assets/nuekexd.BRgQ_uqM.png differ diff --git a/previews/PR807/assets/nz_crop_example.CeBIxUDy.png b/previews/PR807/assets/nz_crop_example.CeBIxUDy.png new file mode 100644 index 00000000..41a0304f Binary files /dev/null and b/previews/PR807/assets/nz_crop_example.CeBIxUDy.png differ diff --git a/previews/PR807/assets/olovemv.CVwZE_Z9.png b/previews/PR807/assets/olovemv.CVwZE_Z9.png new file mode 100644 index 00000000..0f46062e Binary files /dev/null and b/previews/PR807/assets/olovemv.CVwZE_Z9.png differ diff --git a/previews/PR807/assets/ouepwku.BPZOvOxi.png b/previews/PR807/assets/ouepwku.BPZOvOxi.png new file mode 100644 index 00000000..3f00b7e3 Binary files /dev/null and b/previews/PR807/assets/ouepwku.BPZOvOxi.png differ diff --git a/previews/PR807/assets/plot_makie.md.DYZzsleT.js b/previews/PR807/assets/plot_makie.md.DYZzsleT.js new file mode 100644 index 00000000..7199f260 --- /dev/null +++ b/previews/PR807/assets/plot_makie.md.DYZzsleT.js @@ -0,0 +1,78 @@ +import{_ as n,c as e,a5 as a,j as i,a as l,G as h,B as p,o as k}from"./chunks/framework.Cl7EIXwS.js";const r="/Rasters.jl/previews/PR807/assets/fzzzwbh.ALj2aDbZ.png",d="/Rasters.jl/previews/PR807/assets/vxnkhbp.Dw_eTAB7.png",o="/Rasters.jl/previews/PR807/assets/swkcnzv.B2QjG_n4.png",E="/Rasters.jl/previews/PR807/assets/rplot.CwrU8Sen.mp4",g="/Rasters.jl/previews/PR807/assets/aus_trim.B4Z7jnS4.png",D=JSON.parse('{"title":"reset theme","description":"","frontmatter":{},"headers":[],"relativePath":"plot_makie.md","filePath":"plot_makie.md","lastUpdated":null}'),c={name:"plot_makie.md"},y={class:"jldocstring custom-block",open:""};function F(u,s,C,m,b,f){const t=p("Badge");return k(),e("div",null,[s[3]||(s[3]=a(`

Plotting in Makie

Plotting in Makie works somewhat differently than Plots, since the recipe system is different. You can pass a 2-D raster to any surface-like function (heatmap, contour, contourf, or even surface for a 3D plot) with ease.

2-D rasters in Makie

julia
using CairoMakie, Makie
+using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5) # this is a 3D raster, so is not accepted.
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701
julia
fig, ax, _ = plot(A)
+contour(fig[1, 2], A)
+ax = Axis(fig[2, 1]; aspect = DataAspect())
+contourf!(ax, A)
+surface(fig[2, 2], A) # even a 3D plot work!
+fig

3-D rasters in Makie

Warning

This interface is experimental, and unexported for that reason. It may break at any time!

Just as in Plots, 3D rasters are treated as a series of 2D rasters, which are tiled and plotted.

You can use Rasters.rplot to visualize 3D rasters or RasterStacks in this way. An example is below:

julia
stack = RasterStack(WorldClim{Climate}; month = 1)
+Rasters.rplot(stack; Axis = (aspect = DataAspect(),),)

You can pass any theming keywords in, which are interpreted by Makie appropriately.

The plots seem a little squished here. We provide a Makie theme which makes text a little smaller and has some other space-efficient attributes:

julia
Makie.set_theme!(Rasters.theme_rasters())
+Rasters.rplot(stack)

reset theme

julia
Makie.set_theme!()

Plotting with Observables, animations

Rasters.rplot should support Observable input out of the box, but the dimensions of that input must remain the same - i.e., the element names of a RasterStack must remain the same.

julia
Makie.set_theme!(Rasters.theme_rasters())
+# \`stack\` is the WorldClim climate data for January
+stack_obs = Observable(stack)
+fig = Rasters.rplot(stack_obs;
+    Colorbar=(; height=Relative(0.75), width=5)
+)
+record(fig, "rplot.mp4", 1:12; framerate = 3) do i
+    stack_obs[] = RasterStack(WorldClim{Climate}; month = i)
+end
"rplot.mp4"

julia
Makie.set_theme!() # reset theme
',25)),i("details",y,[i("summary",null,[s[0]||(s[0]=i("a",{id:"Rasters.rplot",href:"#Rasters.rplot"},[i("span",{class:"jlbinding"},"Rasters.rplot")],-1)),s[1]||(s[1]=l()),h(t,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[2]||(s[2]=a('
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

  • plottype = Makie.Heatmap: The type of plot. Can be any Makie plot type which accepts a Raster; in practice, Heatmap, Contour, Contourf and Surface are the best bets.

  • axistype = Makie.Axis: The type of axis. This can be an Axis, Axis3, LScene, or even a GeoAxis from GeoMakie.jl.

  • X = XDim: The X dimension of the raster.

  • Y = YDim: The Y dimension of the raster.

  • Z = YDim: The Y dimension of the raster.

  • draw_colorbar = true: Whether to draw a colorbar for the axis or not.

  • colorbar_position = Makie.Right(): Indicates which side of the axis the colorbar should be placed on. Can be Makie.Top(), Makie.Bottom(), Makie.Left(), or Makie.Right().

  • colorbar_padding = Makie.automatic: The amount of padding between the colorbar and its axis. If automatic, then this is set to the width of the colorbar.

  • title = Makie.automatic: The titles of each plot. If automatic, these are set to the name of the band.

  • xlabel = Makie.automatic: The x-label for the axis. If automatic, set to the dimension name of the X-dimension of the raster.

  • ylabel = Makie.automatic: The y-label for the axis. If automatic, set to the dimension name of the Y-dimension of the raster.

  • colorbarlabel = "": Usually nothing, but here if you need it. Sets the label on the colorbar.

  • colormap = nothing: The colormap for the heatmap. This can be set to a vector of colormaps (symbols, strings, cgrads) if plotting a 3D raster or RasterStack.

  • colorrange = Makie.automatic: The colormap for the heatmap. This can be set to a vector of (low, high) if plotting a 3D raster or RasterStack.

  • nan_color = :transparent: The color which NaN values should take. Default to transparent.

source

',5))]),s[4]||(s[4]=a(`

Using vanilla Makie

julia
using Rasters, RasterDataSources

The data

julia
layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+ausbounds = X(100 .. 160), Y(-50 .. -10) # Roughly cut out australia
+aus = st[ausbounds...] |> Rasters.trim
╭─────────────────────╮
+│ 194×161 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(113.33333333333336, 153.54166666666666, 194) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-10.20833333333334, -43.54166666666667, 161) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :evenness    eltype: UInt16 dims: X, Y size: 194×161
+  :range       eltype: UInt16 dims: X, Y size: 194×161
+  :contrast    eltype: UInt32 dims: X, Y size: 194×161
+  :correlation eltype: UInt16 dims: X, Y size: 194×161
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (113.33333333333336, 153.75), Y = (-43.54166666666667, -10.000000000000005))
+  missingval: (evenness = 0xffff, range = 0xffff, contrast = 0xffffffff, correlation = 0xffff)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

The plot

julia
# colorbar attributes
+colormap = :batlow
+flipaxis = false
+tickalign=1
+width = 13
+ticksize = 13
+# figure
+with_theme(theme_dark()) do
+    fig = Figure(; size=(600, 600), backgroundcolor=:transparent)
+    axs = [Axis(fig[i,j], xlabel = "lon", ylabel = "lat",
+        backgroundcolor=:transparent) for i in 1:2 for j in 1:2]
+    plt = [Makie.heatmap!(axs[i], aus[l]; colormap) for (i, l) in enumerate(layers)]
+    for (i, l) in enumerate(layers) axs[i].title = string(l) end
+    hidexdecorations!.(axs[1:2]; grid=false, ticks=false)
+    hideydecorations!.(axs[[2,4]]; grid=false, ticks=false)
+    Colorbar(fig[1, 0], plt[1]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[1, 3], plt[2]; tickalign, width, ticksize)
+    Colorbar(fig[2, 0], plt[3]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[2, 3], plt[4]; tickalign, width, ticksize)
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    Label(fig[0, :], "RasterStack of EarthEnv HabitatHeterogeneity layers, trimmed to Australia")
+    fig
+end
+save("aus_trim.png", current_figure());
CairoMakie.Screen{IMAGE}

',9))])}const v=n(c,[["render",F]]);export{D as __pageData,v as default}; diff --git a/previews/PR807/assets/plot_makie.md.DYZzsleT.lean.js b/previews/PR807/assets/plot_makie.md.DYZzsleT.lean.js new file mode 100644 index 00000000..7199f260 --- /dev/null +++ b/previews/PR807/assets/plot_makie.md.DYZzsleT.lean.js @@ -0,0 +1,78 @@ +import{_ as n,c as e,a5 as a,j as i,a as l,G as h,B as p,o as k}from"./chunks/framework.Cl7EIXwS.js";const r="/Rasters.jl/previews/PR807/assets/fzzzwbh.ALj2aDbZ.png",d="/Rasters.jl/previews/PR807/assets/vxnkhbp.Dw_eTAB7.png",o="/Rasters.jl/previews/PR807/assets/swkcnzv.B2QjG_n4.png",E="/Rasters.jl/previews/PR807/assets/rplot.CwrU8Sen.mp4",g="/Rasters.jl/previews/PR807/assets/aus_trim.B4Z7jnS4.png",D=JSON.parse('{"title":"reset theme","description":"","frontmatter":{},"headers":[],"relativePath":"plot_makie.md","filePath":"plot_makie.md","lastUpdated":null}'),c={name:"plot_makie.md"},y={class:"jldocstring custom-block",open:""};function F(u,s,C,m,b,f){const t=p("Badge");return k(),e("div",null,[s[3]||(s[3]=a(`

Plotting in Makie

Plotting in Makie works somewhat differently than Plots, since the recipe system is different. You can pass a 2-D raster to any surface-like function (heatmap, contour, contourf, or even surface for a 3D plot) with ease.

2-D rasters in Makie

julia
using CairoMakie, Makie
+using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5) # this is a 3D raster, so is not accepted.
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701
julia
fig, ax, _ = plot(A)
+contour(fig[1, 2], A)
+ax = Axis(fig[2, 1]; aspect = DataAspect())
+contourf!(ax, A)
+surface(fig[2, 2], A) # even a 3D plot work!
+fig

3-D rasters in Makie

Warning

This interface is experimental, and unexported for that reason. It may break at any time!

Just as in Plots, 3D rasters are treated as a series of 2D rasters, which are tiled and plotted.

You can use Rasters.rplot to visualize 3D rasters or RasterStacks in this way. An example is below:

julia
stack = RasterStack(WorldClim{Climate}; month = 1)
+Rasters.rplot(stack; Axis = (aspect = DataAspect(),),)

You can pass any theming keywords in, which are interpreted by Makie appropriately.

The plots seem a little squished here. We provide a Makie theme which makes text a little smaller and has some other space-efficient attributes:

julia
Makie.set_theme!(Rasters.theme_rasters())
+Rasters.rplot(stack)

reset theme

julia
Makie.set_theme!()

Plotting with Observables, animations

Rasters.rplot should support Observable input out of the box, but the dimensions of that input must remain the same - i.e., the element names of a RasterStack must remain the same.

julia
Makie.set_theme!(Rasters.theme_rasters())
+# \`stack\` is the WorldClim climate data for January
+stack_obs = Observable(stack)
+fig = Rasters.rplot(stack_obs;
+    Colorbar=(; height=Relative(0.75), width=5)
+)
+record(fig, "rplot.mp4", 1:12; framerate = 3) do i
+    stack_obs[] = RasterStack(WorldClim{Climate}; month = i)
+end
"rplot.mp4"

julia
Makie.set_theme!() # reset theme
',25)),i("details",y,[i("summary",null,[s[0]||(s[0]=i("a",{id:"Rasters.rplot",href:"#Rasters.rplot"},[i("span",{class:"jlbinding"},"Rasters.rplot")],-1)),s[1]||(s[1]=l()),h(t,{type:"info",class:"jlObjectType jlFunction",text:"Function"})]),s[2]||(s[2]=a('
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

  • plottype = Makie.Heatmap: The type of plot. Can be any Makie plot type which accepts a Raster; in practice, Heatmap, Contour, Contourf and Surface are the best bets.

  • axistype = Makie.Axis: The type of axis. This can be an Axis, Axis3, LScene, or even a GeoAxis from GeoMakie.jl.

  • X = XDim: The X dimension of the raster.

  • Y = YDim: The Y dimension of the raster.

  • Z = YDim: The Y dimension of the raster.

  • draw_colorbar = true: Whether to draw a colorbar for the axis or not.

  • colorbar_position = Makie.Right(): Indicates which side of the axis the colorbar should be placed on. Can be Makie.Top(), Makie.Bottom(), Makie.Left(), or Makie.Right().

  • colorbar_padding = Makie.automatic: The amount of padding between the colorbar and its axis. If automatic, then this is set to the width of the colorbar.

  • title = Makie.automatic: The titles of each plot. If automatic, these are set to the name of the band.

  • xlabel = Makie.automatic: The x-label for the axis. If automatic, set to the dimension name of the X-dimension of the raster.

  • ylabel = Makie.automatic: The y-label for the axis. If automatic, set to the dimension name of the Y-dimension of the raster.

  • colorbarlabel = "": Usually nothing, but here if you need it. Sets the label on the colorbar.

  • colormap = nothing: The colormap for the heatmap. This can be set to a vector of colormaps (symbols, strings, cgrads) if plotting a 3D raster or RasterStack.

  • colorrange = Makie.automatic: The colormap for the heatmap. This can be set to a vector of (low, high) if plotting a 3D raster or RasterStack.

  • nan_color = :transparent: The color which NaN values should take. Default to transparent.

source

',5))]),s[4]||(s[4]=a(`

Using vanilla Makie

julia
using Rasters, RasterDataSources

The data

julia
layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+ausbounds = X(100 .. 160), Y(-50 .. -10) # Roughly cut out australia
+aus = st[ausbounds...] |> Rasters.trim
╭─────────────────────╮
+│ 194×161 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(113.33333333333336, 153.54166666666666, 194) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-10.20833333333334, -43.54166666666667, 161) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :evenness    eltype: UInt16 dims: X, Y size: 194×161
+  :range       eltype: UInt16 dims: X, Y size: 194×161
+  :contrast    eltype: UInt32 dims: X, Y size: 194×161
+  :correlation eltype: UInt16 dims: X, Y size: 194×161
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (113.33333333333336, 153.75), Y = (-43.54166666666667, -10.000000000000005))
+  missingval: (evenness = 0xffff, range = 0xffff, contrast = 0xffffffff, correlation = 0xffff)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

The plot

julia
# colorbar attributes
+colormap = :batlow
+flipaxis = false
+tickalign=1
+width = 13
+ticksize = 13
+# figure
+with_theme(theme_dark()) do
+    fig = Figure(; size=(600, 600), backgroundcolor=:transparent)
+    axs = [Axis(fig[i,j], xlabel = "lon", ylabel = "lat",
+        backgroundcolor=:transparent) for i in 1:2 for j in 1:2]
+    plt = [Makie.heatmap!(axs[i], aus[l]; colormap) for (i, l) in enumerate(layers)]
+    for (i, l) in enumerate(layers) axs[i].title = string(l) end
+    hidexdecorations!.(axs[1:2]; grid=false, ticks=false)
+    hideydecorations!.(axs[[2,4]]; grid=false, ticks=false)
+    Colorbar(fig[1, 0], plt[1]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[1, 3], plt[2]; tickalign, width, ticksize)
+    Colorbar(fig[2, 0], plt[3]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[2, 3], plt[4]; tickalign, width, ticksize)
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    Label(fig[0, :], "RasterStack of EarthEnv HabitatHeterogeneity layers, trimmed to Australia")
+    fig
+end
+save("aus_trim.png", current_figure());
CairoMakie.Screen{IMAGE}

',9))])}const v=n(c,[["render",F]]);export{D as __pageData,v as default}; diff --git a/previews/PR807/assets/plotting.md.n1eGQxVQ.js b/previews/PR807/assets/plotting.md.n1eGQxVQ.js new file mode 100644 index 00000000..288b22f5 --- /dev/null +++ b/previews/PR807/assets/plotting.md.n1eGQxVQ.js @@ -0,0 +1,135 @@ +import{_ as a,c as i,a5 as n,o as t}from"./chunks/framework.Cl7EIXwS.js";const e="/Rasters.jl/previews/PR807/assets/motceku.oyWWmvC1.png",p="/Rasters.jl/previews/PR807/assets/nuekexd.BRgQ_uqM.png",l="/Rasters.jl/previews/PR807/assets/edcrsgk.2YhfOv1i.png",h="/Rasters.jl/previews/PR807/assets/maoowux.CO0mgiME.png",k="/Rasters.jl/previews/PR807/assets/qeatmhs.BsE3Kr89.png",o="/Rasters.jl/previews/PR807/assets/huuwpka.CVxd1wxn.png",d="/Rasters.jl/previews/PR807/assets/ouepwku.BPZOvOxi.png",r="/Rasters.jl/previews/PR807/assets/xqojlxo.Djo3H46f.png",c="/Rasters.jl/previews/PR807/assets/uedqoev.CUldC_pQ.png",g="/Rasters.jl/previews/PR807/assets/eqdfnkz.8o5RdXOt.png",E="/Rasters.jl/previews/PR807/assets/spxvigw.D9tQTCLW.png",u="/Rasters.jl/previews/PR807/assets/ryavibo.H6rBHY04.png",D=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"plotting.md","filePath":"plotting.md","lastUpdated":null}'),y={name:"plotting.md"};function m(F,s,C,v,b,q){return t(),i("div",null,s[0]||(s[0]=[n(`

Plots, simple

Plots.jl and Makie.jl are fully supported by Rasters.jl, with recipes for plotting Raster and RasterStack provided. plot will plot a heatmap with axes matching dimension values. If mappedcrs is used, converted values will be shown on axes instead of the underlying crs values. contourf will similarly plot a filled contour plot.

Pixel resolution is limited to allow loading very large files quickly. max_res specifies the maximum pixel resolution to show on the longest axis of the array. It can be set manually to change the resolution (e.g. for large or high-quality plots):

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{BioClim}, 5)
+plot(A; max_res=3000)

For Makie, plot functions in a similar way. plot will only accept two-dimensional rasters. You can invoke contour, contourf, heatmap, surface or any Makie plotting function which supports surface-like data on a 2D raster.

To obtain tiled plots for 3D rasters and RasterStacks, use the function Rasters.rplot([gridposition], raster; kw_args...). This is an unexported function, since we're not sure how the API will change going forward.

Makie, simple

julia
using CairoMakie
+CairoMakie.activate!(px_per_unit = 2)
+using Rasters, CairoMakie, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5)
+Makie.plot(A)

Loading data

Our first example simply loads a file from disk and plots it.

This netcdf file only has one layer, if it has more we could use RasterStack instead.

julia
using Rasters, NCDatasets, Plots
+using Downloads: download
+
+url = "https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc";
+filename = download(url, "tos_O1_2001-2002.nc");
+A = Raster(filename)
╭──────────────────────────────────────────────────╮
+│ 180×170×24 Raster{Union{Missing, Float32},3} tos │
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} [DateTime360Day(2001-01-16T00:00:00), …, DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Objects with Dimensions other than X and Y will produce multi-pane plots. Here we plot every third month in the first year in one plot:

julia
A[Ti=1:3:12] |> plot

Now plot the ocean temperatures around the Americas in the first month of 2001. Notice we are using lat/lon coordinates and date/time instead of regular indices. The time dimension uses DateTime360Day, so we need to load CFTime.jl to index it with Near.

julia
using CFTime
+A[Ti(Near(DateTime360Day(2001, 01, 17))), Y(-60.0 .. 90.0), X(45.0 .. 190.0)] |> plot

Now get the mean over the timespan, then save it to disk, and plot it as a filled contour.

Other plot functions and sliced objects that have only one X/Y/Z dimension fall back to generic DimensionalData.jl plotting, which will still correctly label plot axes.

julia
using Statistics
+# Take the mean
+mean_tos = mean(A; dims=Ti)
╭─────────────────────────────────────────────────╮
+│ 180×170×1 Raster{Union{Missing, Float32},3} tos │
+├─────────────────────────────────────────────────┴────────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} DateTime360Day(2002-01-16T00:00:00):Millisecond(2592000000):DateTime360Day(2002-01-16T00:00:00) ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Plot a contour plot

julia
using Plots
+Plots.contourf(mean_tos; dpi=300, size=(800, 400))

write to disk

Write the mean values to disk

julia
write("mean_tos.nc", mean_tos)
"mean_tos.nc"

Plotting recipes in DimensionalData.jl are the fallback for Rasters.jl when the object doesn't have 2 X/Y/Z dimensions, or a non-spatial plot command is used. So (as a random example) we could plot a transect of ocean surface temperature at 20 degree latitude :

julia
A[Y(Near(20.0)), Ti(1)] |> plot

Polygon masking, mosaic and plot

In this example we will mask the Scandinavian countries with border polygons, then mosaic together to make a single plot.

First, get the country boundary shape files using GADM.jl.

using Rasters, RasterDataSources, ArchGDAL, Shapefile, Plots, Dates, Downloads, NCDatasets

Download the shapefile

julia
using Downloads
+using Shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary_lines.shp"
+Downloads.download(shapefile_url, shapefile_name);

Load using Shapefile.jl

julia
shapes = Shapefile.Handle(shapefile_name)
+denmark_border = shapes.shapes[71]
+norway_border = shapes.shapes[53]
+sweden_border = shapes.shapes[54];

Then load raster data. We load some worldclim layers using RasterDataSources via Rasters.jl:

julia
using Rasters, RasterDataSources
+using Dates
+climate = RasterStack(WorldClim{Climate}, (:tmin, :tmax, :prec, :wind); month=July)
╭───────────────────────╮
+│ 2160×1080 RasterStack │
+├───────────────────────┴──────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 2160×1080
+  :tmax eltype: Float32 dims: X, Y size: 2160×1080
+  :prec eltype: Int16 dims: X, Y size: 2160×1080
+  :wind eltype: Float32 dims: X, Y size: 2160×1080
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

mask Denmark, Norway and Sweden from the global dataset using their border polygon, then trim the missing values. We pad trim with a 10 pixel margin.

julia
mask_trim(climate, poly) = trim(mask(climate; with=poly); pad=10)
+
+denmark = mask_trim(climate, denmark_border)
+norway = mask_trim(climate, norway_border)
+sweden = mask_trim(climate, sweden_border)
╭────────────────────╮
+│ 98×102 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(9.499999999999972, 25.666666666666643, 98) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(70.5, 53.66666666666667, 102) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 98×102
+  :tmax eltype: Float32 dims: X, Y size: 98×102
+  :prec eltype: Int16 dims: X, Y size: 98×102
+  :wind eltype: Float32 dims: X, Y size: 98×102
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (9.499999999999972, 25.83333333333331), Y = (53.66666666666667, 70.66666666666667))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plotting with Plots.jl

First define a function to add borders to all subplots.

julia
function borders!(p, poly)
+    for i in 1:length(p)
+        Plots.plot!(p, poly; subplot=i, fillalpha=0, linewidth=0.6)
+    end
+    return p
+end
borders! (generic function with 1 method)

Now we can plot the individual countries.

julia
dp = plot(denmark)
+borders!(dp, denmark_border)

and sweden

julia
sp = plot(sweden)
+borders!(sp, sweden_border)

and norway

julia
np = plot(norway)
+borders!(np, norway_border)

The Norway shape includes a lot of islands. Lets crop them out using .. intervals:

julia
norway_region = climate[X(0..40), Y(55..73)]
+plot(norway_region)

And mask it with the border again:

julia
norway = mask_trim(norway_region, norway_border)
+np = plot(norway)
+borders!(np, norway_border)

Now we can combine the countries into a single raster using mosaic. first will take the first value if/when there is an overlap.

julia
scandinavia = mosaic(first, denmark, norway, sweden)
╭─────────────────────╮
+│ 177×119 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} 3.1666666666666443:0.16666666666666666:32.49999999999998 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} 72.66666666666666:-0.16666666666666666:52.99999999999999 ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 177×119
+  :tmax eltype: Float32 dims: X, Y size: 177×119
+  :prec eltype: Int16 dims: X, Y size: 177×119
+  :wind eltype: Float32 dims: X, Y size: 177×119
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (3.1666666666666443, 32.66666666666664), Y = (52.99999999999999, 72.83333333333333))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

And plot scandinavia, with all borders included:

julia
p = plot(scandinavia)
+borders!(p, denmark_border)
+borders!(p, norway_border)
+borders!(p, sweden_border)
+p

And save to netcdf - a single multi-layered file, and tif, which will write a file for each stack layer.

julia
write("scandinavia.nc", scandinavia)
+write("scandinavia.tif", scandinavia)
(tmin = "scandinavia_tmin.tif", tmax = "scandinavia_tmax.tif", prec = "scandinavia_prec.tif", wind = "scandinavia_wind.tif")

Rasters.jl provides a range of other methods that are being added to over time. Where applicable these methods read and write lazily to and from disk-based arrays of common raster file types. These methods also work for entire RasterStacks and RasterSeries using the same syntax.

`,78)]))}const f=a(y,[["render",m]]);export{D as __pageData,f as default}; diff --git a/previews/PR807/assets/plotting.md.n1eGQxVQ.lean.js b/previews/PR807/assets/plotting.md.n1eGQxVQ.lean.js new file mode 100644 index 00000000..288b22f5 --- /dev/null +++ b/previews/PR807/assets/plotting.md.n1eGQxVQ.lean.js @@ -0,0 +1,135 @@ +import{_ as a,c as i,a5 as n,o as t}from"./chunks/framework.Cl7EIXwS.js";const e="/Rasters.jl/previews/PR807/assets/motceku.oyWWmvC1.png",p="/Rasters.jl/previews/PR807/assets/nuekexd.BRgQ_uqM.png",l="/Rasters.jl/previews/PR807/assets/edcrsgk.2YhfOv1i.png",h="/Rasters.jl/previews/PR807/assets/maoowux.CO0mgiME.png",k="/Rasters.jl/previews/PR807/assets/qeatmhs.BsE3Kr89.png",o="/Rasters.jl/previews/PR807/assets/huuwpka.CVxd1wxn.png",d="/Rasters.jl/previews/PR807/assets/ouepwku.BPZOvOxi.png",r="/Rasters.jl/previews/PR807/assets/xqojlxo.Djo3H46f.png",c="/Rasters.jl/previews/PR807/assets/uedqoev.CUldC_pQ.png",g="/Rasters.jl/previews/PR807/assets/eqdfnkz.8o5RdXOt.png",E="/Rasters.jl/previews/PR807/assets/spxvigw.D9tQTCLW.png",u="/Rasters.jl/previews/PR807/assets/ryavibo.H6rBHY04.png",D=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"plotting.md","filePath":"plotting.md","lastUpdated":null}'),y={name:"plotting.md"};function m(F,s,C,v,b,q){return t(),i("div",null,s[0]||(s[0]=[n(`

Plots, simple

Plots.jl and Makie.jl are fully supported by Rasters.jl, with recipes for plotting Raster and RasterStack provided. plot will plot a heatmap with axes matching dimension values. If mappedcrs is used, converted values will be shown on axes instead of the underlying crs values. contourf will similarly plot a filled contour plot.

Pixel resolution is limited to allow loading very large files quickly. max_res specifies the maximum pixel resolution to show on the longest axis of the array. It can be set manually to change the resolution (e.g. for large or high-quality plots):

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{BioClim}, 5)
+plot(A; max_res=3000)

For Makie, plot functions in a similar way. plot will only accept two-dimensional rasters. You can invoke contour, contourf, heatmap, surface or any Makie plotting function which supports surface-like data on a 2D raster.

To obtain tiled plots for 3D rasters and RasterStacks, use the function Rasters.rplot([gridposition], raster; kw_args...). This is an unexported function, since we're not sure how the API will change going forward.

Makie, simple

julia
using CairoMakie
+CairoMakie.activate!(px_per_unit = 2)
+using Rasters, CairoMakie, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5)
+Makie.plot(A)

Loading data

Our first example simply loads a file from disk and plots it.

This netcdf file only has one layer, if it has more we could use RasterStack instead.

julia
using Rasters, NCDatasets, Plots
+using Downloads: download
+
+url = "https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc";
+filename = download(url, "tos_O1_2001-2002.nc");
+A = Raster(filename)
╭──────────────────────────────────────────────────╮
+│ 180×170×24 Raster{Union{Missing, Float32},3} tos │
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} [DateTime360Day(2001-01-16T00:00:00), …, DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Objects with Dimensions other than X and Y will produce multi-pane plots. Here we plot every third month in the first year in one plot:

julia
A[Ti=1:3:12] |> plot

Now plot the ocean temperatures around the Americas in the first month of 2001. Notice we are using lat/lon coordinates and date/time instead of regular indices. The time dimension uses DateTime360Day, so we need to load CFTime.jl to index it with Near.

julia
using CFTime
+A[Ti(Near(DateTime360Day(2001, 01, 17))), Y(-60.0 .. 90.0), X(45.0 .. 190.0)] |> plot

Now get the mean over the timespan, then save it to disk, and plot it as a filled contour.

Other plot functions and sliced objects that have only one X/Y/Z dimension fall back to generic DimensionalData.jl plotting, which will still correctly label plot axes.

julia
using Statistics
+# Take the mean
+mean_tos = mean(A; dims=Ti)
╭─────────────────────────────────────────────────╮
+│ 180×170×1 Raster{Union{Missing, Float32},3} tos │
+├─────────────────────────────────────────────────┴────────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} DateTime360Day(2002-01-16T00:00:00):Millisecond(2592000000):DateTime360Day(2002-01-16T00:00:00) ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Plot a contour plot

julia
using Plots
+Plots.contourf(mean_tos; dpi=300, size=(800, 400))

write to disk

Write the mean values to disk

julia
write("mean_tos.nc", mean_tos)
"mean_tos.nc"

Plotting recipes in DimensionalData.jl are the fallback for Rasters.jl when the object doesn't have 2 X/Y/Z dimensions, or a non-spatial plot command is used. So (as a random example) we could plot a transect of ocean surface temperature at 20 degree latitude :

julia
A[Y(Near(20.0)), Ti(1)] |> plot

Polygon masking, mosaic and plot

In this example we will mask the Scandinavian countries with border polygons, then mosaic together to make a single plot.

First, get the country boundary shape files using GADM.jl.

using Rasters, RasterDataSources, ArchGDAL, Shapefile, Plots, Dates, Downloads, NCDatasets

Download the shapefile

julia
using Downloads
+using Shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary_lines.shp"
+Downloads.download(shapefile_url, shapefile_name);

Load using Shapefile.jl

julia
shapes = Shapefile.Handle(shapefile_name)
+denmark_border = shapes.shapes[71]
+norway_border = shapes.shapes[53]
+sweden_border = shapes.shapes[54];

Then load raster data. We load some worldclim layers using RasterDataSources via Rasters.jl:

julia
using Rasters, RasterDataSources
+using Dates
+climate = RasterStack(WorldClim{Climate}, (:tmin, :tmax, :prec, :wind); month=July)
╭───────────────────────╮
+│ 2160×1080 RasterStack │
+├───────────────────────┴──────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 2160×1080
+  :tmax eltype: Float32 dims: X, Y size: 2160×1080
+  :prec eltype: Int16 dims: X, Y size: 2160×1080
+  :wind eltype: Float32 dims: X, Y size: 2160×1080
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

mask Denmark, Norway and Sweden from the global dataset using their border polygon, then trim the missing values. We pad trim with a 10 pixel margin.

julia
mask_trim(climate, poly) = trim(mask(climate; with=poly); pad=10)
+
+denmark = mask_trim(climate, denmark_border)
+norway = mask_trim(climate, norway_border)
+sweden = mask_trim(climate, sweden_border)
╭────────────────────╮
+│ 98×102 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(9.499999999999972, 25.666666666666643, 98) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(70.5, 53.66666666666667, 102) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 98×102
+  :tmax eltype: Float32 dims: X, Y size: 98×102
+  :prec eltype: Int16 dims: X, Y size: 98×102
+  :wind eltype: Float32 dims: X, Y size: 98×102
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (9.499999999999972, 25.83333333333331), Y = (53.66666666666667, 70.66666666666667))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plotting with Plots.jl

First define a function to add borders to all subplots.

julia
function borders!(p, poly)
+    for i in 1:length(p)
+        Plots.plot!(p, poly; subplot=i, fillalpha=0, linewidth=0.6)
+    end
+    return p
+end
borders! (generic function with 1 method)

Now we can plot the individual countries.

julia
dp = plot(denmark)
+borders!(dp, denmark_border)

and sweden

julia
sp = plot(sweden)
+borders!(sp, sweden_border)

and norway

julia
np = plot(norway)
+borders!(np, norway_border)

The Norway shape includes a lot of islands. Lets crop them out using .. intervals:

julia
norway_region = climate[X(0..40), Y(55..73)]
+plot(norway_region)

And mask it with the border again:

julia
norway = mask_trim(norway_region, norway_border)
+np = plot(norway)
+borders!(np, norway_border)

Now we can combine the countries into a single raster using mosaic. first will take the first value if/when there is an overlap.

julia
scandinavia = mosaic(first, denmark, norway, sweden)
╭─────────────────────╮
+│ 177×119 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} 3.1666666666666443:0.16666666666666666:32.49999999999998 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} 72.66666666666666:-0.16666666666666666:52.99999999999999 ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 177×119
+  :tmax eltype: Float32 dims: X, Y size: 177×119
+  :prec eltype: Int16 dims: X, Y size: 177×119
+  :wind eltype: Float32 dims: X, Y size: 177×119
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (3.1666666666666443, 32.66666666666664), Y = (52.99999999999999, 72.83333333333333))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

And plot scandinavia, with all borders included:

julia
p = plot(scandinavia)
+borders!(p, denmark_border)
+borders!(p, norway_border)
+borders!(p, sweden_border)
+p

And save to netcdf - a single multi-layered file, and tif, which will write a file for each stack layer.

julia
write("scandinavia.nc", scandinavia)
+write("scandinavia.tif", scandinavia)
(tmin = "scandinavia_tmin.tif", tmax = "scandinavia_tmax.tif", prec = "scandinavia_prec.tif", wind = "scandinavia_wind.tif")

Rasters.jl provides a range of other methods that are being added to over time. Where applicable these methods read and write lazily to and from disk-based arrays of common raster file types. These methods also work for entire RasterStacks and RasterSeries using the same syntax.

`,78)]))}const f=a(y,[["render",m]]);export{D as __pageData,f as default}; diff --git a/previews/PR807/assets/qeatmhs.BsE3Kr89.png b/previews/PR807/assets/qeatmhs.BsE3Kr89.png new file mode 100644 index 00000000..6c08a5e7 Binary files /dev/null and b/previews/PR807/assets/qeatmhs.BsE3Kr89.png differ diff --git a/previews/PR807/assets/resample_example_after.C_gavhhT.png b/previews/PR807/assets/resample_example_after.C_gavhhT.png new file mode 100644 index 00000000..d2bc6d68 Binary files /dev/null and b/previews/PR807/assets/resample_example_after.C_gavhhT.png differ diff --git a/previews/PR807/assets/rplot.CwrU8Sen.mp4 b/previews/PR807/assets/rplot.CwrU8Sen.mp4 new file mode 100644 index 00000000..ce1552d4 Binary files /dev/null and b/previews/PR807/assets/rplot.CwrU8Sen.mp4 differ diff --git a/previews/PR807/assets/ryavibo.H6rBHY04.png b/previews/PR807/assets/ryavibo.H6rBHY04.png new file mode 100644 index 00000000..d42cc77c Binary files /dev/null and b/previews/PR807/assets/ryavibo.H6rBHY04.png differ diff --git a/previews/PR807/assets/spxvigw.D9tQTCLW.png b/previews/PR807/assets/spxvigw.D9tQTCLW.png new file mode 100644 index 00000000..10e37aad Binary files /dev/null and b/previews/PR807/assets/spxvigw.D9tQTCLW.png differ diff --git a/previews/PR807/assets/style.qEgyZbUA.css b/previews/PR807/assets/style.qEgyZbUA.css new file mode 100644 index 00000000..40bfc51d --- /dev/null +++ b/previews/PR807/assets/style.qEgyZbUA.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic";@import"https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic";@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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(/Rasters.jl/previews/PR807/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-906d7fb4]{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-906d7fb4]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-906d7fb4]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-906d7fb4]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-906d7fb4]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-906d7fb4]: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-906d7fb4]: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-906d7fb4]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-906d7fb4]: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-906d7fb4]: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-906d7fb4]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-906d7fb4]: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-906d7fb4]: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-acbfed09]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-acbfed09]{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-acbfed09]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-acbfed09]{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-04f5c5e9]{position:relative}.VPFlyout[data-v-04f5c5e9]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-04f5c5e9]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-04f5c5e9]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-04f5c5e9]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-04f5c5e9]{color:var(--vp-c-brand-2)}.button[aria-expanded=false]+.menu[data-v-04f5c5e9]{opacity:0;visibility:hidden;transform:translateY(0)}.VPFlyout:hover .menu[data-v-04f5c5e9],.button[aria-expanded=true]+.menu[data-v-04f5c5e9]{opacity:1;visibility:visible;transform:translateY(0)}.button[data-v-04f5c5e9]{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-04f5c5e9]{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-04f5c5e9]{margin-right:0;font-size:16px}.text-icon[data-v-04f5c5e9]{margin-left:4px;font-size:14px}.icon[data-v-04f5c5e9]{font-size:20px;transition:fill .25s}.menu[data-v-04f5c5e9]{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-956ec74c]{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-956ec74c],.VPNavBarMenuLink[data-v-956ec74c]: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.2 | 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-735512b8]{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-735512b8]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-372ae7c0]{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-372ae7c0]: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}: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}: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: "Space Mono", Menlo, Monaco, Consolas, "Courier New", monospace}.mono{font-feature-settings:"calt" 0}:root{--c-yellow-1: #ffd859;--c-yellow-2: #f7d336;--c-yellow-3: #dec96e;--c-yellow-soft-1: #ecb732;--c-yellow-soft-2: #c99513;--c-teal: #086367;--c-teal-light: #33898d;--c-white-dark: #f8f8f8;--c-black-darker: #0d121b;--c-black: #111827;--c-black-light: #161f32;--c-black-lighter: #262a44;--c-green-1: #52ce63;--c-green-2: #8ae99c;--c-green-3: #51a256;--c-green-soft: #316334;--vp-c-brand-1: var(--vp-c-green-1);--vp-c-brand-2: var(--vp-c-green-2);--vp-c-brand-3: var(--vp-c-green-3);--vp-c-brand-soft: var(--vp-c-green-soft);--c-text-dark-1: #d9e6eb;--c-text-dark-2: #c4dde6;--c-text-dark-3: #abc4cc;--c-text-light-1: #2c3e50;--c-text-light-2: #476582;--c-text-light-3: #90a4b7;--vp-c-brand-dark: var(--c-green-soft);--vp-c-brand-darker: var(--c-green-soft);--vp-c-brand-dimm: rgba(100, 108, 255, .08);--vp-c-brand-text: var(--c-text-light-1);--c-bg-accent: var(--c-white-dark);--code-bg-color: var(--c-white-dark);--code-inline-bg-color: var(--c-white-dark);--code-font-family: "dm", source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;--code-font-size: 16px;--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-line-highlight-color: rgba(0, 0, 0, .075);--vp-code-color: var(--vp-text-color)}html.dark:root{--vp-c-brand-1: var(--c-yellow-1);--vp-c-brand-2: var(--c-yellow-2);--vp-c-brand-3: var(--c-yellow-3);--vp-c-bg-alpha-with-backdrop: rgba(20, 25, 36, .7);--vp-c-bg-alpha-without-backdrop: rgba(20, 25, 36, .9);--vp-code-line-highlight-color: rgba(0, 0, 0, .5);--vp-c-text-1: var(--c-text-dark-1);--vp-c-brand-text: var(--c-text-light-1);--c-text-light: var(--c-text-dark-2);--c-text-lighter: var(--c-text-dark-3);--c-divider: var(--c-divider-dark);--c-bg-accent: var(--c-black-light);--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: #0d121b;--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-home-hero-name-background: -webkit-linear-gradient( 78deg, var(--c-yellow-2) 30%, var(--c-green-3) )}html.dark .DocSearch{--docsearch-hit-active-color: var(--c-text-light-1)}:root{--vp-button-brand-border: var(--c-yellow-soft-1);--vp-button-brand-text: var(--c-black);--vp-button-brand-bg: var(--c-yellow-1);--vp-button-brand-hover-border: var(--c-yellow-2);--vp-button-brand-hover-text: var(--c-black-darker);--vp-button-brand-hover-bg: var(--c-yellow-2);--vp-button-brand-active-border: var(--c-yellow-soft-1);--vp-button-brand-active-text: var(--c-black-darker);--vp-button-brand-active-bg: var(--vp-button-brand-bg)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: linear-gradient( 292deg, var(--c-text-light-2) 50%, var(--c-green-2) );--vp-home-hero-image-filter: blur(40px)}.VPHero .VPImage.image-src{max-height:192px}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}.VPHero .VPImage.image-src{max-height:256px}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(72px)}.VPHero .VPImage.image-src{max-height:320px}}.become-sponsor{font-size:.9em;font-weight:700;width:auto;text-align:center;background-color:transparent;padding:.75em 2em;border-radius:2em;transition:all .15s ease;box-sizing:border-box;border:2px solid var(--c-yellow-2)}.become-sponsor:hover{background-color:var(--c-yellow-1);text-decoration:none;border-color:var(--c-yellow-1);color:var(--c-text-light-1)}.vp-doc a{text-decoration:none}.vp-doc a:hover{text-decoration:underline}.sponsors-top .become-sponsor{font-size:.75em;padding:.2em;width:auto;max-width:150px}kbd{display:inline-block;padding:3px 5px;font-size:.65em;color:var(--vp-c-text-1);vertical-align:middle;background-color:var(--vp-c-bg-mute);border:solid 1px var(--vp-c-bg-soft-mute);border-radius:6px;box-shadow:inset 0 -1px 0 var(--vp-c-bg-soft-mute);line-height:.95em}.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}}.jldocstring.custom-block{border:1px solid var(--vp-c-gray-2);color:var(--vp-c-text-1)}.jldocstring.custom-block summary{font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none;margin:0 0 8px}.VPLocalSearchBox[data-v-1783de97]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-1783de97]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-1783de97]{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-1783de97]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-1783de97]{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-1783de97]{padding:0 8px}}.search-bar[data-v-1783de97]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-1783de97]{display:block;font-size:18px}.navigate-icon[data-v-1783de97]{display:block;font-size:14px}.search-icon[data-v-1783de97]{margin:8px}@media (max-width: 767px){.search-icon[data-v-1783de97]{display:none}}.search-input[data-v-1783de97]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-1783de97]{padding:6px 4px}}.search-actions[data-v-1783de97]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-1783de97]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-1783de97]{display:none}}.search-actions button[data-v-1783de97]{padding:8px}.search-actions button[data-v-1783de97]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-1783de97]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-1783de97]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-1783de97]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-1783de97]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-1783de97]{display:none}}.search-keyboard-shortcuts kbd[data-v-1783de97]{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-1783de97]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-1783de97]{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-1783de97]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-1783de97]{margin:8px}}.titles[data-v-1783de97]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-1783de97]{display:flex;align-items:center;gap:4px}.title.main[data-v-1783de97]{font-weight:500}.title-icon[data-v-1783de97]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-1783de97]{opacity:.5}.result.selected[data-v-1783de97]{--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-1783de97]{position:relative}.excerpt[data-v-1783de97]{opacity:50%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;margin-top:4px}.result.selected .excerpt[data-v-1783de97]{opacity:1}.excerpt[data-v-1783de97] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-1783de97] mark,.excerpt[data-v-1783de97] 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-1783de97] .vp-code-group .tabs{display:none}.excerpt[data-v-1783de97] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-1783de97]{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-1783de97]{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-1783de97],.result.selected .title-icon[data-v-1783de97]{color:var(--vp-c-brand-1)!important}.no-results[data-v-1783de97]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-1783de97]{flex:none} diff --git a/previews/PR807/assets/swkcnzv.B2QjG_n4.png b/previews/PR807/assets/swkcnzv.B2QjG_n4.png new file mode 100644 index 00000000..5d0f7959 Binary files /dev/null and b/previews/PR807/assets/swkcnzv.B2QjG_n4.png differ diff --git a/previews/PR807/assets/trim_example_after.CsDpPakV.png b/previews/PR807/assets/trim_example_after.CsDpPakV.png new file mode 100644 index 00000000..4d2cfc3b Binary files /dev/null and b/previews/PR807/assets/trim_example_after.CsDpPakV.png differ diff --git a/previews/PR807/assets/trim_example_before.B583SoP8.png b/previews/PR807/assets/trim_example_before.B583SoP8.png new file mode 100644 index 00000000..0dcae76b Binary files /dev/null and b/previews/PR807/assets/trim_example_before.B583SoP8.png differ diff --git a/previews/PR807/assets/uedqoev.CUldC_pQ.png b/previews/PR807/assets/uedqoev.CUldC_pQ.png new file mode 100644 index 00000000..2b55a24f Binary files /dev/null and b/previews/PR807/assets/uedqoev.CUldC_pQ.png differ diff --git a/previews/PR807/assets/vjnjunt.DojgcnZi.png b/previews/PR807/assets/vjnjunt.DojgcnZi.png new file mode 100644 index 00000000..d4e41605 Binary files /dev/null and b/previews/PR807/assets/vjnjunt.DojgcnZi.png differ diff --git a/previews/PR807/assets/vxnkhbp.Dw_eTAB7.png b/previews/PR807/assets/vxnkhbp.Dw_eTAB7.png new file mode 100644 index 00000000..ac804e89 Binary files /dev/null and b/previews/PR807/assets/vxnkhbp.Dw_eTAB7.png differ diff --git a/previews/PR807/assets/warp_example_after.rgHHAHxc.png b/previews/PR807/assets/warp_example_after.rgHHAHxc.png new file mode 100644 index 00000000..aaf21485 Binary files /dev/null and b/previews/PR807/assets/warp_example_after.rgHHAHxc.png differ diff --git a/previews/PR807/assets/warp_example_before.DrW8As6m.png b/previews/PR807/assets/warp_example_before.DrW8As6m.png new file mode 100644 index 00000000..af493262 Binary files /dev/null and b/previews/PR807/assets/warp_example_before.DrW8As6m.png differ diff --git a/previews/PR807/assets/xqojlxo.Djo3H46f.png b/previews/PR807/assets/xqojlxo.Djo3H46f.png new file mode 100644 index 00000000..8014c407 Binary files /dev/null and b/previews/PR807/assets/xqojlxo.Djo3H46f.png differ diff --git a/previews/PR807/data_sources.html b/previews/PR807/data_sources.html new file mode 100644 index 00000000..73bdcdc6 --- /dev/null +++ b/previews/PR807/data_sources.html @@ -0,0 +1,28 @@ + + + + + + Data sources | Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Data sources

Rasters.jl uses a number of backends to load raster data. Raster, RasterStack and RasterSeries will detect which backend to use for you, automatically.

GRD

R GRD files can be loaded natively, using Julias MMap - which means they are very fast, but are not compressed. They are always 3 dimensional, and have Y, X and Band dimensions.

NetCDF

NetCDF .nc files are loaded using NCDatasets.jl. Layers from files can be loaded as Raster("filename.nc"; name=:layername). Without name the first layer is used. RasterStack("filename.nc") will use all netcdf variables in the file that are not dimensions as layers.

NetCDF layers can have arbitrary dimensions. Known, common dimension names are converted to X, Y Z, and Ti, otherwise Dim{:layername} is used. Layers in the same file may also have different dimensions.

NetCDF files still have issues loading directly from disk for some operations. Using read(ncstack) may help.

GDAL

All files GDAL can access, such as .tiff and .asc files, can be loaded, using ArchGDAL.jl. These are generally best loaded as Raster("filename.tif"), but can be loaded as RasterStack("filename.tif"; layersfrom=Band), taking layers from the Band dimension, which is also the default.

SMAP

The Soil Moisture Active-Passive dataset provides global layers of soil moisture, temperature and other related data, in a custom HDF5 format. Layers are always 2 dimensional, with Y and X dimensions.

These can be loaded as multi-layered RasterStack("filename.h5"). Individual layers can be loaded as Raster("filename.h5"; name=:layername), without name the first layer is used.

julia
using Rasters

Missing docstring.

Missing docstring for smapseries. Check Documenter's build log for details.

Writing file formats to disk

Files can be written to disk in all formats other than SMAP HDF5 using write("filename.ext", A). See the docs for write. They can (with some caveats) be written to different formats than they were loaded in as, providing file-type conversion for spatial data.

Some metadata may be lost in formats that store little metadata, or where metadata conversion has not been completely implemented.

RasterDataSources.jl integration

RasterDataSources.jl standardises the download of common raster data sources, with a focus on datasets used in ecology and the environmental sciences. RasterDataSources.jl is tightly integrated into Rasters.jl, so that datsets and keywords can be used directly to download and load data as a Raster, RasterStack, or RasterSeries.

julia
using Rasters, CairoMakie, Dates
+using RasterDataSources
+A = Raster(WorldClim{Climate}, :tavg; month=June)
+Makie.plot(A)

See the docs for Raster, RasterStack and RasterSeries, and the docs for RasterDataSources.getraster for syntax to specify various data sources.

+ + + + \ No newline at end of file diff --git a/previews/PR807/gbif_wflow.html b/previews/PR807/gbif_wflow.html new file mode 100644 index 00000000..a12a399e --- /dev/null +++ b/previews/PR807/gbif_wflow.html @@ -0,0 +1,91 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Load occurrences for the Mountain Pygmy Possum using GBIF.jl

Load GBIF

julia
using Rasters, GBIF2
+using RasterDataSources
+const RS = Rasters
Rasters
julia
records = GBIF2.occurrence_search("Burramys parvus"; limit=300)
300-element GBIF2.Table{GBIF2.Occurrence, JSON3.Array{JSON3.Object, Vector{UInt8}, SubArray{UInt64, 1, Vector{UInt64}, Tuple{UnitRange{Int64}}, true}}}┌──────────────────────────┬─────────┬─────────┬─────────┬──────────┬───────────
+│                 geometry │    year │   month │     day │  kingdom │   phylum ⋯
+│ Tuple{Float64, Float64}? │  Int64? │  Int64? │  Int64? │  String? │  String? ⋯
+├──────────────────────────┼─────────┼─────────┼─────────┼──────────┼───────────
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │    2021 │       1 │       6 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.391, -36.3036) │    2015 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.333, -36.4333) │    2011 │      11 │      21 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.396, -36.3818) │    2016 │      11 │      15 │ Animalia │ Chordata ⋯
+│      (148.347, -36.5047) │    2012 │      11 │      22 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (147.096, -36.9357) │    2020 │       2 │      10 │ Animalia │ Chordata ⋯
+│      (148.329, -36.4317) │    2016 │       1 │       3 │ Animalia │ Chordata ⋯
+│      (148.241, -36.4001) │    2011 │      11 │      18 │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│                  missing │ missing │ missing │ missing │ Animalia │ Chordata ⋯
+│      (148.236, -36.5249) │    2012 │      11 │      23 │ Animalia │ Chordata ⋯
+│            ⋮             │    ⋮    │    ⋮    │    ⋮    │    ⋮     │    ⋮     ⋱
+└──────────────────────────┴─────────┴─────────┴─────────┴──────────┴───────────
+                                                 78 columns and 285 rows omitted

Extract coordinates

Extract the longitude/latitude value to a Vector of points (a Tuple counts as a (x, y) point in GeoInterface.jl):

julia
coords = [(r.decimalLongitude, r.decimalLatitude) for r in records if !ismissing(r.decimalLatitude)]
256-element Vector{Tuple{Float64, Float64}}:
+ (148.391097, -36.30362)
+ (148.332969, -36.433349)
+ (148.396453, -36.381847)
+ (148.347186, -36.504673)
+ (147.096394, -36.935687)
+ (148.328896, -36.431684)
+ (148.240881, -36.400058)
+ (148.235596, -36.524924)
+ (148.338776, -36.430986)
+ (147.1, -37.0)
+
+ (148.391682, -36.373215)
+ (148.394749, -36.284565)
+ (148.333783, -36.432552)
+ (148.333783, -36.432552)
+ (148.377673, -36.418261)
+ (148.328025, -36.437709)
+ (148.398438, -36.382602)
+ (148.310064, -36.448374)
+ (148.259489, -36.490719)

Get layer / Band

Get BioClim layers and subset to south-east Australia

julia
A = RasterStack(WorldClim{BioClim}, (1, 3, 7, 12))
+se_aus = A[X(138 .. 155), Y(-40 .. -25), RS.Band(1)]
╭────────────────────╮
+│ 102×89 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(138.0, 154.83333333333331, 102) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-25.16666666666667, -39.83333333333333, 89) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :bio1  eltype: Float32 dims: X, Y size: 102×89
+  :bio3  eltype: Float32 dims: X, Y size: 102×89
+  :bio7  eltype: Float32 dims: X, Y size: 102×89
+  :bio12 eltype: Float32 dims: X, Y size: 102×89
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (138.0, 154.99999999999997), Y = (-39.83333333333333, -25.000000000000004))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plot BioClim predictors and scatter occurrence points on all subplots

julia
using Plots
+p = plot(se_aus);
+kw = (legend=:none, opacity=0.5, markershape=:cross, markercolor=:black)
+foreach(i -> scatter!(p, coords; subplot=i, kw...), 1:4)
+p

Then extract predictor variables and write to CSV.

julia
using CSV
+predictors = collect(extract(se_aus, coords))
+CSV.write("burramys_parvus_predictors.csv", predictors)
"burramys_parvus_predictors.csv"

Or convert them to a DataFrame:

julia
using DataFrames
+df = DataFrame(predictors)
+df[1:5,:]
+ + + + \ No newline at end of file diff --git a/previews/PR807/get_started.html b/previews/PR807/get_started.html new file mode 100644 index 00000000..dcf5eb4b --- /dev/null +++ b/previews/PR807/get_started.html @@ -0,0 +1,119 @@ + + + + + + Quick start | Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Quick start

Install the package by typing:

julia
] 
+add Rasters

then do

julia
using Rasters

Using Rasters to read GeoTiff or NetCDF files will output something similar to the following toy examples. This is possible because Rasters.jl extends DimensionalData.jl so that spatial data can be indexed using named dimensions like X, Y and Ti (time) and e.g. spatial coordinates.

julia
using Rasters, Dates
+
+lon, lat = X(25:1:30), Y(25:1:30)
+ti = Ti(DateTime(2001):Month(1):DateTime(2002))
+ras = Raster(rand(lon, lat, ti)) # this generates random numbers with the dimensions given
╭──────────────────────────╮
+│ 6×6×13 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2002-01-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2002-01-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Getting the lookup array from dimensions

julia
lon = lookup(ras, X) # if X is longitude
+lat = lookup(ras, Y) # if Y is latitude
Sampled{Int64} ForwardOrdered Regular Points
+wrapping: 25:1:30

Select by index

Selecting a time slice by index is done via

julia
ras[Ti(1)]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

also

julia
ras[Ti=1]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

or and interval of indices using the syntax =a:b or (a:b)

julia
ras[Ti(1:10)]
╭──────────────────────────╮
+│ 6×6×10 Raster{Float64,3} │
+├──────────────────────────┴───────────────────────────────────────────── dims ┐
+  ↓ X  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y  Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  ↗ Ti Sampled{DateTime} DateTime("2001-01-01T00:00:00"):Month(1):DateTime("2001-10-01T00:00:00") ForwardOrdered Regular Points
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30), Ti = (DateTime("2001-01-01T00:00:00"), DateTime("2001-10-01T00:00:00")))
+
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

Select by value

julia
ras[Ti=At(DateTime(2001))]
╭───────────────────────╮
+│ 6×6 Raster{Float64,2} │
+├───────────────────────┴───────────────────────────── dims ┐
+  ↓ X Sampled{Int64} 25:1:30 ForwardOrdered Regular Points,
+  → Y Sampled{Int64} 25:1:30 ForwardOrdered Regular Points
+├─────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (25, 30), Y = (25, 30))
+
+└───────────────────────────────────────────────────────────┘
+  ↓ →  25         26          27         28          29         30
+ 25     0.96572    0.924799    0.179414   0.791698    0.109752   0.697933
+ 26     0.13084    0.348444    0.219342   0.324747    0.756557   0.0351028
+ 27     0.909224   0.588274    0.492677   0.0619296   0.37036    0.220698
+ 28     0.207309   0.311813    0.534878   0.305028    0.853306   0.624422
+ 29     0.934186   0.755033    0.516819   0.185905    0.453071   0.533883
+ 30     0.329765   0.0840219   0.957178   0.923752    0.145538   0.75708

More options are available, like Near, Contains and Where.

Dimensions

Rasters uses X, Y, and Z dimensions from DimensionalData to represent spatial directions like longitude, latitude and the vertical dimension, and subset data with them. Ti is used for time, and Band represent bands. Other dimensions can have arbitrary names, but will be treated generically. See DimensionalData for more details on how they work.

Lookup Arrays

These specify properties of the index associated with e.g. the X and Y dimension. Rasters.jl defines additional lookup arrays: Projected to handle dimensions with projections, and Mapped where the projection is mapped to another projection like EPSG(4326). Mapped is largely designed to handle NetCDF dimensions, especially with Explicit spans.

Subsetting an object

Regular getindex (e.g. A[1:100, :]) and view work on all objects just as with an Array. view is always lazy, and reads from disk are deferred until getindex is used. DimensionalData.jl Dimensions and Selectors are the other way to subset an object, making use of the objects index to find values at e.g. certain X/Y coordinates. The available selectors are listed here:

SelectorsDescription
At(x)get the index exactly matching the passed in value(s).
Near(x)get the closest index to the passed in value(s).
Where(f::Function)filter the array axis by a function of the dimension index values.
a..b/Between(a, b)get all indices between two values, excluding the high value.
Contains(x)get indices where the value x falls within an interval.

Info

  • Use the .. selector to take a view of madagascar:
julia
using Rasters, RasterDataSources
+const RS = Rasters
+using CairoMakie
+CairoMakie.activate!()
+
+A = Raster(WorldClim{BioClim}, 5)
+madagascar = view(A, X(43.25 .. 50.48), Y(-25.61 .. -12.04))
+# Note the space between .. -12
+Makie.plot(madagascar)

+ + + + \ No newline at end of file diff --git a/previews/PR807/hashmap.json b/previews/PR807/hashmap.json new file mode 100644 index 00000000..cd80ee2c --- /dev/null +++ b/previews/PR807/hashmap.json @@ -0,0 +1 @@ +{"api.md":"OKz0SH8-","array_operations.md":"CRu0fcQR","data_sources.md":"Dcl5DOui","gbif_wflow.md":"B-xemxXG","get_started.md":"CRLYYECF","index.md":"CYSmGW74","methods.md":"tEJSj4eC","plot_makie.md":"DYZzsleT","plotting.md":"n1eGQxVQ"} diff --git a/previews/PR807/index.html b/previews/PR807/index.html new file mode 100644 index 00000000..2ce2c359 --- /dev/null +++ b/previews/PR807/index.html @@ -0,0 +1,25 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Rasters.jl

Manipulating rasterized spatial data

Rasters

Data-source abstraction

Rasters provides a standardised interface that allows many source data types to be used with identical syntax.

  • Scripts and packages building on Rasters.jl can treat Raster, RasterStack, and RasterSeries as black boxes.

  • The data could hold GeoTiff or NetCDF files, Arrays in memory or CuArrays on the GPU - they will all behave in the same way.

  • RasterStack can be backed by a Netcdf or HDF5 file, or a NamedTuple of Raster holding .tif files, or all Raster in memory.

  • Users do not have to deal with the specifics of spatial file types.

  • Projected lookups with Cylindrical projections can by indexed using other Cylindrical projections by setting the mappedcrs keyword on construction. You don't need to know the underlying projection, the conversion is handled automatically. This means lat/lon EPSG(4326) can be used seamlessly if you need that.

Installation

julia
] add Rasters

Packages extensions

Packages extensions and Rasters 0.8 and onwards

On Julia 1.9 we can put additional packages in extensions, so the code only loads when you load a specific package. Rasters.jl was always intended to work like this, and its finally possible. This reduced package using time from many seconds to well under a second.

But, it means you have to manually load packages you need for each backend or additional functionality.

For example, to use the GDAL backend, and download files, you now need to do:

julia
using Rasters, ArchGDAL, RasterDataSources

where previously it was just using Rasters.

Sources and packages needed:

  • :gdal: using ArchGDAL

  • :netcdf: using NCDatasets

  • :grd: built-in.

  • :smap: using HDF5

  • :grib: not yet finished.

Other functionality in extensions:

  • Raster data downloads, like Worldclim{Climate}: using RasterDataSources

  • Makie plots: using Makie

  • Coordinate transformations for gdal rasters: using CoordinateTransformations

Bugs and errors

Bugs, errors and making issues for Rasters.jl

Raster data is complicated and there are many places for subtle or not-so-subtle bugs to creep in.

We need bug reports to reduce how often they occur over time. But also, we need issues that are easy to reproduce or it isn't practically possible to fix them.

Because there are so many raster file types and variations of them, most of the time we need the exact file that caused your problem to know how to fix it, and be sure that we have actually fixed it when we are done. So fixing a Rasters.jl bug nearly always involves downloading some file and running some code that breaks with it (if you can trigger the bug without a file, that's great! but its not always possible).

To make an issue we can fix quickly (or at all) there are three key steps:

  1. Include the file in an accessible place on web without authentication or any other work on our part, so we can just get it and find your bug. You can put it on a file hosting platform (e.g. google drive, drop box, whatever you use) and share the url.

  2. Add a minimum working example to the issue template that first downloads the file, then runs the function that triggers the bug.

  3. Paste the complete stack trace of the error it produces, right to the bottom, into the issue template. Then we can be sure we reproduced the same problem.

Good issues are really appreciated, but they do take just a little extra effort with Rasters.jl because of this need for files.

+ + + + \ No newline at end of file diff --git a/previews/PR807/logo.png b/previews/PR807/logo.png new file mode 100644 index 00000000..4b53fffb Binary files /dev/null and b/previews/PR807/logo.png differ diff --git a/previews/PR807/methods.html b/previews/PR807/methods.html new file mode 100644 index 00000000..9fab7f85 --- /dev/null +++ b/previews/PR807/methods.html @@ -0,0 +1,25 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Methods that change the resolution or extent of an object

Click through to the function documentation for more in-depth descriptions and examples.

MethodsDescription
aggregateaggregate data by the same or different amounts for each axis.
disaggregatesimilarly disaggregate data.
mosaicjoin rasters covering different extents into a single array or file.
cropshrink objects to specific dimension sizes or the extent of another object.
extendextend objects to specific dimension sizes or the extent of another object.
trimtrims areas of missing values for arrays and across stack layers.
resampleresample data to a different size and projection, or snap to another object.
warpuse gdalwarp on any object, e.g. a multidimensional NetCDF stack.

Methods that change an objects values

Info

Note that most regular Julia methods, such as replace, work as for a standard Array. These additional methods are commonly required in GIS applications.

MethodsDescription
classifyclassify values into categories.
maskmask an object by a polygon or Raster along X/Y, or other dimensions.
replace_missingreplace all missing values in an object and update missingval.

Point, polygon and table operation

MethodsDescription
rasterizerasterize points and geometries.
extractextract values from points or geometries.
zonalcalculate zonal statistics for an object masked by geometries.

Methods to load, write and modify data sources

MethodsDescription
modifyreplace the data in objects. Useful to e.g. move objects to/from a GPU.
readread data to memory if it is on disk.
read!read data to predefined memory.
openopen the underlying data for manually reading or writing.
writewrite objects to file.
+ + + + \ No newline at end of file diff --git a/previews/PR807/plot_makie.html b/previews/PR807/plot_makie.html new file mode 100644 index 00000000..7647820e --- /dev/null +++ b/previews/PR807/plot_makie.html @@ -0,0 +1,102 @@ + + + + + + reset theme | Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Plotting in Makie

Plotting in Makie works somewhat differently than Plots, since the recipe system is different. You can pass a 2-D raster to any surface-like function (heatmap, contour, contourf, or even surface for a 3D plot) with ease.

2-D rasters in Makie

julia
using CairoMakie, Makie
+using Rasters, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5) # this is a 3D raster, so is not accepted.
╭──────────────────────────────────╮
+│ 2160×1080 Raster{Float32,2} bio5 │
+├──────────────────────────────────┴───────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
+  "units"    => ""
+  "offset"   => 0.0
+  "filepath" => "./WorldClim/BioClim/wc2.1_10m_bio_5.tif"
+  "scale"    => 1.0
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: -3.4f38
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘
+    ↓ →    89.8333  89.6667  89.5     89.3333  …  -89.6667  -89.8333  -90.0
+ -180.0    -3.4f38  -3.4f38  -3.4f38  -3.4f38     -15.399   -13.805   -14.046
+    ⋮                                          ⋱                        ⋮
+  179.833  -3.4f38  -3.4f38  -3.4f38  -3.4f38  …  -17.1478  -15.4243  -15.701
julia
fig, ax, _ = plot(A)
+contour(fig[1, 2], A)
+ax = Axis(fig[2, 1]; aspect = DataAspect())
+contourf!(ax, A)
+surface(fig[2, 2], A) # even a 3D plot work!
+fig

3-D rasters in Makie

Warning

This interface is experimental, and unexported for that reason. It may break at any time!

Just as in Plots, 3D rasters are treated as a series of 2D rasters, which are tiled and plotted.

You can use Rasters.rplot to visualize 3D rasters or RasterStacks in this way. An example is below:

julia
stack = RasterStack(WorldClim{Climate}; month = 1)
+Rasters.rplot(stack; Axis = (aspect = DataAspect(),),)

You can pass any theming keywords in, which are interpreted by Makie appropriately.

The plots seem a little squished here. We provide a Makie theme which makes text a little smaller and has some other space-efficient attributes:

julia
Makie.set_theme!(Rasters.theme_rasters())
+Rasters.rplot(stack)

reset theme

julia
Makie.set_theme!()

Plotting with Observables, animations

Rasters.rplot should support Observable input out of the box, but the dimensions of that input must remain the same - i.e., the element names of a RasterStack must remain the same.

julia
Makie.set_theme!(Rasters.theme_rasters())
+# `stack` is the WorldClim climate data for January
+stack_obs = Observable(stack)
+fig = Rasters.rplot(stack_obs;
+    Colorbar=(; height=Relative(0.75), width=5)
+)
+record(fig, "rplot.mp4", 1:12; framerate = 3) do i
+    stack_obs[] = RasterStack(WorldClim{Climate}; month = i)
+end
"rplot.mp4"

julia
Makie.set_theme!() # reset theme
Rasters.rplot Function
julia
Rasters.rplot([position::GridPosition], raster; kw...)

raster may be a Raster (of 2 or 3 dimensions) or a RasterStack whose underlying rasters are 2 dimensional, or 3-dimensional with a singleton (length-1) third dimension.

Keywords

  • plottype = Makie.Heatmap: The type of plot. Can be any Makie plot type which accepts a Raster; in practice, Heatmap, Contour, Contourf and Surface are the best bets.

  • axistype = Makie.Axis: The type of axis. This can be an Axis, Axis3, LScene, or even a GeoAxis from GeoMakie.jl.

  • X = XDim: The X dimension of the raster.

  • Y = YDim: The Y dimension of the raster.

  • Z = YDim: The Y dimension of the raster.

  • draw_colorbar = true: Whether to draw a colorbar for the axis or not.

  • colorbar_position = Makie.Right(): Indicates which side of the axis the colorbar should be placed on. Can be Makie.Top(), Makie.Bottom(), Makie.Left(), or Makie.Right().

  • colorbar_padding = Makie.automatic: The amount of padding between the colorbar and its axis. If automatic, then this is set to the width of the colorbar.

  • title = Makie.automatic: The titles of each plot. If automatic, these are set to the name of the band.

  • xlabel = Makie.automatic: The x-label for the axis. If automatic, set to the dimension name of the X-dimension of the raster.

  • ylabel = Makie.automatic: The y-label for the axis. If automatic, set to the dimension name of the Y-dimension of the raster.

  • colorbarlabel = "": Usually nothing, but here if you need it. Sets the label on the colorbar.

  • colormap = nothing: The colormap for the heatmap. This can be set to a vector of colormaps (symbols, strings, cgrads) if plotting a 3D raster or RasterStack.

  • colorrange = Makie.automatic: The colormap for the heatmap. This can be set to a vector of (low, high) if plotting a 3D raster or RasterStack.

  • nan_color = :transparent: The color which NaN values should take. Default to transparent.

source

Using vanilla Makie

julia
using Rasters, RasterDataSources

The data

julia
layers = (:evenness, :range, :contrast, :correlation)
+st = RasterStack(EarthEnv{HabitatHeterogeneity}, layers)
+ausbounds = X(100 .. 160), Y(-50 .. -10) # Roughly cut out australia
+aus = st[ausbounds...] |> Rasters.trim
╭─────────────────────╮
+│ 194×161 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(113.33333333333336, 153.54166666666666, 194) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(-10.20833333333334, -43.54166666666667, 161) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :evenness    eltype: UInt16 dims: X, Y size: 194×161
+  :range       eltype: UInt16 dims: X, Y size: 194×161
+  :contrast    eltype: UInt32 dims: X, Y size: 194×161
+  :correlation eltype: UInt16 dims: X, Y size: 194×161
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (113.33333333333336, 153.75), Y = (-43.54166666666667, -10.000000000000005))
+  missingval: (evenness = 0xffff, range = 0xffff, contrast = 0xffffffff, correlation = 0xffff)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

The plot

julia
# colorbar attributes
+colormap = :batlow
+flipaxis = false
+tickalign=1
+width = 13
+ticksize = 13
+# figure
+with_theme(theme_dark()) do
+    fig = Figure(; size=(600, 600), backgroundcolor=:transparent)
+    axs = [Axis(fig[i,j], xlabel = "lon", ylabel = "lat",
+        backgroundcolor=:transparent) for i in 1:2 for j in 1:2]
+    plt = [Makie.heatmap!(axs[i], aus[l]; colormap) for (i, l) in enumerate(layers)]
+    for (i, l) in enumerate(layers) axs[i].title = string(l) end
+    hidexdecorations!.(axs[1:2]; grid=false, ticks=false)
+    hideydecorations!.(axs[[2,4]]; grid=false, ticks=false)
+    Colorbar(fig[1, 0], plt[1]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[1, 3], plt[2]; tickalign, width, ticksize)
+    Colorbar(fig[2, 0], plt[3]; flipaxis, tickalign, width, ticksize)
+    Colorbar(fig[2, 3], plt[4]; tickalign, width, ticksize)
+    colgap!(fig.layout, 5)
+    rowgap!(fig.layout, 5)
+    Label(fig[0, :], "RasterStack of EarthEnv HabitatHeterogeneity layers, trimmed to Australia")
+    fig
+end
+save("aus_trim.png", current_figure());
CairoMakie.Screen{IMAGE}

+ + + + \ No newline at end of file diff --git a/previews/PR807/plotting.html b/previews/PR807/plotting.html new file mode 100644 index 00000000..cb6e5509 --- /dev/null +++ b/previews/PR807/plotting.html @@ -0,0 +1,159 @@ + + + + + + Rasters.jl + + + + + + + + + + + + + + +
Skip to content

Plots, simple

Plots.jl and Makie.jl are fully supported by Rasters.jl, with recipes for plotting Raster and RasterStack provided. plot will plot a heatmap with axes matching dimension values. If mappedcrs is used, converted values will be shown on axes instead of the underlying crs values. contourf will similarly plot a filled contour plot.

Pixel resolution is limited to allow loading very large files quickly. max_res specifies the maximum pixel resolution to show on the longest axis of the array. It can be set manually to change the resolution (e.g. for large or high-quality plots):

julia
using Rasters, RasterDataSources, ArchGDAL, Plots
+A = Raster(WorldClim{BioClim}, 5)
+plot(A; max_res=3000)

For Makie, plot functions in a similar way. plot will only accept two-dimensional rasters. You can invoke contour, contourf, heatmap, surface or any Makie plotting function which supports surface-like data on a 2D raster.

To obtain tiled plots for 3D rasters and RasterStacks, use the function Rasters.rplot([gridposition], raster; kw_args...). This is an unexported function, since we're not sure how the API will change going forward.

Makie, simple

julia
using CairoMakie
+CairoMakie.activate!(px_per_unit = 2)
+using Rasters, CairoMakie, RasterDataSources, ArchGDAL
+A = Raster(WorldClim{BioClim}, 5)
+Makie.plot(A)

Loading data

Our first example simply loads a file from disk and plots it.

This netcdf file only has one layer, if it has more we could use RasterStack instead.

julia
using Rasters, NCDatasets, Plots
+using Downloads: download
+
+url = "https://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc";
+filename = download(url, "tos_O1_2001-2002.nc");
+A = Raster(filename)
╭──────────────────────────────────────────────────╮
+│ 180×170×24 Raster{Union{Missing, Float32},3} tos │
+├──────────────────────────────────────────────────┴───────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} [DateTime360Day(2001-01-16T00:00:00), …, DateTime360Day(2002-12-16T00:00:00)] ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Objects with Dimensions other than X and Y will produce multi-pane plots. Here we plot every third month in the first year in one plot:

julia
A[Ti=1:3:12] |> plot

Now plot the ocean temperatures around the Americas in the first month of 2001. Notice we are using lat/lon coordinates and date/time instead of regular indices. The time dimension uses DateTime360Day, so we need to load CFTime.jl to index it with Near.

julia
using CFTime
+A[Ti(Near(DateTime360Day(2001, 01, 17))), Y(-60.0 .. 90.0), X(45.0 .. 190.0)] |> plot

Now get the mean over the timespan, then save it to disk, and plot it as a filled contour.

Other plot functions and sliced objects that have only one X/Y/Z dimension fall back to generic DimensionalData.jl plotting, which will still correctly label plot axes.

julia
using Statistics
+# Take the mean
+mean_tos = mean(A; dims=Ti)
╭─────────────────────────────────────────────────╮
+│ 180×170×1 Raster{Union{Missing, Float32},3} tos │
+├─────────────────────────────────────────────────┴────────────────────── dims ┐
+  ↓ X  Mapped{Float64} [1.0, 3.0, …, 357.0, 359.0] ForwardOrdered Regular Intervals{Center},
+  → Y  Mapped{Float64} [-79.5, -78.5, …, 88.5, 89.5] ForwardOrdered Regular Intervals{Center},
+  ↗ Ti Sampled{DateTime360Day} DateTime360Day(2002-01-16T00:00:00):Millisecond(2592000000):DateTime360Day(2002-01-16T00:00:00) ForwardOrdered Explicit Intervals{Center}
+├──────────────────────────────────────────────────────────────────── metadata ┤
+  Metadata{Rasters.NCDsource} of Dict{String, Any} with 9 entries:
+  "units"          => "K"
+  "missing_value"  => 1.0f20
+  "original_units" => "degC"
+  "cell_methods"   => "time: mean (interval: 30 minutes)"
+  "history"        => " At   16:37:23 on 01/11/2005: CMOR altered the data in t…
+  "long_name"      => "Sea Surface Temperature"
+  "standard_name"  => "sea_surface_temperature"
+  "_FillValue"     => 1.0f20
+  "original_name"  => "sosstsst"
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (0.0, 360.0), Y = (-80.0, 90.0), Ti = (DateTime360Day(2001-01-01T00:00:00), DateTime360Day(2003-01-01T00:00:00)))
+  missingval: missing
+  crs: EPSG:4326
+  mappedcrs: EPSG:4326
+└──────────────────────────────────────────────────────────────────────────────┘
+[:, :, 1]
+ ⋮      ⋱

Plot a contour plot

julia
using Plots
+Plots.contourf(mean_tos; dpi=300, size=(800, 400))

write to disk

Write the mean values to disk

julia
write("mean_tos.nc", mean_tos)
"mean_tos.nc"

Plotting recipes in DimensionalData.jl are the fallback for Rasters.jl when the object doesn't have 2 X/Y/Z dimensions, or a non-spatial plot command is used. So (as a random example) we could plot a transect of ocean surface temperature at 20 degree latitude :

julia
A[Y(Near(20.0)), Ti(1)] |> plot

Polygon masking, mosaic and plot

In this example we will mask the Scandinavian countries with border polygons, then mosaic together to make a single plot.

First, get the country boundary shape files using GADM.jl.

using Rasters, RasterDataSources, ArchGDAL, Shapefile, Plots, Dates, Downloads, NCDatasets

Download the shapefile

julia
using Downloads
+using Shapefile
+shapefile_url = "https://github.com/nvkelso/natural-earth-vector/raw/master/10m_cultural/ne_10m_admin_0_countries.shp"
+shapefile_name = "boundary_lines.shp"
+Downloads.download(shapefile_url, shapefile_name);

Load using Shapefile.jl

julia
shapes = Shapefile.Handle(shapefile_name)
+denmark_border = shapes.shapes[71]
+norway_border = shapes.shapes[53]
+sweden_border = shapes.shapes[54];

Then load raster data. We load some worldclim layers using RasterDataSources via Rasters.jl:

julia
using Rasters, RasterDataSources
+using Dates
+climate = RasterStack(WorldClim{Climate}, (:tmin, :tmax, :prec, :wind); month=July)
╭───────────────────────╮
+│ 2160×1080 RasterStack │
+├───────────────────────┴──────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.83333333333331, 2160) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(89.83333333333333, -90.0, 1080) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 2160×1080
+  :tmax eltype: Float32 dims: X, Y size: 2160×1080
+  :prec eltype: Int16 dims: X, Y size: 2160×1080
+  :wind eltype: Float32 dims: X, Y size: 2160×1080
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (-180.0, 179.99999999999997), Y = (-90.0, 90.0))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

mask Denmark, Norway and Sweden from the global dataset using their border polygon, then trim the missing values. We pad trim with a 10 pixel margin.

julia
mask_trim(climate, poly) = trim(mask(climate; with=poly); pad=10)
+
+denmark = mask_trim(climate, denmark_border)
+norway = mask_trim(climate, norway_border)
+sweden = mask_trim(climate, sweden_border)
╭────────────────────╮
+│ 98×102 RasterStack │
+├────────────────────┴─────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} LinRange{Float64}(9.499999999999972, 25.666666666666643, 98) ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} LinRange{Float64}(70.5, 53.66666666666667, 102) ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 98×102
+  :tmax eltype: Float32 dims: X, Y size: 98×102
+  :prec eltype: Int16 dims: X, Y size: 98×102
+  :wind eltype: Float32 dims: X, Y size: 98×102
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (9.499999999999972, 25.83333333333331), Y = (53.66666666666667, 70.66666666666667))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

Plotting with Plots.jl

First define a function to add borders to all subplots.

julia
function borders!(p, poly)
+    for i in 1:length(p)
+        Plots.plot!(p, poly; subplot=i, fillalpha=0, linewidth=0.6)
+    end
+    return p
+end
borders! (generic function with 1 method)

Now we can plot the individual countries.

julia
dp = plot(denmark)
+borders!(dp, denmark_border)

and sweden

julia
sp = plot(sweden)
+borders!(sp, sweden_border)

and norway

julia
np = plot(norway)
+borders!(np, norway_border)

The Norway shape includes a lot of islands. Lets crop them out using .. intervals:

julia
norway_region = climate[X(0..40), Y(55..73)]
+plot(norway_region)

And mask it with the border again:

julia
norway = mask_trim(norway_region, norway_border)
+np = plot(norway)
+borders!(np, norway_border)

Now we can combine the countries into a single raster using mosaic. first will take the first value if/when there is an overlap.

julia
scandinavia = mosaic(first, denmark, norway, sweden)
╭─────────────────────╮
+│ 177×119 RasterStack │
+├─────────────────────┴────────────────────────────────────────────────── dims ┐
+  ↓ X Projected{Float64} 3.1666666666666443:0.16666666666666666:32.49999999999998 ForwardOrdered Regular Intervals{Start},
+  → Y Projected{Float64} 72.66666666666666:-0.16666666666666666:52.99999999999999 ReverseOrdered Regular Intervals{Start}
+├────────────────────────────────────────────────────────────────────── layers ┤
+  :tmin eltype: Float32 dims: X, Y size: 177×119
+  :tmax eltype: Float32 dims: X, Y size: 177×119
+  :prec eltype: Int16 dims: X, Y size: 177×119
+  :wind eltype: Float32 dims: X, Y size: 177×119
+├────────────────────────────────────────────────────────────────────── raster ┤
+  extent: Extent(X = (3.1666666666666443, 32.66666666666664), Y = (52.99999999999999, 72.83333333333333))
+  missingval: (tmin = -3.4f38, tmax = -3.4f38, prec = -32768, wind = -3.4f38)
+  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
+└──────────────────────────────────────────────────────────────────────────────┘

And plot scandinavia, with all borders included:

julia
p = plot(scandinavia)
+borders!(p, denmark_border)
+borders!(p, norway_border)
+borders!(p, sweden_border)
+p

And save to netcdf - a single multi-layered file, and tif, which will write a file for each stack layer.

julia
write("scandinavia.nc", scandinavia)
+write("scandinavia.tif", scandinavia)
(tmin = "scandinavia_tmin.tif", tmax = "scandinavia_tmax.tif", prec = "scandinavia_prec.tif", wind = "scandinavia_wind.tif")

Rasters.jl provides a range of other methods that are being added to over time. Where applicable these methods read and write lazily to and from disk-based arrays of common raster file types. These methods also work for entire RasterStacks and RasterSeries using the same syntax.

+ + + + \ No newline at end of file diff --git a/previews/PR807/siteinfo.js b/previews/PR807/siteinfo.js new file mode 100644 index 00000000..ea3998f2 --- /dev/null +++ b/previews/PR807/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "previews/PR807";