diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..b72a7ca2c --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 84cf3550a94947108bc515d701c92eb8 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/CONTRIBUTING.doctree b/.doctrees/CONTRIBUTING.doctree new file mode 100644 index 000000000..ff5f5b1f2 Binary files /dev/null and b/.doctrees/CONTRIBUTING.doctree differ diff --git a/.doctrees/_generated/gustaf.create.doctree b/.doctrees/_generated/gustaf.create.doctree new file mode 100644 index 000000000..d0552e6e5 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.doctree differ diff --git a/.doctrees/_generated/gustaf.create.edges.doctree b/.doctrees/_generated/gustaf.create.edges.doctree new file mode 100644 index 000000000..e93d3eef4 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.edges.doctree differ diff --git a/.doctrees/_generated/gustaf.create.edges.from_data.doctree b/.doctrees/_generated/gustaf.create.edges.from_data.doctree new file mode 100644 index 000000000..d1defa9bd Binary files /dev/null and b/.doctrees/_generated/gustaf.create.edges.from_data.doctree differ diff --git a/.doctrees/_generated/gustaf.create.edges.from_vertices.doctree b/.doctrees/_generated/gustaf.create.edges.from_vertices.doctree new file mode 100644 index 000000000..03f70f7cc Binary files /dev/null and b/.doctrees/_generated/gustaf.create.edges.from_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.box.doctree b/.doctrees/_generated/gustaf.create.faces.box.doctree new file mode 100644 index 000000000..e1f7551c1 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.box.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.doctree b/.doctrees/_generated/gustaf.create.faces.doctree new file mode 100644 index 000000000..fc3064d84 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.edges_as_quad.doctree b/.doctrees/_generated/gustaf.create.faces.edges_as_quad.doctree new file mode 100644 index 000000000..7b7c41bdf Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.edges_as_quad.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.to_quad.doctree b/.doctrees/_generated/gustaf.create.faces.to_quad.doctree new file mode 100644 index 000000000..5ea585638 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.to_quad.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.to_simplex.doctree b/.doctrees/_generated/gustaf.create.faces.to_simplex.doctree new file mode 100644 index 000000000..dbf8759a7 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.to_simplex.doctree differ diff --git a/.doctrees/_generated/gustaf.create.faces.vertex_normals.doctree b/.doctrees/_generated/gustaf.create.faces.vertex_normals.doctree new file mode 100644 index 000000000..68747d777 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.faces.vertex_normals.doctree differ diff --git a/.doctrees/_generated/gustaf.create.vertices.doctree b/.doctrees/_generated/gustaf.create.vertices.doctree new file mode 100644 index 000000000..c387afd70 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.create.vertices.raster.doctree b/.doctrees/_generated/gustaf.create.vertices.raster.doctree new file mode 100644 index 000000000..fe1ad2cbc Binary files /dev/null and b/.doctrees/_generated/gustaf.create.vertices.raster.doctree differ diff --git a/.doctrees/_generated/gustaf.create.volumes.box.doctree b/.doctrees/_generated/gustaf.create.volumes.box.doctree new file mode 100644 index 000000000..7001cf46e Binary files /dev/null and b/.doctrees/_generated/gustaf.create.volumes.box.doctree differ diff --git a/.doctrees/_generated/gustaf.create.volumes.doctree b/.doctrees/_generated/gustaf.create.volumes.doctree new file mode 100644 index 000000000..eb0aa9db4 Binary files /dev/null and b/.doctrees/_generated/gustaf.create.volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.doctree b/.doctrees/_generated/gustaf.doctree new file mode 100644 index 000000000..3259c6447 Binary files /dev/null and b/.doctrees/_generated/gustaf.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.centers.doctree b/.doctrees/_generated/gustaf.edges.Edges.centers.doctree new file mode 100644 index 000000000..41e4da89f Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.centers.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.const_edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.const_edges.doctree new file mode 100644 index 000000000..a983d0431 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.const_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.const_elements.doctree b/.doctrees/_generated/gustaf.edges.Edges.const_elements.doctree new file mode 100644 index 000000000..2ede6f5be Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.const_elements.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.dashed.doctree b/.doctrees/_generated/gustaf.edges.Edges.dashed.doctree new file mode 100644 index 000000000..d10848d7b Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.dashed.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.doctree new file mode 100644 index 000000000..3b4444fcc Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.edges.doctree new file mode 100644 index 000000000..69b67b409 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.elements.doctree b/.doctrees/_generated/gustaf.edges.Edges.elements.doctree new file mode 100644 index 000000000..607f2713f Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.elements.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.kind.doctree b/.doctrees/_generated/gustaf.edges.Edges.kind.doctree new file mode 100644 index 000000000..57b0bc632 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.kind.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.referenced_vertices.doctree b/.doctrees/_generated/gustaf.edges.Edges.referenced_vertices.doctree new file mode 100644 index 000000000..9c5e95d07 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.referenced_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.doctree b/.doctrees/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.doctree new file mode 100644 index 000000000..7af4890e3 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.shrink.doctree b/.doctrees/_generated/gustaf.edges.Edges.shrink.doctree new file mode 100644 index 000000000..9a9ac41fc Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.shrink.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.single_edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.single_edges.doctree new file mode 100644 index 000000000..34f261f0d Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.single_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.sorted_edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.sorted_edges.doctree new file mode 100644 index 000000000..e55941b9f Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.sorted_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.to_vertices.doctree b/.doctrees/_generated/gustaf.edges.Edges.to_vertices.doctree new file mode 100644 index 000000000..27c0b9c00 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.to_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.unique_edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.unique_edges.doctree new file mode 100644 index 000000000..34083fa30 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.unique_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.update_edges.doctree b/.doctrees/_generated/gustaf.edges.Edges.update_edges.doctree new file mode 100644 index 000000000..f11b8debe Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.update_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.update_elements.doctree b/.doctrees/_generated/gustaf.edges.Edges.update_elements.doctree new file mode 100644 index 000000000..b61f4b814 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.update_elements.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.Edges.whatami.doctree b/.doctrees/_generated/gustaf.edges.Edges.whatami.doctree new file mode 100644 index 000000000..e434d5d29 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.Edges.whatami.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.EdgesShowOption.doctree b/.doctrees/_generated/gustaf.edges.EdgesShowOption.doctree new file mode 100644 index 000000000..b98a7c1b7 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.EdgesShowOption.doctree differ diff --git a/.doctrees/_generated/gustaf.edges.doctree b/.doctrees/_generated/gustaf.edges.doctree new file mode 100644 index 000000000..56650bfb5 Binary files /dev/null and b/.doctrees/_generated/gustaf.edges.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.BC.doctree b/.doctrees/_generated/gustaf.faces.Faces.BC.doctree new file mode 100644 index 000000000..345c28331 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.BC.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.const_edges.doctree b/.doctrees/_generated/gustaf.faces.Faces.const_edges.doctree new file mode 100644 index 000000000..84e7d0d35 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.const_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.const_faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.const_faces.doctree new file mode 100644 index 000000000..3827104fb Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.const_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.dashed.doctree b/.doctrees/_generated/gustaf.faces.Faces.dashed.doctree new file mode 100644 index 000000000..fd4a098a0 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.dashed.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.doctree new file mode 100644 index 000000000..370aa2b12 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.edges.doctree b/.doctrees/_generated/gustaf.faces.Faces.edges.doctree new file mode 100644 index 000000000..83e9c4b2e Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.edges.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.faces.doctree new file mode 100644 index 000000000..624397b5b Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.kind.doctree b/.doctrees/_generated/gustaf.faces.Faces.kind.doctree new file mode 100644 index 000000000..80a629a28 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.kind.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.single_faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.single_faces.doctree new file mode 100644 index 000000000..1c16c99f1 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.single_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.sorted_faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.sorted_faces.doctree new file mode 100644 index 000000000..e6afcaea3 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.sorted_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.to_edges.doctree b/.doctrees/_generated/gustaf.faces.Faces.to_edges.doctree new file mode 100644 index 000000000..c2eeb305d Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.to_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.to_subelements.doctree b/.doctrees/_generated/gustaf.faces.Faces.to_subelements.doctree new file mode 100644 index 000000000..434f18dd4 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.to_subelements.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.unique_faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.unique_faces.doctree new file mode 100644 index 000000000..a12ad719a Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.unique_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.update_edges.doctree b/.doctrees/_generated/gustaf.faces.Faces.update_edges.doctree new file mode 100644 index 000000000..44b17d589 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.update_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.update_faces.doctree b/.doctrees/_generated/gustaf.faces.Faces.update_faces.doctree new file mode 100644 index 000000000..ba74173c9 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.update_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.whatami.doctree b/.doctrees/_generated/gustaf.faces.Faces.whatami.doctree new file mode 100644 index 000000000..65406d537 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.whatami.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.Faces.whatareyou.doctree b/.doctrees/_generated/gustaf.faces.Faces.whatareyou.doctree new file mode 100644 index 000000000..45858c8b1 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.Faces.whatareyou.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.FacesShowOption.doctree b/.doctrees/_generated/gustaf.faces.FacesShowOption.doctree new file mode 100644 index 000000000..caadab8d8 Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.FacesShowOption.doctree differ diff --git a/.doctrees/_generated/gustaf.faces.doctree b/.doctrees/_generated/gustaf.faces.doctree new file mode 100644 index 000000000..1e154129e Binary files /dev/null and b/.doctrees/_generated/gustaf.faces.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.ComputedData.depends_on.doctree b/.doctrees/_generated/gustaf.helpers.data.ComputedData.depends_on.doctree new file mode 100644 index 000000000..0ac4e16fd Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.ComputedData.depends_on.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.ComputedData.doctree b/.doctrees/_generated/gustaf.helpers.data.ComputedData.doctree new file mode 100644 index 000000000..75f94685e Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.ComputedData.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.ComputedMeshData.doctree b/.doctrees/_generated/gustaf.helpers.data.ComputedMeshData.doctree new file mode 100644 index 000000000..d2a67705c Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.ComputedMeshData.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.clear.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.clear.doctree new file mode 100644 index 000000000..e3263c7f3 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.clear.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.doctree new file mode 100644 index 000000000..4726bb040 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.get.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.get.doctree new file mode 100644 index 000000000..2711705d1 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.get.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.items.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.items.doctree new file mode 100644 index 000000000..4d1d5367e Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.items.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.keys.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.keys.doctree new file mode 100644 index 000000000..4f358b569 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.keys.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.pop.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.pop.doctree new file mode 100644 index 000000000..77411b8ec Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.pop.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.update.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.update.doctree new file mode 100644 index 000000000..ed6e90c8b Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.update.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.DataHolder.values.doctree b/.doctrees/_generated/gustaf.helpers.data.DataHolder.values.doctree new file mode 100644 index 000000000..c1566c85a Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.DataHolder.values.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.TrackedArray.copy.doctree b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.copy.doctree new file mode 100644 index 000000000..22c99b69f Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.copy.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.TrackedArray.doctree b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.doctree new file mode 100644 index 000000000..60f672a79 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.TrackedArray.modified.doctree b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.modified.doctree new file mode 100644 index 000000000..31c3ddd7e Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.modified.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.TrackedArray.view.doctree b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.view.doctree new file mode 100644 index 000000000..5c1b5cd4f Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.TrackedArray.view.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.doctree new file mode 100644 index 000000000..b2ac2a5df Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.ids.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.ids.doctree new file mode 100644 index 000000000..b66ab97c6 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.ids.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.intersection.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.intersection.doctree new file mode 100644 index 000000000..4e9925522 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.intersection.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.inverse.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.inverse.doctree new file mode 100644 index 000000000..a524b40e5 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.inverse.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.values.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.values.doctree new file mode 100644 index 000000000..442b1dc82 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DFloats.values.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.counts.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.counts.doctree new file mode 100644 index 000000000..2cca8d0e6 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.counts.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.doctree new file mode 100644 index 000000000..f741f39f7 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.ids.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.ids.doctree new file mode 100644 index 000000000..5b8d46f69 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.ids.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.doctree new file mode 100644 index 000000000..c119b6a5f Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.values.doctree b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.values.doctree new file mode 100644 index 000000000..bb7bbf671 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.Unique2DIntegers.values.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.VertexData.as_arrow.doctree b/.doctrees/_generated/gustaf.helpers.data.VertexData.as_arrow.doctree new file mode 100644 index 000000000..e936fda60 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.VertexData.as_arrow.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.VertexData.as_scalar.doctree b/.doctrees/_generated/gustaf.helpers.data.VertexData.as_scalar.doctree new file mode 100644 index 000000000..02545d25e Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.VertexData.as_scalar.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.VertexData.doctree b/.doctrees/_generated/gustaf.helpers.data.VertexData.doctree new file mode 100644 index 000000000..6e8a9aa33 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.VertexData.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.doctree b/.doctrees/_generated/gustaf.helpers.data.doctree new file mode 100644 index 000000000..843e91ad7 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.data.make_tracked_array.doctree b/.doctrees/_generated/gustaf.helpers.data.make_tracked_array.doctree new file mode 100644 index 000000000..089671fdf Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.data.make_tracked_array.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.doctree b/.doctrees/_generated/gustaf.helpers.doctree new file mode 100644 index 000000000..4843e1487 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.doctree b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.doctree new file mode 100644 index 000000000..5f017f406 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.close.doctree b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.close.doctree new file mode 100644 index 000000000..08eebea50 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.close.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.display.doctree b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.display.doctree new file mode 100644 index 000000000..40297e2d1 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.display.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.doctree b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.doctree new file mode 100644 index 000000000..f4235363c Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.show.doctree b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.show.doctree new file mode 100644 index 000000000..6323b8178 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.K3DPlotterN.show.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.doctree b/.doctrees/_generated/gustaf.helpers.notebook.doctree new file mode 100644 index 000000000..0173be19c Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.notebook.get_shape.doctree b/.doctrees/_generated/gustaf.helpers.notebook.get_shape.doctree new file mode 100644 index 000000000..81730c870 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.notebook.get_shape.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.allowed_types.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.allowed_types.doctree new file mode 100644 index 000000000..60fd7647f Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.allowed_types.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.backends.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.backends.doctree new file mode 100644 index 000000000..484273986 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.backends.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.default.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.default.doctree new file mode 100644 index 000000000..3fd6e04ee Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.default.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.description.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.description.doctree new file mode 100644 index 000000000..0725a9df8 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.description.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.doctree new file mode 100644 index 000000000..0f77064a0 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.Option.key.doctree b/.doctrees/_generated/gustaf.helpers.options.Option.key.doctree new file mode 100644 index 000000000..ff579735a Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.Option.key.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.SetDefault.default.doctree b/.doctrees/_generated/gustaf.helpers.options.SetDefault.default.doctree new file mode 100644 index 000000000..8805ff614 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.SetDefault.default.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.SetDefault.doctree b/.doctrees/_generated/gustaf.helpers.options.SetDefault.doctree new file mode 100644 index 000000000..0a789fd25 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.SetDefault.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.SetDefault.key.doctree b/.doctrees/_generated/gustaf.helpers.options.SetDefault.key.doctree new file mode 100644 index 000000000..b8f794a39 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.SetDefault.key.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.clear.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.clear.doctree new file mode 100644 index 000000000..39e99b817 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.clear.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.doctree new file mode 100644 index 000000000..b8f03d17a Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.doctree new file mode 100644 index 000000000..e894103f8 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.get.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.get.doctree new file mode 100644 index 000000000..54ede6cb2 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.get.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.items.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.items.doctree new file mode 100644 index 000000000..5da3d2504 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.items.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.keys.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.keys.doctree new file mode 100644 index 000000000..16e6ab53f Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.keys.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.pop.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.pop.doctree new file mode 100644 index 000000000..cde5e142c Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.pop.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.update.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.update.doctree new file mode 100644 index 000000000..29b32ac8b Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.update.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.valid_keys.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.valid_keys.doctree new file mode 100644 index 000000000..f663e6c13 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.valid_keys.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.ShowOption.values.doctree b/.doctrees/_generated/gustaf.helpers.options.ShowOption.values.doctree new file mode 100644 index 000000000..96d81983d Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.ShowOption.values.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.doctree b/.doctrees/_generated/gustaf.helpers.options.doctree new file mode 100644 index 000000000..3458182e0 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.options.make_valid_options.doctree b/.doctrees/_generated/gustaf.helpers.options.make_valid_options.doctree new file mode 100644 index 000000000..3df9a107c Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.options.make_valid_options.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.doctree b/.doctrees/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.doctree new file mode 100644 index 000000000..723b91039 Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.raise_if.doctree b/.doctrees/_generated/gustaf.helpers.raise_if.doctree new file mode 100644 index 000000000..1e6a3cc5e Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.raise_if.doctree differ diff --git a/.doctrees/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.doctree b/.doctrees/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.doctree new file mode 100644 index 000000000..9ef857c2d Binary files /dev/null and b/.doctrees/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.doctree differ diff --git a/.doctrees/_generated/gustaf.io.default.doctree b/.doctrees/_generated/gustaf.io.default.doctree new file mode 100644 index 000000000..af7945fcd Binary files /dev/null and b/.doctrees/_generated/gustaf.io.default.doctree differ diff --git a/.doctrees/_generated/gustaf.io.default.load.doctree b/.doctrees/_generated/gustaf.io.default.load.doctree new file mode 100644 index 000000000..3e36889ce Binary files /dev/null and b/.doctrees/_generated/gustaf.io.default.load.doctree differ diff --git a/.doctrees/_generated/gustaf.io.doctree b/.doctrees/_generated/gustaf.io.doctree new file mode 100644 index 000000000..1c2986c07 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.doctree differ diff --git a/.doctrees/_generated/gustaf.io.ioutils.abs_fname.doctree b/.doctrees/_generated/gustaf.io.ioutils.abs_fname.doctree new file mode 100644 index 000000000..a64bff180 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.ioutils.abs_fname.doctree differ diff --git a/.doctrees/_generated/gustaf.io.ioutils.check_and_makedirs.doctree b/.doctrees/_generated/gustaf.io.ioutils.check_and_makedirs.doctree new file mode 100644 index 000000000..e125f129e Binary files /dev/null and b/.doctrees/_generated/gustaf.io.ioutils.check_and_makedirs.doctree differ diff --git a/.doctrees/_generated/gustaf.io.ioutils.doctree b/.doctrees/_generated/gustaf.io.ioutils.doctree new file mode 100644 index 000000000..118b6af67 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.ioutils.doctree differ diff --git a/.doctrees/_generated/gustaf.io.meshio.doctree b/.doctrees/_generated/gustaf.io.meshio.doctree new file mode 100644 index 000000000..2a9321009 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.meshio.doctree differ diff --git a/.doctrees/_generated/gustaf.io.meshio.export.doctree b/.doctrees/_generated/gustaf.io.meshio.export.doctree new file mode 100644 index 000000000..1302f677a Binary files /dev/null and b/.doctrees/_generated/gustaf.io.meshio.export.doctree differ diff --git a/.doctrees/_generated/gustaf.io.meshio.load.doctree b/.doctrees/_generated/gustaf.io.meshio.load.doctree new file mode 100644 index 000000000..e3613560d Binary files /dev/null and b/.doctrees/_generated/gustaf.io.meshio.load.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mfem.doctree b/.doctrees/_generated/gustaf.io.mfem.doctree new file mode 100644 index 000000000..00320e5ce Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mfem.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mfem.export.doctree b/.doctrees/_generated/gustaf.io.mfem.export.doctree new file mode 100644 index 000000000..4319cfa6a Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mfem.export.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mfem.load.doctree b/.doctrees/_generated/gustaf.io.mfem.load.doctree new file mode 100644 index 000000000..b71a23e9b Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mfem.load.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mixd.doctree b/.doctrees/_generated/gustaf.io.mixd.doctree new file mode 100644 index 000000000..5ae0ee796 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mixd.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mixd.export.doctree b/.doctrees/_generated/gustaf.io.mixd.export.doctree new file mode 100644 index 000000000..18a0ed853 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mixd.export.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mixd.load.doctree b/.doctrees/_generated/gustaf.io.mixd.load.doctree new file mode 100644 index 000000000..4c7401d23 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mixd.load.doctree differ diff --git a/.doctrees/_generated/gustaf.io.mixd.make_mrng.doctree b/.doctrees/_generated/gustaf.io.mixd.make_mrng.doctree new file mode 100644 index 000000000..a69481735 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.mixd.make_mrng.doctree differ diff --git a/.doctrees/_generated/gustaf.io.nutils.doctree b/.doctrees/_generated/gustaf.io.nutils.doctree new file mode 100644 index 000000000..c161f4bc7 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.nutils.doctree differ diff --git a/.doctrees/_generated/gustaf.io.nutils.export.doctree b/.doctrees/_generated/gustaf.io.nutils.export.doctree new file mode 100644 index 000000000..523457217 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.nutils.export.doctree differ diff --git a/.doctrees/_generated/gustaf.io.nutils.load.doctree b/.doctrees/_generated/gustaf.io.nutils.load.doctree new file mode 100644 index 000000000..7f56ff45f Binary files /dev/null and b/.doctrees/_generated/gustaf.io.nutils.load.doctree differ diff --git a/.doctrees/_generated/gustaf.io.nutils.to_nutils_simplex.doctree b/.doctrees/_generated/gustaf.io.nutils.to_nutils_simplex.doctree new file mode 100644 index 000000000..7f0aba238 Binary files /dev/null and b/.doctrees/_generated/gustaf.io.nutils.to_nutils_simplex.doctree differ diff --git a/.doctrees/_generated/gustaf.settings.doctree b/.doctrees/_generated/gustaf.settings.doctree new file mode 100644 index 000000000..42efcbf99 Binary files /dev/null and b/.doctrees/_generated/gustaf.settings.doctree differ diff --git a/.doctrees/_generated/gustaf.show.doctree b/.doctrees/_generated/gustaf.show.doctree new file mode 100644 index 000000000..b81017c72 Binary files /dev/null and b/.doctrees/_generated/gustaf.show.doctree differ diff --git a/.doctrees/_generated/gustaf.show.interpolate_vedo_dictcam.doctree b/.doctrees/_generated/gustaf.show.interpolate_vedo_dictcam.doctree new file mode 100644 index 000000000..9de893bb2 Binary files /dev/null and b/.doctrees/_generated/gustaf.show.interpolate_vedo_dictcam.doctree differ diff --git a/.doctrees/_generated/gustaf.show.make_showable.doctree b/.doctrees/_generated/gustaf.show.make_showable.doctree new file mode 100644 index 000000000..bdd0bd236 Binary files /dev/null and b/.doctrees/_generated/gustaf.show.make_showable.doctree differ diff --git a/.doctrees/_generated/gustaf.show.show.doctree b/.doctrees/_generated/gustaf.show.show.doctree new file mode 100644 index 000000000..328d286f6 Binary files /dev/null and b/.doctrees/_generated/gustaf.show.show.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.bounds.doctree b/.doctrees/_generated/gustaf.utils.arr.bounds.doctree new file mode 100644 index 000000000..df25cbb02 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.bounds.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.bounds_diagonal.doctree b/.doctrees/_generated/gustaf.utils.arr.bounds_diagonal.doctree new file mode 100644 index 000000000..9489469f1 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.bounds_diagonal.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.bounds_mean.doctree b/.doctrees/_generated/gustaf.utils.arr.bounds_mean.doctree new file mode 100644 index 000000000..163a8f4e6 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.bounds_mean.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.bounds_norm.doctree b/.doctrees/_generated/gustaf.utils.arr.bounds_norm.doctree new file mode 100644 index 000000000..6bcf3042d Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.bounds_norm.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.close_rows.doctree b/.doctrees/_generated/gustaf.utils.arr.close_rows.doctree new file mode 100644 index 000000000..f33fe1ec9 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.close_rows.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.cross3d.doctree b/.doctrees/_generated/gustaf.utils.arr.cross3d.doctree new file mode 100644 index 000000000..2168a1e5f Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.cross3d.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.derivatives_to_normals.doctree b/.doctrees/_generated/gustaf.utils.arr.derivatives_to_normals.doctree new file mode 100644 index 000000000..fb8ab4057 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.derivatives_to_normals.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.doctree b/.doctrees/_generated/gustaf.utils.arr.doctree new file mode 100644 index 000000000..e24dc3276 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.enforce_len.doctree b/.doctrees/_generated/gustaf.utils.arr.enforce_len.doctree new file mode 100644 index 000000000..e6f64c706 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.enforce_len.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.is_one_of_shapes.doctree b/.doctrees/_generated/gustaf.utils.arr.is_one_of_shapes.doctree new file mode 100644 index 000000000..36d7a9a88 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.is_one_of_shapes.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.is_shape.doctree b/.doctrees/_generated/gustaf.utils.arr.is_shape.doctree new file mode 100644 index 000000000..187f6a177 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.is_shape.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.make_c_contiguous.doctree b/.doctrees/_generated/gustaf.utils.arr.make_c_contiguous.doctree new file mode 100644 index 000000000..f98888381 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.make_c_contiguous.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.rotate.doctree b/.doctrees/_generated/gustaf.utils.arr.rotate.doctree new file mode 100644 index 000000000..deec828a7 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.rotate.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.rotation_matrix.doctree b/.doctrees/_generated/gustaf.utils.arr.rotation_matrix.doctree new file mode 100644 index 000000000..4226fa337 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.rotation_matrix.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.rotation_matrix_around_axis.doctree b/.doctrees/_generated/gustaf.utils.arr.rotation_matrix_around_axis.doctree new file mode 100644 index 000000000..1b50b3faa Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.rotation_matrix_around_axis.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.select_with_ranges.doctree b/.doctrees/_generated/gustaf.utils.arr.select_with_ranges.doctree new file mode 100644 index 000000000..0080bbad6 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.select_with_ranges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.arr.unique_rows.doctree b/.doctrees/_generated/gustaf.utils.arr.unique_rows.doctree new file mode 100644 index 000000000..802576604 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.arr.unique_rows.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.doctree b/.doctrees/_generated/gustaf.utils.connec.doctree new file mode 100644 index 000000000..12613e4ec Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.faces_to_edges.doctree b/.doctrees/_generated/gustaf.utils.connec.faces_to_edges.doctree new file mode 100644 index 000000000..5dda0a7d1 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.faces_to_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.hexa_to_quad.doctree b/.doctrees/_generated/gustaf.utils.connec.hexa_to_quad.doctree new file mode 100644 index 000000000..b3b22d223 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.hexa_to_quad.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.make_hexa_volumes.doctree b/.doctrees/_generated/gustaf.utils.connec.make_hexa_volumes.doctree new file mode 100644 index 000000000..03debf74f Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.make_hexa_volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.make_quad_faces.doctree b/.doctrees/_generated/gustaf.utils.connec.make_quad_faces.doctree new file mode 100644 index 000000000..a5ba6a3a0 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.make_quad_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.range_to_edges.doctree b/.doctrees/_generated/gustaf.utils.connec.range_to_edges.doctree new file mode 100644 index 000000000..ab448c646 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.range_to_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.sequence_to_edges.doctree b/.doctrees/_generated/gustaf.utils.connec.sequence_to_edges.doctree new file mode 100644 index 000000000..e97e1972b Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.sequence_to_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.sequentialize_edges.doctree b/.doctrees/_generated/gustaf.utils.connec.sequentialize_edges.doctree new file mode 100644 index 000000000..b5d4a5ece Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.sequentialize_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.sorted_unique.doctree b/.doctrees/_generated/gustaf.utils.connec.sorted_unique.doctree new file mode 100644 index 000000000..bc09506b6 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.sorted_unique.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.subdivide_edges.doctree b/.doctrees/_generated/gustaf.utils.connec.subdivide_edges.doctree new file mode 100644 index 000000000..86dbbc9be Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.subdivide_edges.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.subdivide_quad.doctree b/.doctrees/_generated/gustaf.utils.connec.subdivide_quad.doctree new file mode 100644 index 000000000..747d058ec Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.subdivide_quad.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.subdivide_tri.doctree b/.doctrees/_generated/gustaf.utils.connec.subdivide_tri.doctree new file mode 100644 index 000000000..e8313e225 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.subdivide_tri.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.tet_to_tri.doctree b/.doctrees/_generated/gustaf.utils.connec.tet_to_tri.doctree new file mode 100644 index 000000000..e0a63ef38 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.tet_to_tri.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.connec.volumes_to_faces.doctree b/.doctrees/_generated/gustaf.utils.connec.volumes_to_faces.doctree new file mode 100644 index 000000000..e203c18eb Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.connec.volumes_to_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.doctree b/.doctrees/_generated/gustaf.utils.doctree new file mode 100644 index 000000000..7757498cf Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.configure.doctree b/.doctrees/_generated/gustaf.utils.log.configure.doctree new file mode 100644 index 000000000..3f770d38c Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.configure.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.debug.doctree b/.doctrees/_generated/gustaf.utils.log.debug.doctree new file mode 100644 index 000000000..cf91abc16 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.debug.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.doctree b/.doctrees/_generated/gustaf.utils.log.doctree new file mode 100644 index 000000000..fa2e5686a Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.info.doctree b/.doctrees/_generated/gustaf.utils.log.info.doctree new file mode 100644 index 000000000..75d44098a Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.info.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.prepended_log.doctree b/.doctrees/_generated/gustaf.utils.log.prepended_log.doctree new file mode 100644 index 000000000..7e543ba07 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.prepended_log.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.log.warning.doctree b/.doctrees/_generated/gustaf.utils.log.warning.doctree new file mode 100644 index 000000000..afb600d2c Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.log.warning.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.tictoc.Tic.doctree b/.doctrees/_generated/gustaf.utils.tictoc.Tic.doctree new file mode 100644 index 000000000..3e8cd3705 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.tictoc.Tic.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.tictoc.Tic.now.doctree b/.doctrees/_generated/gustaf.utils.tictoc.Tic.now.doctree new file mode 100644 index 000000000..be8376451 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.tictoc.Tic.now.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.tictoc.Tic.summary.doctree b/.doctrees/_generated/gustaf.utils.tictoc.Tic.summary.doctree new file mode 100644 index 000000000..25fa39df2 Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.tictoc.Tic.summary.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.tictoc.Tic.toc.doctree b/.doctrees/_generated/gustaf.utils.tictoc.Tic.toc.doctree new file mode 100644 index 000000000..b3abee1af Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.tictoc.Tic.toc.doctree differ diff --git a/.doctrees/_generated/gustaf.utils.tictoc.doctree b/.doctrees/_generated/gustaf.utils.tictoc.doctree new file mode 100644 index 000000000..ec92b758e Binary files /dev/null and b/.doctrees/_generated/gustaf.utils.tictoc.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.bounds.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.bounds.doctree new file mode 100644 index 000000000..469eaea91 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.bounds.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal.doctree new file mode 100644 index 000000000..2140a24a4 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.doctree new file mode 100644 index 000000000..e1380b4d7 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.concat.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.concat.doctree new file mode 100644 index 000000000..2874e54e8 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.concat.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.const_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.const_vertices.doctree new file mode 100644 index 000000000..4f640e94a Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.const_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.copy.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.copy.doctree new file mode 100644 index 000000000..91a65ab3d Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.copy.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.doctree new file mode 100644 index 000000000..d6081dd9a Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.kind.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.kind.doctree new file mode 100644 index 000000000..6f2c2bbcf Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.kind.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.merge_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.merge_vertices.doctree new file mode 100644 index 000000000..acb38aa03 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.merge_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.remove_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.remove_vertices.doctree new file mode 100644 index 000000000..e24a051db Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.remove_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.select_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.select_vertices.doctree new file mode 100644 index 000000000..0d5ceb344 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.select_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.show.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.show.doctree new file mode 100644 index 000000000..f35cd18ab Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.show.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.show_options.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.show_options.doctree new file mode 100644 index 000000000..d3bc3342d Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.show_options.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.showable.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.showable.doctree new file mode 100644 index 000000000..2d98cb063 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.showable.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.unique_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.unique_vertices.doctree new file mode 100644 index 000000000..71881ebe9 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.unique_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.update_vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.update_vertices.doctree new file mode 100644 index 000000000..95e149244 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.update_vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.vertex_data.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.vertex_data.doctree new file mode 100644 index 000000000..05dd5e6b0 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.vertex_data.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.vertices.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.vertices.doctree new file mode 100644 index 000000000..b0b1eb751 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.Vertices.whatami.doctree b/.doctrees/_generated/gustaf.vertices.Vertices.whatami.doctree new file mode 100644 index 000000000..78b0995f7 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.Vertices.whatami.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.VerticesShowOption.doctree b/.doctrees/_generated/gustaf.vertices.VerticesShowOption.doctree new file mode 100644 index 000000000..d8579a934 Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.VerticesShowOption.doctree differ diff --git a/.doctrees/_generated/gustaf.vertices.doctree b/.doctrees/_generated/gustaf.vertices.doctree new file mode 100644 index 000000000..c0592d2ff Binary files /dev/null and b/.doctrees/_generated/gustaf.vertices.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.const_faces.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.const_faces.doctree new file mode 100644 index 000000000..1352f8e32 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.const_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.const_volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.const_volumes.doctree new file mode 100644 index 000000000..c5304a94a Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.const_volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.doctree new file mode 100644 index 000000000..b04908ee0 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.faces.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.faces.doctree new file mode 100644 index 000000000..08fae60dc Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.faces.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.kind.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.kind.doctree new file mode 100644 index 000000000..298e1c3ef Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.kind.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.sorted_volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.sorted_volumes.doctree new file mode 100644 index 000000000..1754ee73a Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.sorted_volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.to_faces.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.to_faces.doctree new file mode 100644 index 000000000..127ac0852 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.to_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.unique_volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.unique_volumes.doctree new file mode 100644 index 000000000..24f94ad18 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.unique_volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.update_faces.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.update_faces.doctree new file mode 100644 index 000000000..457006c22 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.update_faces.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.update_volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.update_volumes.doctree new file mode 100644 index 000000000..0ea796108 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.update_volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.volumes.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.volumes.doctree new file mode 100644 index 000000000..e7d52b2e2 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.volumes.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.Volumes.whatareyou.doctree b/.doctrees/_generated/gustaf.volumes.Volumes.whatareyou.doctree new file mode 100644 index 000000000..beff8de35 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.Volumes.whatareyou.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.VolumesShowOption.doctree b/.doctrees/_generated/gustaf.volumes.VolumesShowOption.doctree new file mode 100644 index 000000000..8906e621b Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.VolumesShowOption.doctree differ diff --git a/.doctrees/_generated/gustaf.volumes.doctree b/.doctrees/_generated/gustaf.volumes.doctree new file mode 100644 index 000000000..9e29dd449 Binary files /dev/null and b/.doctrees/_generated/gustaf.volumes.doctree differ diff --git a/.doctrees/details.doctree b/.doctrees/details.doctree new file mode 100644 index 000000000..9168d355c Binary files /dev/null and b/.doctrees/details.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 000000000..f8a364abd Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 000000000..6eb6ad50e Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/python_api.doctree b/.doctrees/python_api.doctree new file mode 100644 index 000000000..f7588108c Binary files /dev/null and b/.doctrees/python_api.doctree differ diff --git a/.doctrees/references.doctree b/.doctrees/references.doctree new file mode 100644 index 000000000..1670edd72 Binary files /dev/null and b/.doctrees/references.doctree differ diff --git a/.doctrees/show_options.doctree b/.doctrees/show_options.doctree new file mode 100644 index 000000000..60360f5aa Binary files /dev/null and b/.doctrees/show_options.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/CONTRIBUTING.html b/CONTRIBUTING.html new file mode 100644 index 000000000..3b271f6a5 --- /dev/null +++ b/CONTRIBUTING.html @@ -0,0 +1,605 @@ + + + + + + + + + + + Contributing — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

Contributing#

+
+

Contributing#

+

gustaf welcomes and appreciates discussions, issues and pull requests!

+
+

Quick start#

+

Once the repo is forked, one possible starting point would be creating a new python environments, for example, using conda with python=3.9

+
conda create -n gustafenv python=3.9
+conda activate gustafenv
+git clone git@github.com:<path-to-your-fork>
+cd gustaf
+git checkout -b new-feature0
+pip install -e .[all]
+
+
+
+
+

Style / implementation preferences#

+
    +
  • use if and raise instead of assert

  • +
  • no complex comprehensions: preferably fits in a line, 2 lines max if it is totally necessary

  • +
  • use first letter abbreviations in element loops: for kv in knot_vectors

  • +
  • use i, j, k, l for pure index: for i, kv in enumerate(knot_vectors)

  • +
+
+

Formatting and style check#

+

To check the format and style of your code use the following commands:

+
pip install pre-commit
+precommit run -a
+
+
+
+
+
+

Local docs build#

+

To check if documentations look as intended, you can build it locally. +Remember, spline extensions will be empty if you don’t have splinepy available.

+
pip install -r ./docs/requirements.txt
+sphinx-apidoc -f -t docs/source/_templates -o docs/source gustaf
+sphinx-build -b html docs/source docs/build
+
+
+

Now, you can check documentations by opening docs/build/index.html with a browser.

+
+

Bash script for format and documentation build checking#

+

Thanks to github, we have a CI that runs tests and checks for PRs. +However, in case you’d like to check this locally, here are sequence of commands as a function:

+
# run this at repo's root
+function gustaf_commit() {
+    pre-commit run -a
+    rm -r docs/build
+    rm docs/source/*.*.rst docs/source/gustaf.rst docs/source/modules.rst
+    sphinx-apidoc -f -t docs/source/_templates -o docs/source gustaf
+    sphinx-build -b html docs/source docs/build
+    pytest tests
+}
+
+
+
+
+
+
+ + +
+ + + + + + + +
+ + + + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.edges.from_data.html b/_generated/gustaf.create.edges.from_data.html new file mode 100644 index 000000000..51938acca --- /dev/null +++ b/_generated/gustaf.create.edges.from_data.html @@ -0,0 +1,818 @@ + + + + + + + + + + + gustaf.create.edges.from_data — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.edges.from_data#

+
+
+gustaf.create.edges.from_data(gus_obj, data, scale=None, data_norm=None)[source]#
+

Creates edges from gustaf object with vertices. +Data can be either multi-dim array-like data or a str describing a name +of vertex_data that belongs to given gustaf object. +len(gus_obj.vertices) number of edges will be created, where origin and +end of each edge is created using the following scheme: +[[vertices[0], vertices[0] + (array_data[0] * scale)], …]. +By default, scaling value will be +max([1, (aabb_diagonal_norm * 0.1 / max_data_norm)]). +If there’s dimension mismatch between vertices and the data, will append +zero paddings!

+
+
Parameters:
+
    +
  • gus_obj (Vertices) – gus.Vertices or its derived classes

  • +
  • data (str or (n_vertices, d) array-like) – If str, will be considered as data and search for saved vertex_data.

  • +
  • scale (float) – Absolute value.

  • +
  • data_norm (float or array-like) – If float, will be considered as max_norm of the data. Else, searches for +max value. Doesn’t enforce len to match.

  • +
+
+
Returns:
+

data_arrow

+
+
Return type:
+

Edges

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.edges.from_vertices.html b/_generated/gustaf.create.edges.from_vertices.html new file mode 100644 index 000000000..d927a6af3 --- /dev/null +++ b/_generated/gustaf.create.edges.from_vertices.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.create.edges.from_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.edges.from_vertices#

+
+
+gustaf.create.edges.from_vertices(vertices, closed=False, continuous=True)[source]#
+

Creates Edges with given vertices. If close==True, +last vertices will be connected to the first one. +If continuous==False, it assumes that every two vertices form +an independent line.

+
+
Parameters:
+
    +
  • vertices ((n, d) np.ndarray or Vertices)

  • +
  • close (bool)

  • +
  • continuous (bool)

  • +
+
+
Returns:
+

edges

+
+
Return type:
+

Edges

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.edges.html b/_generated/gustaf.create.edges.html new file mode 100644 index 000000000..aadc84e80 --- /dev/null +++ b/_generated/gustaf.create.edges.html @@ -0,0 +1,787 @@ + + + + + + + + + + + gustaf.create.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.edges#

+

gustaf/create/edges.py +Routines to create edges.

+

Functions

+ + + + + + + + + +

from_data(gus_obj, data[, scale, data_norm])

Creates edges from gustaf object with vertices.

from_vertices(vertices[, closed, continuous])

Creates Edges with given vertices.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.box.html b/_generated/gustaf.create.faces.box.html new file mode 100644 index 000000000..24be54505 --- /dev/null +++ b/_generated/gustaf.create.faces.box.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.create.faces.box — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces.box#

+
+
+gustaf.create.faces.box(bounds=None, resolutions=None, simplex=False, backslash=False)[source]#
+

Create structured quadrangle or triangle block mesh.

+
+
Parameters:
+
    +
  • bounds ((2, 2) array) – Minimum and maximum coordinates.

  • +
  • resolutions – Vertex count in each dimension.

  • +
  • simplex (boolean) – If true, Mesh will be triangular (simplex).

  • +
+
+
Returns:
+

face_mesh

+
+
Return type:
+

Volumes

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.edges_as_quad.html b/_generated/gustaf.create.faces.edges_as_quad.html new file mode 100644 index 000000000..1ea262c13 --- /dev/null +++ b/_generated/gustaf.create.faces.edges_as_quad.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.create.faces.edges_as_quad — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces.edges_as_quad#

+
+
+gustaf.create.faces.edges_as_quad(edges, scaled_normals)[source]#
+

Expands edges to hexa with given scaled_normals.

+
+
Parameters:
+
    +
  • edges (Edges) – (n, d) vertices, (m, 2) edges

  • +
  • scaled_normals ((n, d) np.ndarray) – Values will be used to subtract/add to existing vertices.

  • +
+
+
Returns:
+

expanded

+
+
Return type:
+

Faces

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.html b/_generated/gustaf.create.faces.html new file mode 100644 index 000000000..92ae37521 --- /dev/null +++ b/_generated/gustaf.create.faces.html @@ -0,0 +1,796 @@ + + + + + + + + + + + gustaf.create.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces#

+

gustaf/create/faces.py +Routines to create faces.

+

Functions

+ + + + + + + + + + + + + + + + + + +

box([bounds, resolutions, simplex, backslash])

Create structured quadrangle or triangle block mesh.

edges_as_quad(edges, scaled_normals)

Expands edges to hexa with given scaled_normals.

to_quad(tri)

In case current mesh is triangle surface mesh, it splits triangle faces into three quad faces by inserting another vertices in the middle of each triangle face.

to_simplex(quad[, alternate])

Given quad faces, diagonalize them to turn them into triangles.

vertex_normals(faces[, area_weighting, ...])

Computes vertex normals and saves it in vertex_data.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.to_quad.html b/_generated/gustaf.create.faces.to_quad.html new file mode 100644 index 000000000..acb9d5ad2 --- /dev/null +++ b/_generated/gustaf.create.faces.to_quad.html @@ -0,0 +1,819 @@ + + + + + + + + + + + gustaf.create.faces.to_quad — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces.to_quad#

+
+
+gustaf.create.faces.to_quad(tri)[source]#
+

In case current mesh is triangle surface mesh, it splits triangle faces +into three quad faces by inserting another vertices in the middle of +each triangle face. Warning: mesh quality could be bad!

+

(new) Quad Face

+
Ref: (node_ind), face_ind
+
+         (2)
+         /                     / 2                 (5)/\   /\(4)
+      /  \ /                   / 0  |(6)                 /_____|___1_              (0)   (3)    (1)
+
+face_ind | node_ind
+---------|----------
+0        | 0 3 6 5
+1        | 1 4 6 3
+2        | 2 5 6 4
+
+
+
+
Parameters:
+

None

+
+
Returns:
+

quad_mesh – Only if current mesh is triangle surface mesh. Otherwise, None.

+
+
Return type:
+

Mesh

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.to_simplex.html b/_generated/gustaf.create.faces.to_simplex.html new file mode 100644 index 000000000..5ce825c88 --- /dev/null +++ b/_generated/gustaf.create.faces.to_simplex.html @@ -0,0 +1,828 @@ + + + + + + + + + + + gustaf.create.faces.to_simplex — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces.to_simplex#

+
+
+gustaf.create.faces.to_simplex(quad, alternate=False)[source]#
+

Given quad faces, diagonalize them to turn them into triangles.

+

If quad is counterclockwise (CCW), triangle will also be CCW and +vice versa. Will return a tri-mesh, if input is triangular. +Default diagonalization looks like this:

+
(3) *---* (2)
+    |  /|
+    | / |
+    |/  |
+(0) *---* (1)
+
+
+

resembling ‘slash’.

+
(3) *---* (2)
+    |\  |
+    | \ |
+    |  \|
+(0) *---* (1)
+
+
+

resembling ‘backslash’.

+

If you want to alternate the slash-direction, set alternate-variable.

+
+
Parameters:
+
    +
  • quad (Faces) – Faces representation which is to be converted from a cubic mesh into a +simplex mesh.

  • +
  • alternate (bool) – Alternate between forward and back-slash to avoid “favored” meshing +direction (important in some analysis problem).

  • +
+
+
Returns:
+

tri – Simplexifyed mesh.

+
+
Return type:
+

Faces

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.faces.vertex_normals.html b/_generated/gustaf.create.faces.vertex_normals.html new file mode 100644 index 000000000..0d861229e --- /dev/null +++ b/_generated/gustaf.create.faces.vertex_normals.html @@ -0,0 +1,816 @@ + + + + + + + + + + + gustaf.create.faces.vertex_normals — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.faces.vertex_normals#

+
+
+gustaf.create.faces.vertex_normals(faces, area_weighting=False, angle_weighting=False, return_original_ids=False)[source]#
+

Computes vertex normals and saves it in vertex_data. +This calls inplace remove_unreferenced_vertices, but original IDs can be +retrieved using the flag return_original_ids.

+

The normals are computed on the face-centers and their contributions are +weighted and added to the vertex normals. Per default, all element faces +that are adjacent to a vertex are added with equal contributions, but it is +also possible to use weightings by area of the adjacent element +(area_weighting) or by the angle between edges at the corner vertex.

+
+
Parameters:
+
    +
  • faces (Faces)

  • +
  • area_weighting (bool (false)) – Use the element area as a weighting to its respective normal contribution

  • +
  • angle_weighting (bool (false)) – Use the angle of between element edges as a weighting to its respective +normal contribution

  • +
  • return_original_ids (bool (false)) – return the original ids in the global mesh

  • +
+
+
Returns:
+

faces – faces with vertex_data[“normals”] computed.

+
+
Return type:
+

Faces

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.html b/_generated/gustaf.create.html new file mode 100644 index 000000000..238e19ee4 --- /dev/null +++ b/_generated/gustaf.create.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.create — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.vertices.html b/_generated/gustaf.create.vertices.html new file mode 100644 index 000000000..5a7bde5cb --- /dev/null +++ b/_generated/gustaf.create.vertices.html @@ -0,0 +1,784 @@ + + + + + + + + + + + gustaf.create.vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.vertices#

+

gustaf/create/vertices.py.

+

Routines to create vertices.

+

Functions

+ + + + + + +

raster(bounds, resolutions)

Simple wrapper of np.mgrid to extract raster points of desired bounds and resolutions.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.vertices.raster.html b/_generated/gustaf.create.vertices.raster.html new file mode 100644 index 000000000..5c9e78269 --- /dev/null +++ b/_generated/gustaf.create.vertices.raster.html @@ -0,0 +1,809 @@ + + + + + + + + + + + gustaf.create.vertices.raster — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.vertices.raster#

+
+
+gustaf.create.vertices.raster(bounds, resolutions)[source]#
+

Simple wrapper of np.mgrid to extract raster points of desired bounds +and resolutions.

+
+
Parameters:
+
    +
  • bounds ((2, d) array-like) – float

  • +
  • resolutions ((d,) array-like or int) – int. It will be casted to int. +In case int is given, it will be repeated to match the length of +each bounds

  • +
+
+
Returns:
+

raster_vertices

+
+
Return type:
+

Vertices

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.volumes.box.html b/_generated/gustaf.create.volumes.box.html new file mode 100644 index 000000000..89e5b64df --- /dev/null +++ b/_generated/gustaf.create.volumes.box.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.create.volumes.box — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.volumes.box#

+
+
+gustaf.create.volumes.box(bounds=None, resolutions=None)[source]#
+

Create structured hexahedron block mesh.

+
+
Parameters:
+
    +
  • bounds ((2, 3) array) – Minimum and maximum coordinates.

  • +
  • resolutions – Vertex count in each dimension.

  • +
+
+
Returns:
+

volume_mesh

+
+
Return type:
+

Volumes

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.create.volumes.html b/_generated/gustaf.create.volumes.html new file mode 100644 index 000000000..4e65ecaad --- /dev/null +++ b/_generated/gustaf.create.volumes.html @@ -0,0 +1,784 @@ + + + + + + + + + + + gustaf.create.volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.create.volumes#

+

gustaf/create/volumes.py +Routines to create volumes.

+

Functions

+ + + + + + +

box([bounds, resolutions])

Create structured hexahedron block mesh.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.centers.html b/_generated/gustaf.edges.Edges.centers.html new file mode 100644 index 000000000..536162e30 --- /dev/null +++ b/_generated/gustaf.edges.Edges.centers.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.centers — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.centers#

+
+
+Edges.centers()[source]#
+

Center of elements.

+
+
Parameters:
+

None

+
+
Returns:
+

centers

+
+
Return type:
+

(n_elements, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.const_edges.html b/_generated/gustaf.edges.Edges.const_edges.html new file mode 100644 index 000000000..57b8186c0 --- /dev/null +++ b/_generated/gustaf.edges.Edges.const_edges.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.edges.Edges.const_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.const_edges#

+
+
+property Edges.const_edges#
+

Returns non-writeable version of edges.

+
+
Parameters:
+

None

+
+
Return type:
+

const_edges (n, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.const_elements.html b/_generated/gustaf.edges.Edges.const_elements.html new file mode 100644 index 000000000..372e9ca86 --- /dev/null +++ b/_generated/gustaf.edges.Edges.const_elements.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.const_elements — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.const_elements#

+
+
+property Edges.const_elements#
+

Returns non-mutable version of elements.

+
+
Parameters:
+

None

+
+
Returns:
+

non_mutable_elements

+
+
Return type:
+

(n, d) TrackedArray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.dashed.html b/_generated/gustaf.edges.Edges.dashed.html new file mode 100644 index 000000000..0e9e3a2ea --- /dev/null +++ b/_generated/gustaf.edges.Edges.dashed.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.edges.Edges.dashed — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.dashed#

+
+
+Edges.dashed(spacing=None)[source]#
+

Turn edges into dashed edges(=lines). Given spacing, it will try to +chop edges as close to it as possible. Pattern should look:

+

dashed edges

+
o--------o    o--------o    o--------o
+|<------>|             |<-->|
+   (chop length)         (chop length / 2)
+
+
+
+
Parameters:
+

spacing (float) – Default is None and it will use self.bounds_diagonal_norm() / 50

+
+
Returns:
+

dashing_edges

+
+
Return type:
+

Edges

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.edges.html b/_generated/gustaf.edges.Edges.edges.html new file mode 100644 index 000000000..d7ef1393a --- /dev/null +++ b/_generated/gustaf.edges.Edges.edges.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.edges#

+
+
+property Edges.edges#
+

Returns edges. If edges is not its original property.

+
+
Parameters:
+

None

+
+
Returns:
+

edges

+
+
Return type:
+

(n, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.elements.html b/_generated/gustaf.edges.Edges.elements.html new file mode 100644 index 000000000..5953f2007 --- /dev/null +++ b/_generated/gustaf.edges.Edges.elements.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.edges.Edges.elements — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.elements#

+
+
+property Edges.elements#
+

Returns current connectivity. A short cut in FE friendly term. +Elements mean different things for different classes: Vertices -> +vertices Edges -> edges Faces -> faces Volumes -> volumes.

+
+
Parameters:
+

None

+
+
Returns:
+

elements – int. iff elements=None

+
+
Return type:
+

(n, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.html b/_generated/gustaf.edges.Edges.html new file mode 100644 index 000000000..a5c4e61ef --- /dev/null +++ b/_generated/gustaf.edges.Edges.html @@ -0,0 +1,853 @@ + + + + + + + + + + + gustaf.edges.Edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges#

+
+
+class gustaf.edges.Edges(vertices=None, edges=None, elements=None)[source]#
+

Bases: Vertices

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Edges.centers()

Center of elements.

Edges.dashed([spacing])

Turn edges into dashed edges(=lines).

Edges.referenced_vertices()

Returns mask of referenced vertices.

Edges.remove_unreferenced_vertices()

Remove unreferenced vertices.

Edges.shrink([ratio, map_vertex_data])

Returns shrunk elements.

Edges.single_edges()

Returns indices of very unique edges: edges that appear only once.

Edges.sorted_edges()

Sort edges along axis=1.

Edges.to_vertices()

Returns Vertices obj.

Edges.unique_edges()

Returns a named tuple of unique edge info.

Edges.update_edges(*args, **kwargs)

Alias to update_elements.

Edges.update_elements(mask)

Similar to update_vertices, but for elements.

+

Attributes

+ + + + + + + + + + + + + + + + + + + + + +

Edges.const_edges

Returns non-writeable version of edges.

Edges.const_elements

Returns non-mutable version of elements.

Edges.edges

Returns edges.

Edges.elements

Returns current connectivity.

Edges.kind

Edges.whatami

whatami?

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.kind.html b/_generated/gustaf.edges.Edges.kind.html new file mode 100644 index 000000000..fe8eeed7b --- /dev/null +++ b/_generated/gustaf.edges.Edges.kind.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.edges.Edges.kind — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.kind#

+
+
+Edges.kind = 'edge'#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.referenced_vertices.html b/_generated/gustaf.edges.Edges.referenced_vertices.html new file mode 100644 index 000000000..92c5ef4c4 --- /dev/null +++ b/_generated/gustaf.edges.Edges.referenced_vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.referenced_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.referenced_vertices#

+
+
+Edges.referenced_vertices()[source]#
+

Returns mask of referenced vertices.

+
+
Parameters:
+

None

+
+
Returns:
+

referenced

+
+
Return type:
+

(n,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.html b/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.html new file mode 100644 index 000000000..19109539b --- /dev/null +++ b/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.edges.Edges.remove_unreferenced_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.remove_unreferenced_vertices#

+
+
+Edges.remove_unreferenced_vertices()[source]#
+

Remove unreferenced vertices. Adapted from +github.com/mikedh/trimesh

+
+
Parameters:
+

None

+
+
Returns:
+

new_self

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.shrink.html b/_generated/gustaf.edges.Edges.shrink.html new file mode 100644 index 000000000..a878acbfb --- /dev/null +++ b/_generated/gustaf.edges.Edges.shrink.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.edges.Edges.shrink — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.shrink#

+
+
+Edges.shrink(ratio=0.8, map_vertex_data=True)[source]#
+

Returns shrunk elements.

+
+
Parameters:
+
    +
  • ratio (float) – Default is 0.8

  • +
  • map_vertex_data (bool) – Default is True. Maps all vertex_data.

  • +
+
+
Returns:
+

s_elements – shrunk elements

+
+
Return type:
+

Elements

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.single_edges.html b/_generated/gustaf.edges.Edges.single_edges.html new file mode 100644 index 000000000..79391af19 --- /dev/null +++ b/_generated/gustaf.edges.Edges.single_edges.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.edges.Edges.single_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.single_edges#

+
+
+Edges.single_edges()[source]#
+

Returns indices of very unique edges: edges that appear only once. +For well constructed faces, this can be considered as outlines.

+
+
Parameters:
+

None

+
+
Returns:
+

outlines

+
+
Return type:
+

(m,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.sorted_edges.html b/_generated/gustaf.edges.Edges.sorted_edges.html new file mode 100644 index 000000000..59d398554 --- /dev/null +++ b/_generated/gustaf.edges.Edges.sorted_edges.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.sorted_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.sorted_edges#

+
+
+Edges.sorted_edges()[source]#
+

Sort edges along axis=1.

+
+
Parameters:
+

None

+
+
Returns:
+

edges_sorted

+
+
Return type:
+

(n_edges, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.to_vertices.html b/_generated/gustaf.edges.Edges.to_vertices.html new file mode 100644 index 000000000..1c523cf4a --- /dev/null +++ b/_generated/gustaf.edges.Edges.to_vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.to_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.to_vertices#

+
+
+Edges.to_vertices()[source]#
+

Returns Vertices obj.

+
+
Parameters:
+

None

+
+
Returns:
+

vertices

+
+
Return type:
+

Vertices

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.unique_edges.html b/_generated/gustaf.edges.Edges.unique_edges.html new file mode 100644 index 000000000..1c75e62f2 --- /dev/null +++ b/_generated/gustaf.edges.Edges.unique_edges.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.edges.Edges.unique_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.unique_edges#

+
+
+Edges.unique_edges()[source]#
+

Returns a named tuple of unique edge info. Info includes unique +values, ids of unique edges, inverse ids, count of each unique values.

+
+
Parameters:
+

None

+
+
Returns:
+

unique_info – valid attributes are {values, ids, inverse, counts}

+
+
Return type:
+

Unique2DIntegers

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.update_edges.html b/_generated/gustaf.edges.Edges.update_edges.html new file mode 100644 index 000000000..672cace48 --- /dev/null +++ b/_generated/gustaf.edges.Edges.update_edges.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.edges.Edges.update_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.update_edges#

+
+
+Edges.update_edges(*args, **kwargs)[source]#
+

Alias to update_elements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.update_elements.html b/_generated/gustaf.edges.Edges.update_elements.html new file mode 100644 index 000000000..fd28d2b3a --- /dev/null +++ b/_generated/gustaf.edges.Edges.update_elements.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.update_elements — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.update_elements#

+
+
+Edges.update_elements(mask)[source]#
+

Similar to update_vertices, but for elements.

+
+
Parameters:
+

mask (bool or (m,) np.ndarray)

+
+
Returns:
+

new_self

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.Edges.whatami.html b/_generated/gustaf.edges.Edges.whatami.html new file mode 100644 index 000000000..bf9906347 --- /dev/null +++ b/_generated/gustaf.edges.Edges.whatami.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.edges.Edges.whatami — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.Edges.whatami#

+
+
+property Edges.whatami#
+

whatami?

+
+
Parameters:
+

None

+
+
Returns:
+

whatami

+
+
Return type:
+

str

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.EdgesShowOption.html b/_generated/gustaf.edges.EdgesShowOption.html new file mode 100644 index 000000000..2d1e5c1cf --- /dev/null +++ b/_generated/gustaf.edges.EdgesShowOption.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.edges.EdgesShowOption — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges.EdgesShowOption#

+
+
+class gustaf.edges.EdgesShowOption(helpee)[source]#
+

Bases: ShowOption

+

Show options for vertices.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.edges.html b/_generated/gustaf.edges.html new file mode 100644 index 000000000..7ef20a780 --- /dev/null +++ b/_generated/gustaf.edges.html @@ -0,0 +1,787 @@ + + + + + + + + + + + gustaf.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.edges#

+

gustaf/gustaf/edges.py.

+

Edges. Also known as lines.

+

Classes

+ + + + + + + + + +

Edges([vertices, edges, elements])

EdgesShowOption(helpee)

Show options for vertices.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.BC.html b/_generated/gustaf.faces.Faces.BC.html new file mode 100644 index 000000000..57f58bdfe --- /dev/null +++ b/_generated/gustaf.faces.Faces.BC.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.faces.Faces.BC — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.BC#

+
+
+Faces.BC#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.const_edges.html b/_generated/gustaf.faces.Faces.const_edges.html new file mode 100644 index 000000000..fcdf23d9c --- /dev/null +++ b/_generated/gustaf.faces.Faces.const_edges.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.faces.Faces.const_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.const_edges#

+
+
+property Faces.const_edges#
+

Returns non-writeable version of edges.

+
+
Parameters:
+

None

+
+
Return type:
+

const_edges (n, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.const_faces.html b/_generated/gustaf.faces.Faces.const_faces.html new file mode 100644 index 000000000..3c733466b --- /dev/null +++ b/_generated/gustaf.faces.Faces.const_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.faces.Faces.const_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.const_faces#

+
+
+property Faces.const_faces#
+

Returns non-writeable view of faces.

+
+
Parameters:
+

None

+
+
Returns:
+

const_faces

+
+
Return type:
+

(n, 2

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.dashed.html b/_generated/gustaf.faces.Faces.dashed.html new file mode 100644 index 000000000..9970e1991 --- /dev/null +++ b/_generated/gustaf.faces.Faces.dashed.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.faces.Faces.dashed — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.dashed#

+
+
+Faces.dashed()#
+

Turn edges into dashed edges(=lines). Given spacing, it will try to +chop edges as close to it as possible. Pattern should look:

+

dashed edges

+
o--------o    o--------o    o--------o
+|<------>|             |<-->|
+   (chop length)         (chop length / 2)
+
+
+
+
Parameters:
+

spacing (float) – Default is None and it will use self.bounds_diagonal_norm() / 50

+
+
Returns:
+

dashing_edges

+
+
Return type:
+

Edges

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.edges.html b/_generated/gustaf.faces.Faces.edges.html new file mode 100644 index 000000000..70a2455a8 --- /dev/null +++ b/_generated/gustaf.faces.Faces.edges.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.faces.Faces.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.edges#

+
+
+Faces.edges()[source]#
+

Edges from here aren’t main property. So this needs to be computed.

+
+
Parameters:
+

None

+
+
Returns:
+

edges

+
+
Return type:
+

(n, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.faces.html b/_generated/gustaf.faces.Faces.faces.html new file mode 100644 index 000000000..c73d6ecb1 --- /dev/null +++ b/_generated/gustaf.faces.Faces.faces.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.faces.Faces.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.faces#

+
+
+property Faces.faces#
+

Returns faces.

+
+
Parameters:
+

None

+
+
Return type:
+

faces

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.html b/_generated/gustaf.faces.Faces.html new file mode 100644 index 000000000..d3fd781b0 --- /dev/null +++ b/_generated/gustaf.faces.Faces.html @@ -0,0 +1,850 @@ + + + + + + + + + + + gustaf.faces.Faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces#

+
+
+class gustaf.faces.Faces(vertices=None, faces=None, elements=None)[source]#
+

Bases: Edges

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Faces.dashed()

Turn edges into dashed edges(=lines).

Faces.edges()

Edges from here aren't main property.

Faces.single_faces()

Returns indices of very unique faces: faces that appear only once.

Faces.sorted_faces()

Similar to edges_sorted but for faces.

Faces.to_edges([unique])

Returns Edges obj.

Faces.to_subelements([unique])

Returns current elements represented as its boundary element class.

Faces.unique_faces()

Returns a namedtuple of unique faces info.

Faces.update_edges()

Alias to update_elements.

Faces.update_faces(*args, **kwargs)

Alias to update_elements.

Faces.whatareyou(face_obj)

classmethod that tells you if the Faces is tri or quad or invalid kind.

+

Attributes

+ + + + + + + + + + + + + + + + + + + + + +

Faces.BC

Faces.const_edges

Returns non-writeable version of edges.

Faces.const_faces

Returns non-writeable view of faces.

Faces.faces

Returns faces.

Faces.kind

Faces.whatami

Determines whatami.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.kind.html b/_generated/gustaf.faces.Faces.kind.html new file mode 100644 index 000000000..d7f7b4095 --- /dev/null +++ b/_generated/gustaf.faces.Faces.kind.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.faces.Faces.kind — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.kind#

+
+
+Faces.kind = 'face'#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.single_faces.html b/_generated/gustaf.faces.Faces.single_faces.html new file mode 100644 index 000000000..edcd6a091 --- /dev/null +++ b/_generated/gustaf.faces.Faces.single_faces.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.faces.Faces.single_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.single_faces#

+
+
+Faces.single_faces()[source]#
+

Returns indices of very unique faces: faces that appear only once. +For well constructed volumes, this can be considered as surfaces.

+
+
Parameters:
+

None

+
+
Returns:
+

single_faces

+
+
Return type:
+

(m,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.sorted_faces.html b/_generated/gustaf.faces.Faces.sorted_faces.html new file mode 100644 index 000000000..2e76e4acb --- /dev/null +++ b/_generated/gustaf.faces.Faces.sorted_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.faces.Faces.sorted_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.sorted_faces#

+
+
+Faces.sorted_faces()[source]#
+

Similar to edges_sorted but for faces.

+
+
Parameters:
+

None

+
+
Returns:
+

sorted_faces

+
+
Return type:
+

(self.faces.shape) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.to_edges.html b/_generated/gustaf.faces.Faces.to_edges.html new file mode 100644 index 000000000..416752d4a --- /dev/null +++ b/_generated/gustaf.faces.Faces.to_edges.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.faces.Faces.to_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.to_edges#

+
+
+Faces.to_edges(unique=True)[source]#
+

Returns Edges obj.

+
+
Parameters:
+

unique (bool) – Default is True. If True, only takes unique edges.

+
+
Returns:
+

edges

+
+
Return type:
+

Edges

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.to_subelements.html b/_generated/gustaf.faces.Faces.to_subelements.html new file mode 100644 index 000000000..eddcaf7f8 --- /dev/null +++ b/_generated/gustaf.faces.Faces.to_subelements.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.faces.Faces.to_subelements — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.to_subelements#

+
+
+Faces.to_subelements(unique=True)[source]#
+

Returns current elements represented as its boundary element class. +For faces, this is equivalent to to_edges(). +For volumes, to_faces().

+
+
Parameters:
+

unique (bool) – Default is True. If True, only takes unique edges.

+
+
Returns:
+

subelements

+
+
Return type:
+

boundary class

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.unique_faces.html b/_generated/gustaf.faces.Faces.unique_faces.html new file mode 100644 index 000000000..046a2ac28 --- /dev/null +++ b/_generated/gustaf.faces.Faces.unique_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.faces.Faces.unique_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.unique_faces#

+
+
+Faces.unique_faces()[source]#
+

Returns a namedtuple of unique faces info. Similar to unique_edges.

+
+
Parameters:
+

None

+
+
Returns:
+

unique_info – valid attributes are {values, ids, inverse, counts}

+
+
Return type:
+

Unique2DIntegers

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.update_edges.html b/_generated/gustaf.faces.Faces.update_edges.html new file mode 100644 index 000000000..bc7b61eae --- /dev/null +++ b/_generated/gustaf.faces.Faces.update_edges.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.faces.Faces.update_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.update_edges#

+
+
+Faces.update_edges()#
+

Alias to update_elements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.update_faces.html b/_generated/gustaf.faces.Faces.update_faces.html new file mode 100644 index 000000000..2431748ce --- /dev/null +++ b/_generated/gustaf.faces.Faces.update_faces.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.faces.Faces.update_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.update_faces#

+
+
+Faces.update_faces(*args, **kwargs)[source]#
+

Alias to update_elements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.whatami.html b/_generated/gustaf.faces.Faces.whatami.html new file mode 100644 index 000000000..303958a10 --- /dev/null +++ b/_generated/gustaf.faces.Faces.whatami.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.faces.Faces.whatami — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.whatami#

+
+
+property Faces.whatami#
+

Determines whatami.

+
+
Parameters:
+

None

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.Faces.whatareyou.html b/_generated/gustaf.faces.Faces.whatareyou.html new file mode 100644 index 000000000..65d373aae --- /dev/null +++ b/_generated/gustaf.faces.Faces.whatareyou.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.faces.Faces.whatareyou — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.Faces.whatareyou#

+
+
+classmethod Faces.whatareyou(face_obj)[source]#
+

classmethod that tells you if the Faces is tri or quad or invalid +kind.

+
+
Parameters:
+

face_obj (Faces)

+
+
Returns:
+

whatareyou

+
+
Return type:
+

str

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.FacesShowOption.html b/_generated/gustaf.faces.FacesShowOption.html new file mode 100644 index 000000000..8b419bb9f --- /dev/null +++ b/_generated/gustaf.faces.FacesShowOption.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.faces.FacesShowOption — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces.FacesShowOption#

+
+
+class gustaf.faces.FacesShowOption(helpee)[source]#
+

Bases: ShowOption

+

Show options for vertices.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.faces.html b/_generated/gustaf.faces.html new file mode 100644 index 000000000..20f4ace28 --- /dev/null +++ b/_generated/gustaf.faces.html @@ -0,0 +1,786 @@ + + + + + + + + + + + gustaf.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.faces#

+

gustaf/gustaf/faces.py.

+

Classes

+ + + + + + + + + +

Faces([vertices, faces, elements])

FacesShowOption(helpee)

Show options for vertices.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.ComputedData.depends_on.html b/_generated/gustaf.helpers.data.ComputedData.depends_on.html new file mode 100644 index 000000000..b2454331f --- /dev/null +++ b/_generated/gustaf.helpers.data.ComputedData.depends_on.html @@ -0,0 +1,811 @@ + + + + + + + + + + + gustaf.helpers.data.ComputedData.depends_on — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.ComputedData.depends_on#

+
+
+classmethod ComputedData.depends_on(var_names, make_property=False)[source]#
+

Decorator as classmethod.

+

checks if the key should be computed. Two cases, where the answer is +yes:

+
    +
  1. +
    there’s modification on arrays that the key depend on.

    ->erases all other

    +
    +
    +
  2. +
  3. is corresponding value None?

  4. +
+

Supports multi-dependency

+
+
Parameters:
+
    +
  • var_name (list)

  • +
  • make_property

  • +
+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.ComputedData.html b/_generated/gustaf.helpers.data.ComputedData.html new file mode 100644 index 000000000..f5a67a863 --- /dev/null +++ b/_generated/gustaf.helpers.data.ComputedData.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.data.ComputedData — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.ComputedData#

+
+
+class gustaf.helpers.data.ComputedData(helpee, **_kwargs)[source]#
+

Bases: DataHolder

+

Methods

+ + + + + + +

ComputedData.depends_on(var_names[, ...])

Decorator as classmethod.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.ComputedMeshData.html b/_generated/gustaf.helpers.data.ComputedMeshData.html new file mode 100644 index 000000000..4c557faab --- /dev/null +++ b/_generated/gustaf.helpers.data.ComputedMeshData.html @@ -0,0 +1,799 @@ + + + + + + + + + + + gustaf.helpers.data.ComputedMeshData — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.ComputedMeshData#

+
+
+class gustaf.helpers.data.ComputedMeshData(helpee, **_kwargs)[source]#
+

Bases: ComputedData

+

A class to hold computed-mesh-data.

+

Subclassed to keep its own dependency info.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.clear.html b/_generated/gustaf.helpers.data.DataHolder.clear.html new file mode 100644 index 000000000..30f967c83 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.clear.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.clear — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.clear#

+
+
+DataHolder.clear()[source]#
+

Clears saved data by reassigning new dict

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.get.html b/_generated/gustaf.helpers.data.DataHolder.get.html new file mode 100644 index 000000000..ce861c8d5 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.get.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.get — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.get#

+
+
+DataHolder.get(key, default_values=None)[source]#
+

Returns stored item if the key exists. Else, given default value. If +the key exist, default value always exists, since it is initialized +that way.

+
+
Parameters:
+
    +
  • key (str)

  • +
  • default_values (object)

  • +
+
+
Returns:
+

value

+
+
Return type:
+

object

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.html b/_generated/gustaf.helpers.data.DataHolder.html new file mode 100644 index 000000000..aa4179c5a --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.html @@ -0,0 +1,818 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder#

+
+
+class gustaf.helpers.data.DataHolder(helpee)[source]#
+

Bases: HelperBase

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + +

DataHolder.clear()

Clears saved data by reassigning new dict

DataHolder.get(key[, default_values])

Returns stored item if the key exists.

DataHolder.items()

Returns items of data holding dict.

DataHolder.keys()

Returns keys of data holding dict.

DataHolder.pop(key[, default])

Applied pop() to saved data

DataHolder.update(**kwargs)

Updates given kwargs using __setitem__.

DataHolder.values()

Returns values of data holding dict.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.items.html b/_generated/gustaf.helpers.data.DataHolder.items.html new file mode 100644 index 000000000..64534db64 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.items.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.items — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.items#

+
+
+DataHolder.items()[source]#
+

Returns items of data holding dict.

+
+
Returns:
+

values

+
+
Return type:
+

dict_values

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.keys.html b/_generated/gustaf.helpers.data.DataHolder.keys.html new file mode 100644 index 000000000..15e9f629d --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.keys.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.keys — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.keys#

+
+
+DataHolder.keys()[source]#
+

Returns keys of data holding dict.

+
+
Returns:
+

keys

+
+
Return type:
+

dict_keys

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.pop.html b/_generated/gustaf.helpers.data.DataHolder.pop.html new file mode 100644 index 000000000..106eca0c8 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.pop.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.pop — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.pop#

+
+
+DataHolder.pop(key, default=None)[source]#
+

Applied pop() to saved data

+
+
Parameters:
+
    +
  • key (str)

  • +
  • default (object)

  • +
+
+
Returns:
+

value

+
+
Return type:
+

object

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.update.html b/_generated/gustaf.helpers.data.DataHolder.update.html new file mode 100644 index 000000000..c881fa375 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.update.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.update — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.update#

+
+
+DataHolder.update(**kwargs)[source]#
+

Updates given kwargs using __setitem__.

+
+
Parameters:
+

**kwargs (kwargs)

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.DataHolder.values.html b/_generated/gustaf.helpers.data.DataHolder.values.html new file mode 100644 index 000000000..4a2c50349 --- /dev/null +++ b/_generated/gustaf.helpers.data.DataHolder.values.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.data.DataHolder.values — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.DataHolder.values#

+
+
+DataHolder.values()[source]#
+

Returns values of data holding dict.

+
+
Returns:
+

values

+
+
Return type:
+

dict_values

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.TrackedArray.copy.html b/_generated/gustaf.helpers.data.TrackedArray.copy.html new file mode 100644 index 000000000..4bad1e652 --- /dev/null +++ b/_generated/gustaf.helpers.data.TrackedArray.copy.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.data.TrackedArray.copy — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.TrackedArray.copy#

+
+
+TrackedArray.copy(*args, **kwargs)[source]#
+

copy creates regular numpy array

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.TrackedArray.html b/_generated/gustaf.helpers.data.TrackedArray.html new file mode 100644 index 000000000..d2e1a4044 --- /dev/null +++ b/_generated/gustaf.helpers.data.TrackedArray.html @@ -0,0 +1,813 @@ + + + + + + + + + + + gustaf.helpers.data.TrackedArray — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.TrackedArray#

+
+
+class gustaf.helpers.data.TrackedArray[source]#
+

Bases: ndarray

+

numpy array object that keeps mirroring inplace changes to the source. +Meant to help control_points.

+

Methods

+ + + + + + + + + +

TrackedArray.copy(*args, **kwargs)

copy creates regular numpy array

TrackedArray.view(*args, **kwargs)

Set writeable flags to False for the view.

+

Attributes

+ + + + + + +

TrackedArray.modified

Modified flag getter

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.TrackedArray.modified.html b/_generated/gustaf.helpers.data.TrackedArray.modified.html new file mode 100644 index 000000000..7a8969536 --- /dev/null +++ b/_generated/gustaf.helpers.data.TrackedArray.modified.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.data.TrackedArray.modified — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.TrackedArray.modified#

+
+
+property TrackedArray.modified#
+

Modified flag getter

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.TrackedArray.view.html b/_generated/gustaf.helpers.data.TrackedArray.view.html new file mode 100644 index 000000000..9073af7e7 --- /dev/null +++ b/_generated/gustaf.helpers.data.TrackedArray.view.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.data.TrackedArray.view — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.TrackedArray.view#

+
+
+TrackedArray.view(*args, **kwargs)[source]#
+

Set writeable flags to False for the view.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DFloats.html b/_generated/gustaf.helpers.data.Unique2DFloats.html new file mode 100644 index 000000000..d5688b2d4 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DFloats.html @@ -0,0 +1,818 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DFloats — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DFloats#

+
+
+class gustaf.helpers.data.Unique2DFloats(values, ids, inverse, intersection)#
+

Bases: tuple

+

namedtuple to hold unique information of float type arrays. +Note that for float types, “close enough” might be a better name than unique. +This way, all tracked arrays, as long as they are 2D, have a dot separated +syntax to access unique info. For example, mesh.unique_vertices.ids.

+

Methods

+ + + +
+

Attributes

+ + + + + + + + + + + + + + + +

Unique2DFloats.ids

(n, d) np.ndarray Field number 1

Unique2DFloats.intersection

(m) list of list given original array's index, returns overlapping arrays, including itself.

Unique2DFloats.inverse

(n, d) np.ndarray Field number 2

Unique2DFloats.values

(n, d) np.ndarray Field number 0

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DFloats.ids.html b/_generated/gustaf.helpers.data.Unique2DFloats.ids.html new file mode 100644 index 000000000..3dddc6ee1 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DFloats.ids.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DFloats.ids — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DFloats.ids#

+
+
+Unique2DFloats.ids#
+

(n, d) np.ndarray +Field number 1

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DFloats.intersection.html b/_generated/gustaf.helpers.data.Unique2DFloats.intersection.html new file mode 100644 index 000000000..8552a2a49 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DFloats.intersection.html @@ -0,0 +1,794 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DFloats.intersection — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DFloats.intersection#

+
+
+Unique2DFloats.intersection#
+

(m) list of list +given original array’s index, returns overlapping arrays, including itself. +Field number 3

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DFloats.inverse.html b/_generated/gustaf.helpers.data.Unique2DFloats.inverse.html new file mode 100644 index 000000000..812365084 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DFloats.inverse.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DFloats.inverse — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DFloats.inverse#

+
+
+Unique2DFloats.inverse#
+

(n, d) np.ndarray +Field number 2

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DFloats.values.html b/_generated/gustaf.helpers.data.Unique2DFloats.values.html new file mode 100644 index 000000000..75f22a677 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DFloats.values.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DFloats.values — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DFloats.values#

+
+
+Unique2DFloats.values#
+

(n, d) np.ndarray +Field number 0

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DIntegers.counts.html b/_generated/gustaf.helpers.data.Unique2DIntegers.counts.html new file mode 100644 index 000000000..ef027166e --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DIntegers.counts.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DIntegers.counts — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DIntegers.counts#

+
+
+Unique2DIntegers.counts#
+

(n) np.ndarray +Field number 3

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DIntegers.html b/_generated/gustaf.helpers.data.Unique2DIntegers.html new file mode 100644 index 000000000..09d376b78 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DIntegers.html @@ -0,0 +1,816 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DIntegers — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DIntegers#

+
+
+class gustaf.helpers.data.Unique2DIntegers(values, ids, inverse, counts)#
+

Bases: tuple

+

namedtuple to hold unique information of integer type arrays. +Similar approach to Unique2DFloats.

+

Methods

+ + + +
+

Attributes

+ + + + + + + + + + + + + + + +

Unique2DIntegers.counts

(n) np.ndarray Field number 3

Unique2DIntegers.ids

(n) np.ndarray Field number 1

Unique2DIntegers.inverse

(m) np.ndarray Field number 2

Unique2DIntegers.values

(n, d) np.ndarray Field number 0

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DIntegers.ids.html b/_generated/gustaf.helpers.data.Unique2DIntegers.ids.html new file mode 100644 index 000000000..5f92f024c --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DIntegers.ids.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DIntegers.ids — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DIntegers.ids#

+
+
+Unique2DIntegers.ids#
+

(n) np.ndarray +Field number 1

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.html b/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.html new file mode 100644 index 000000000..dd0417566 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DIntegers.inverse — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DIntegers.inverse#

+
+
+Unique2DIntegers.inverse#
+

(m) np.ndarray +Field number 2

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.Unique2DIntegers.values.html b/_generated/gustaf.helpers.data.Unique2DIntegers.values.html new file mode 100644 index 000000000..819718b57 --- /dev/null +++ b/_generated/gustaf.helpers.data.Unique2DIntegers.values.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.data.Unique2DIntegers.values — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.Unique2DIntegers.values#

+
+
+Unique2DIntegers.values#
+

(n, d) np.ndarray +Field number 0

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.VertexData.as_arrow.html b/_generated/gustaf.helpers.data.VertexData.as_arrow.html new file mode 100644 index 000000000..ee15c597f --- /dev/null +++ b/_generated/gustaf.helpers.data.VertexData.as_arrow.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.helpers.data.VertexData.as_arrow — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.VertexData.as_arrow#

+
+
+VertexData.as_arrow(key, default=None, raise_=True)[source]#
+

Returns an array as is, only if it is showable as arrow.

+
+
Parameters:
+
    +
  • key (str)

  • +
  • default (object)

  • +
  • raise (bool)

  • +
+
+
Returns:
+

data

+
+
Return type:
+

(n, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.VertexData.as_scalar.html b/_generated/gustaf.helpers.data.VertexData.as_scalar.html new file mode 100644 index 000000000..1f37a729b --- /dev/null +++ b/_generated/gustaf.helpers.data.VertexData.as_scalar.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.helpers.data.VertexData.as_scalar — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.VertexData.as_scalar#

+
+
+VertexData.as_scalar(key, default=None)[source]#
+

Returns scalar version of requested data. If it is already a scalar, +will return as is. Else, will return a norm. using np.linalg.norm().

+
+
Parameters:
+
    +
  • key (str)

  • +
  • default (object)

  • +
+
+
Returns:
+

data_as_scalar

+
+
Return type:
+

(n, 1) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.VertexData.html b/_generated/gustaf.helpers.data.VertexData.html new file mode 100644 index 000000000..9ca6c1b93 --- /dev/null +++ b/_generated/gustaf.helpers.data.VertexData.html @@ -0,0 +1,809 @@ + + + + + + + + + + + gustaf.helpers.data.VertexData — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.VertexData#

+
+
+class gustaf.helpers.data.VertexData(helpee)[source]#
+

Bases: DataHolder

+

Minimal manager for vertex data. Checks input array size, transforms +data on request. __setitem__ and __getitem__ will perform length checks. +key(), values(), items(), and get() will return whatever is currently +stored.

+

gustaf supports two kinds of data representation: scalar-data with cmap +and vector-data with arrows.

+

Methods

+ + + + + + + + + +

VertexData.as_arrow(key[, default, raise_])

Returns an array as is, only if it is showable as arrow.

VertexData.as_scalar(key[, default])

Returns scalar version of requested data.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.html b/_generated/gustaf.helpers.data.html new file mode 100644 index 000000000..828807408 --- /dev/null +++ b/_generated/gustaf.helpers.data.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.helpers.data — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data#

+

gustaf/gustaf/helpers/data.py.

+

Helps helpee to manage data. Some useful data structures.

+

Functions

+ + + + + + +

make_tracked_array(array[, dtype, copy])

Motivated by nice implementations of trimesh (see LICENSE.txt).

+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + +

ComputedData(helpee, **_kwargs)

ComputedMeshData(helpee, **_kwargs)

A class to hold computed-mesh-data.

DataHolder(helpee)

TrackedArray

numpy array object that keeps mirroring inplace changes to the source.

Unique2DFloats(values, ids, inverse, ...)

namedtuple to hold unique information of float type arrays.

Unique2DIntegers(values, ids, inverse, counts)

namedtuple to hold unique information of integer type arrays.

VertexData(helpee)

Minimal manager for vertex data.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.data.make_tracked_array.html b/_generated/gustaf.helpers.data.make_tracked_array.html new file mode 100644 index 000000000..49d6c0bfd --- /dev/null +++ b/_generated/gustaf.helpers.data.make_tracked_array.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.helpers.data.make_tracked_array — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.data.make_tracked_array#

+
+
+gustaf.helpers.data.make_tracked_array(array, dtype=None, copy=True)[source]#
+

Motivated by nice implementations of trimesh (see LICENSE.txt). +https://github.com/mikedh/trimesh/blob/main/trimesh/caching.py.

+

Factory-like wrapper function for TrackedArray. +If you want to use TrackedArray, it is recommended to use this function.

+
+
Parameters:
+
    +
  • array (array- like object) – To be turned into a TrackedArray

  • +
  • dtype (np.dtype) – Which dtype to use for the array

  • +
  • copy (bool) – Default is True. copy if True.

  • +
+
+
Returns:
+

tracked – Contains input array data

+
+
Return type:
+

TrackedArray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.html b/_generated/gustaf.helpers.html new file mode 100644 index 000000000..3e3bc621e --- /dev/null +++ b/_generated/gustaf.helpers.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.html b/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.html new file mode 100644 index 000000000..5877f8d3e --- /dev/null +++ b/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.notebook.K3DPlotterN.clear — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.K3DPlotterN.clear#

+
+
+K3DPlotterN.clear(*args, **kwargs)[source]#
+

Clear the plotters.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.K3DPlotterN.close.html b/_generated/gustaf.helpers.notebook.K3DPlotterN.close.html new file mode 100644 index 000000000..e08a2d48c --- /dev/null +++ b/_generated/gustaf.helpers.notebook.K3DPlotterN.close.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.helpers.notebook.K3DPlotterN.close — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.K3DPlotterN.close#

+
+
+K3DPlotterN.close()[source]#
+

Closes all vedo.Plotters

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.K3DPlotterN.display.html b/_generated/gustaf.helpers.notebook.K3DPlotterN.display.html new file mode 100644 index 000000000..371e17890 --- /dev/null +++ b/_generated/gustaf.helpers.notebook.K3DPlotterN.display.html @@ -0,0 +1,794 @@ + + + + + + + + + + + gustaf.helpers.notebook.K3DPlotterN.display — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.K3DPlotterN.display#

+
+
+K3DPlotterN.display(close=True)[source]#
+

Display the plotter.

+

This is needed in case the plotter is the last thing in a cell. In that +case the IPython will try to call this function to display this.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.K3DPlotterN.html b/_generated/gustaf.helpers.notebook.K3DPlotterN.html new file mode 100644 index 000000000..804d7b076 --- /dev/null +++ b/_generated/gustaf.helpers.notebook.K3DPlotterN.html @@ -0,0 +1,817 @@ + + + + + + + + + + + gustaf.helpers.notebook.K3DPlotterN — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.K3DPlotterN#

+
+
+class gustaf.helpers.notebook.K3DPlotterN(**kwargs: Any)[source]#
+

Bases: GridspecLayout, GustafBase

+

Helper to plot in notebooks with k3d.

+

Sets up K3D plotter especially if multiple plots are to be shown in the +notebook.

+

Methods

+ + + + + + + + + + + + + + + +

K3DPlotterN.clear(*args, **kwargs)

Clear the plotters.

K3DPlotterN.close()

Closes all vedo.Plotters

K3DPlotterN.display([close])

Display the plotter.

K3DPlotterN.show(list_of_showables, at, ...)

Add the showables to the renderer at the given location.

+

Attributes

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.K3DPlotterN.show.html b/_generated/gustaf.helpers.notebook.K3DPlotterN.show.html new file mode 100644 index 000000000..4f774b8dd --- /dev/null +++ b/_generated/gustaf.helpers.notebook.K3DPlotterN.show.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.notebook.K3DPlotterN.show — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.K3DPlotterN.show#

+
+
+K3DPlotterN.show(list_of_showables, at, interactive, camera, axes, *args, **kwargs)[source]#
+

Add the showables to the renderer at the given location.

+
+
Parameters:
+
    +
  • list_of_showables (Any)

  • +
  • at (int) – Render id.

  • +
  • interactive (bool) – See vedo.Plotter.show for details.

  • +
  • camera (Any) – See vedo.Plotter.show for details.

  • +
  • axes (bool) – Add axes to the plot. Will also cast int to bool.

  • +
+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.get_shape.html b/_generated/gustaf.helpers.notebook.get_shape.html new file mode 100644 index 000000000..d890e77b4 --- /dev/null +++ b/_generated/gustaf.helpers.notebook.get_shape.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.helpers.notebook.get_shape — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook.get_shape#

+
+
+gustaf.helpers.notebook.get_shape(N, x, y)[source]#
+

Taken verbatim from vedo plotter:show function.

+
+
Parameters:
+
    +
  • N (_type_) – _description_

  • +
  • x (_type_) – _description_

  • +
  • y (_type_) – _description_

  • +
+
+
Returns:
+

_description_

+
+
Return type:
+

_type_

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.notebook.html b/_generated/gustaf.helpers.notebook.html new file mode 100644 index 000000000..57eb0c4ec --- /dev/null +++ b/_generated/gustaf.helpers.notebook.html @@ -0,0 +1,795 @@ + + + + + + + + + + + gustaf.helpers.notebook — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.notebook#

+

gustaf/gustaf/helpers/notebook.py.

+

Enables the plotting in ipynb with k3d.

+

There are no import guards since they are in the place where this module is +imported. This should be enough since I do not think that this module +will/should be used outside this place.

+

Functions

+ + + + + + +

get_shape(N, x, y)

Taken verbatim from vedo plotter:show function.

+

Classes

+ + + + + + +

K3DPlotterN(**kwargs)

Helper to plot in notebooks with k3d.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.allowed_types.html b/_generated/gustaf.helpers.options.Option.allowed_types.html new file mode 100644 index 000000000..1930ff3fe --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.allowed_types.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.Option.allowed_types — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option.allowed_types#

+
+
+Option.allowed_types#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.backends.html b/_generated/gustaf.helpers.options.Option.backends.html new file mode 100644 index 000000000..edfe9ba70 --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.backends.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.Option.backends — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option.backends#

+
+
+Option.backends#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.default.html b/_generated/gustaf.helpers.options.Option.default.html new file mode 100644 index 000000000..dedd2da54 --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.default.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.Option.default — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option.default#

+
+
+Option.default#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.description.html b/_generated/gustaf.helpers.options.Option.description.html new file mode 100644 index 000000000..3247928f2 --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.description.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.Option.description — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option.description#

+
+
+Option.description#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.html b/_generated/gustaf.helpers.options.Option.html new file mode 100644 index 000000000..ac3a97120 --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.html @@ -0,0 +1,829 @@ + + + + + + + + + + + gustaf.helpers.options.Option — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option#

+
+
+class gustaf.helpers.options.Option(backends, key, description, allowed_types, default=None)[source]#
+

Bases: object

+

Minimal Class to hold each options. Mainly to replace nested dict.

+
+
Parameters:
+
    +
  • backends (set) – set of strings.

  • +
  • key (str)

  • +
  • description (str)

  • +
  • allowed_types (set) – set of types

  • +
  • default (one of allwed_types) – Optional. Default is None

  • +
+
+
+

Methods

+ + + +
+

Attributes

+ + + + + + + + + + + + + + + + + + +

Option.backends

Option.key

Option.description

Option.allowed_types

Option.default

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.Option.key.html b/_generated/gustaf.helpers.options.Option.key.html new file mode 100644 index 000000000..f09537604 --- /dev/null +++ b/_generated/gustaf.helpers.options.Option.key.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.Option.key — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.Option.key#

+
+
+Option.key#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.SetDefault.default.html b/_generated/gustaf.helpers.options.SetDefault.default.html new file mode 100644 index 000000000..6659f563e --- /dev/null +++ b/_generated/gustaf.helpers.options.SetDefault.default.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.SetDefault.default — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.SetDefault.default#

+
+
+SetDefault.default#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.SetDefault.html b/_generated/gustaf.helpers.options.SetDefault.html new file mode 100644 index 000000000..0c56704c8 --- /dev/null +++ b/_generated/gustaf.helpers.options.SetDefault.html @@ -0,0 +1,809 @@ + + + + + + + + + + + gustaf.helpers.options.SetDefault — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.SetDefault#

+
+
+class gustaf.helpers.options.SetDefault(key, default)[source]#
+

Bases: object

+

Default setter object. Can use as argument in make_valid_options

+

Methods

+ + + +
+

Attributes

+ + + + + + + + + +

SetDefault.key

SetDefault.default

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.SetDefault.key.html b/_generated/gustaf.helpers.options.SetDefault.key.html new file mode 100644 index 000000000..680f4924c --- /dev/null +++ b/_generated/gustaf.helpers.options.SetDefault.key.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.helpers.options.SetDefault.key — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.SetDefault.key#

+
+
+SetDefault.key#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.clear.html b/_generated/gustaf.helpers.options.ShowOption.clear.html new file mode 100644 index 000000000..104326da0 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.clear.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.clear — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.clear#

+
+
+ShowOption.clear()[source]#
+

Clears all the options.

+
+
Parameters:
+

None

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.html b/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.html new file mode 100644 index 000000000..a7c196ab6 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.copy_valid_options — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.copy_valid_options#

+
+
+ShowOption.copy_valid_options(copy_to, keys=None)[source]#
+

Copies valid option to other show_option. Simply iterates and tries.

+
+
Parameters:
+
    +
  • copy_to (ShowOption)

  • +
  • keys (tuple or list) – Can specify keys

  • +
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.get.html b/_generated/gustaf.helpers.options.ShowOption.get.html new file mode 100644 index 000000000..7c1e0bd1f --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.get.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.get — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.get#

+
+
+ShowOption.get(key, default=None)[source]#
+

Gets value from key and default. Similar to dict.get(), +but this is always safe, as it will always return None

+
+
Parameters:
+
    +
  • key (stir)

  • +
  • default (object)

  • +
+
+
Returns:
+

values

+
+
Return type:
+

object

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.html b/_generated/gustaf.helpers.options.ShowOption.html new file mode 100644 index 000000000..7d97d3d16 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.html @@ -0,0 +1,830 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption#

+
+
+class gustaf.helpers.options.ShowOption(helpee)[source]#
+

Bases: HelperBase

+

Behaves similar to dict, but will only accept a set of options that’s +applicable to the helpee class. Intended use is to create a +subclass that would define valid options for helpee. +Options should be described by Option object. +Helps all the way up to initializing backend showables up to their backend +specific common routines. ShowOption and ShowManager in a sense.

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

ShowOption.clear()

Clears all the options.

ShowOption.copy_valid_options(copy_to[, keys])

Copies valid option to other show_option.

ShowOption.get(key[, default])

Gets value from key and default.

ShowOption.items()

Registered option items.

ShowOption.keys()

Registered option keys.

ShowOption.pop(*args, **kwargs)

Calls pop() on current options

ShowOption.update(**kwargs)

Calls __setitem__ iteratively for validity check.

ShowOption.valid_keys()

Returns valid keys.

ShowOption.values()

Registered option values.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.items.html b/_generated/gustaf.helpers.options.ShowOption.items.html new file mode 100644 index 000000000..6db40a098 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.items.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.items — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.items#

+
+
+ShowOption.items()[source]#
+

Registered option items.

+
+
Parameters:
+

None

+
+
Returns:
+

items

+
+
Return type:
+

dict_items

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.keys.html b/_generated/gustaf.helpers.options.ShowOption.keys.html new file mode 100644 index 000000000..bd93b77ef --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.keys.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.keys — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.keys#

+
+
+ShowOption.keys()[source]#
+

Registered option keys.

+
+
Parameters:
+

None

+
+
Returns:
+

keys

+
+
Return type:
+

dict_keys

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.pop.html b/_generated/gustaf.helpers.options.ShowOption.pop.html new file mode 100644 index 000000000..9694f5aa9 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.pop.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.pop — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.pop#

+
+
+ShowOption.pop(*args, **kwargs)[source]#
+

Calls pop() on current options

+
+
Parameters:
+

None

+
+
Returns:
+

value

+
+
Return type:
+

object

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.update.html b/_generated/gustaf.helpers.options.ShowOption.update.html new file mode 100644 index 000000000..782fdb975 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.update.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.update — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.update#

+
+
+ShowOption.update(**kwargs)[source]#
+

Calls __setitem__ iteratively for validity check.

+
+
Parameters:
+

**kwargs (kwargs)

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.valid_keys.html b/_generated/gustaf.helpers.options.ShowOption.valid_keys.html new file mode 100644 index 000000000..76be25128 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.valid_keys.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.valid_keys — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.valid_keys#

+
+
+ShowOption.valid_keys()[source]#
+

Returns valid keys.

+
+
Parameters:
+

None

+
+
Returns:
+

valid_keys

+
+
Return type:
+

dict_keys

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.ShowOption.values.html b/_generated/gustaf.helpers.options.ShowOption.values.html new file mode 100644 index 000000000..9ba548fc1 --- /dev/null +++ b/_generated/gustaf.helpers.options.ShowOption.values.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.ShowOption.values — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.ShowOption.values#

+
+
+ShowOption.values()[source]#
+

Registered option values.

+
+
Parameters:
+

None

+
+
Returns:
+

keys

+
+
Return type:
+

dict_values

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.html b/_generated/gustaf.helpers.options.html new file mode 100644 index 000000000..6dac0c106 --- /dev/null +++ b/_generated/gustaf.helpers.options.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.helpers.options — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options#

+

gustaf/gustaf/helpers/options.py

+

Classes to help organize options.

+

Functions

+ + + + + + +

make_valid_options(*options)

Forms valid options.

+

Classes

+ + + + + + + + + + + + +

Option(backends, key, description, allowed_types)

Minimal Class to hold each options.

SetDefault(key, default)

Default setter object.

ShowOption(helpee)

Behaves similar to dict, but will only accept a set of options that's applicable to the helpee class.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.options.make_valid_options.html b/_generated/gustaf.helpers.options.make_valid_options.html new file mode 100644 index 000000000..d0b9cabb3 --- /dev/null +++ b/_generated/gustaf.helpers.options.make_valid_options.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.helpers.options.make_valid_options — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.options.make_valid_options#

+
+
+gustaf.helpers.options.make_valid_options(*options)[source]#
+

Forms valid options. Should run only once during module loading.

+
+
Parameters:
+

*options (Option)

+
+
Returns:
+

valid_options

+
+
Return type:
+

dict()

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.html b/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.html new file mode 100644 index 000000000..122aaba1d --- /dev/null +++ b/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.html @@ -0,0 +1,802 @@ + + + + + + + + + + + gustaf.helpers.raise_if.ModuleImportRaiser — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.raise_if.ModuleImportRaiser#

+
+
+class gustaf.helpers.raise_if.ModuleImportRaiser(lib_name: str, error_message: str | None = None)[source]#
+

Bases: object

+

Mock imports optional modules if they are not installed.

+

Class used to have better import error handling in the case that a +package package is not installed. This is necessary due to that some +packages are not a dependency of gustaf, but some parts require +them to function. Examples are splinepy and vedo.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.raise_if.html b/_generated/gustaf.helpers.raise_if.html new file mode 100644 index 000000000..ba870e167 --- /dev/null +++ b/_generated/gustaf.helpers.raise_if.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.helpers.raise_if — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.raise_if#

+

gustaf/gustaf/helpers/raise_if.py.

+

Collection of wrapper functions/classes that raises Error with certain +behavior

+

Functions

+ + + + + + +

invalid_inherited_attr(attr_name, qualname)

Returns a function that would behave the same as given function, but would raise AttributeError.

+

Classes

+ + + + + + +

ModuleImportRaiser(lib_name[, error_message])

Mock imports optional modules if they are not installed.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.html b/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.html new file mode 100644 index 000000000..4d597bb0e --- /dev/null +++ b/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.helpers.raise_if.invalid_inherited_attr — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.helpers.raise_if.invalid_inherited_attr#

+
+
+gustaf.helpers.raise_if.invalid_inherited_attr(attr_name, qualname, property_=False)[source]#
+

Returns a function that would behave the same as given function, but +would raise AttributeError. This needs to be defined in class level.

+
+
Parameters:
+
    +
  • func ((function)) – _description_

  • +
  • qualname ((class)) – _description_

  • +
  • property ((bool, optional)) – is this function a property?. Defaults to False.

  • +
+
+
Returns:
+

raiser – behaves same as func if property_ is correctly defined

+
+
Return type:
+

function

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.html b/_generated/gustaf.html new file mode 100644 index 000000000..2c539aa5f --- /dev/null +++ b/_generated/gustaf.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.default.html b/_generated/gustaf.io.default.html new file mode 100644 index 000000000..84a877015 --- /dev/null +++ b/_generated/gustaf.io.default.html @@ -0,0 +1,782 @@ + + + + + + + + + + + gustaf.io.default — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.default#

+

Functions

+ + + + + + +

load(fname)

Load function for all supported file formats.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.default.load.html b/_generated/gustaf.io.default.load.html new file mode 100644 index 000000000..b4a4846f2 --- /dev/null +++ b/_generated/gustaf.io.default.load.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.io.default.load — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.default.load#

+
+
+gustaf.io.default.load(fname)[source]#
+

Load function for all supported file formats.

+

This function tries to guess the correct io module for the given file.

+
+
Parameters:
+

fname (Union[str, pathlib.Path]) – Name of the file to be loaded.

+
+
Returns:
+

Loaded mesh.

+
+
Return type:
+

MESH_TYPES

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.html b/_generated/gustaf.io.html new file mode 100644 index 000000000..482998d40 --- /dev/null +++ b/_generated/gustaf.io.html @@ -0,0 +1,801 @@ + + + + + + + + + + + gustaf.io — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.ioutils.abs_fname.html b/_generated/gustaf.io.ioutils.abs_fname.html new file mode 100644 index 000000000..13a30db02 --- /dev/null +++ b/_generated/gustaf.io.ioutils.abs_fname.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.io.ioutils.abs_fname — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.ioutils.abs_fname#

+
+
+gustaf.io.ioutils.abs_fname(fname)[source]#
+

Checks if fname is abs. If not, returns abs. Tilde safe.

+
+
Parameters:
+

fname (str)

+
+
Returns:
+

abs_fname – Maybe same as fname, maybe not.

+
+
Return type:
+

str

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.ioutils.check_and_makedirs.html b/_generated/gustaf.io.ioutils.check_and_makedirs.html new file mode 100644 index 000000000..4f04438fc --- /dev/null +++ b/_generated/gustaf.io.ioutils.check_and_makedirs.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.io.ioutils.check_and_makedirs — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.ioutils.check_and_makedirs#

+
+
+gustaf.io.ioutils.check_and_makedirs(fname)[source]#
+

Checks if the directories of the path exists. If not, makedirs!

+
+
Parameters:
+

fname (str)

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.ioutils.html b/_generated/gustaf.io.ioutils.html new file mode 100644 index 000000000..f27609ea8 --- /dev/null +++ b/_generated/gustaf.io.ioutils.html @@ -0,0 +1,787 @@ + + + + + + + + + + + gustaf.io.ioutils — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.ioutils#

+

gustaf/gustaf/io/ioutils.py.

+

utils for lord load and his expected expertise, export.

+

Functions

+ + + + + + + + + +

abs_fname(fname)

Checks if fname is abs.

check_and_makedirs(fname)

Checks if the directories of the path exists.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.meshio.export.html b/_generated/gustaf.io.meshio.export.html new file mode 100644 index 000000000..66a5c3385 --- /dev/null +++ b/_generated/gustaf.io.meshio.export.html @@ -0,0 +1,854 @@ + + + + + + + + + + + gustaf.io.meshio.export — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.meshio.export#

+
+
+gustaf.io.meshio.export(fname, mesh, submeshes=None, **kwargs)[source]#
+

Export mesh elements and vertex data into meshio and use its write +function. The definition of submeshes with identical vertex coordinates +is possible. In that case vertex numbering and data from the main mesh +are used. For more export options, refer to meshio’s documentation +nschloe/meshio .

+
import gustaf
+
+# define coordinates
+v = np.array(
+    [
+        [0.0, 0.0, 0.0],
+        [1.0, 0.0, 0.0],
+        [0.0, 1.0, 0.0],
+        [1.0, 1.0, 0.0],
+        [0.0, 0.0, 1.0],
+        [1.0, 0.0, 1.0],
+        [0.0, 1.0, 1.0],
+        [1.0, 1.0, 1.0],
+    ]
+)
+# define triangle connectivity
+tf = np.array(
+    [
+        [1, 0, 2],
+        [0, 1, 5],
+        [3, 2, 6],
+        [2, 0, 4],
+        [4, 5, 7],
+        [2, 3, 1],
+        [7, 5, 1],
+        [6, 7, 3],
+        [4, 6, 2],
+        [7, 6, 4],
+    ]
+)
+# init tri faces
+mesh = gus.Faces(
+    vertices=v,
+    faces=tf,
+)
+gustaf.io.meshio.export(mesh, "tri-mesh.stl")
+
+
+
+
Parameters:
+
    +
  • fname (Union[str, pathlib.Path]) – File to save the mesh in.

  • +
  • mesh (Edges, Faces or Volumes) – Input mesh

  • +
  • submeshes (Iterable) – Submeshes where the vertices are identical to the main mesh. The element +type can be identical to mesh.elements or lower-dimensional (e.g. +boundary elements).

  • +
  • **kwargs (Any) – Any additional argument will be passed to the respective meshio write +function. See meshio docs for more information

  • +
+
+
Raises:
+
    +
  • NotImplementedError: – For mesh types that are not implemented.

  • +
  • ValueError: – Raises a value error, if the vertices indexed in a subset are not + present in the main mesh.

  • +
+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.meshio.html b/_generated/gustaf.io.meshio.html new file mode 100644 index 000000000..faca1bff6 --- /dev/null +++ b/_generated/gustaf.io.meshio.html @@ -0,0 +1,788 @@ + + + + + + + + + + + gustaf.io.meshio — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.meshio#

+

Import a meshio based mesh,

+

Export can only happen after it is possible to save and define boundaries in +gustaf.

+

Functions

+ + + + + + + + + +

export(fname, mesh[, submeshes])

Export mesh elements and vertex data into meshio and use its write function.

load(fname)

Load mesh in meshio format.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.meshio.load.html b/_generated/gustaf.io.meshio.load.html new file mode 100644 index 000000000..5e77153c6 --- /dev/null +++ b/_generated/gustaf.io.meshio.load.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.io.meshio.load — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.meshio.load#

+
+
+gustaf.io.meshio.load(fname)[source]#
+

Load mesh in meshio format. Loads vertices and their connectivity. +Currently cannot process boundary.

+
+

Note

+

This is more or less a direct copy from the original gustav implementation. +A lot of the meshio information are lost. When boundaries and multi-patch +definitions are added this needs to be revisited and extended.

+
+
+
Parameters:
+

fname (str | pathlib.Path)

+
+
Return type:
+

MESH_TYPES | List[MESH_TYPES]

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mfem.export.html b/_generated/gustaf.io.mfem.export.html new file mode 100644 index 000000000..3c471d436 --- /dev/null +++ b/_generated/gustaf.io.mfem.export.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.io.mfem.export — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mfem.export#

+
+
+gustaf.io.mfem.export(fname, mesh)[source]#
+

Export mesh in MFEM format. Supports 2D triangle and quadrilateral +meshes. Does not support different element attributes or difference in +vertex dimension and mesh dimension.

+
+
Parameters:
+
    +
  • fname (str)

  • +
  • mesh (Faces)

  • +
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mfem.html b/_generated/gustaf.io.mfem.html new file mode 100644 index 000000000..acfd5de6b --- /dev/null +++ b/_generated/gustaf.io.mfem.html @@ -0,0 +1,789 @@ + + + + + + + + + + + gustaf.io.mfem — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mfem#

+

gustaf/gustaf/io/mfem.py.

+

io functions for mfem. Supports simple linear elements (straight meshes) +For detailed information, see: https://mfem.org/mesh- +format-v1.0/#straight-meshes

+

Functions

+ + + + + + + + + +

export(fname, mesh)

Export mesh in MFEM format.

load(fname)

Load mesh in MFEM format.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mfem.load.html b/_generated/gustaf.io.mfem.load.html new file mode 100644 index 000000000..ab3576613 --- /dev/null +++ b/_generated/gustaf.io.mfem.load.html @@ -0,0 +1,801 @@ + + + + + + + + + + + gustaf.io.mfem.load — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mfem.load#

+
+
+gustaf.io.mfem.load(fname)[source]#
+

Load mesh in MFEM format. Loads vertices and their connectivity. +Currently cannot process boundary.

+
+
Parameters:
+

fname (str)

+
+
Return type:
+

mesh

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mixd.export.html b/_generated/gustaf.io.mixd.export.html new file mode 100644 index 000000000..9184ce56e --- /dev/null +++ b/_generated/gustaf.io.mixd.export.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.io.mixd.export — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mixd.export#

+
+
+gustaf.io.mixd.export(fname, mesh, space_time=False, dual=False)[source]#
+

Export in mixd format. Supports triangle, quadrilateral, tetrahedron, +and hexahedron semi-discrete and (flat) space-time mesh output.

+
+
Parameters:
+
    +
  • mesh (Faces or Volumes)

  • +
  • fname (str)

  • +
  • space_time (bool) – Export Mesh as Space-Time Slab for discontinuous space-time

  • +
  • dual (bool) – Includes dual-subelement information.

  • +
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mixd.html b/_generated/gustaf.io.mixd.html new file mode 100644 index 000000000..c475c025c --- /dev/null +++ b/_generated/gustaf.io.mixd.html @@ -0,0 +1,790 @@ + + + + + + + + + + + gustaf.io.mixd — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mixd#

+

gustaf/gustaf/io/mixd.py.

+

io functions for mixd.

+

Functions

+ + + + + + + + + + + + +

export(fname, mesh[, space_time, dual])

Export in mixd format.

load([simplex, volume, fname, mxyz, mien, mrng])

mixd load.

make_mrng(mesh)

Builds and return mrng array based on mesh.BC Supports Faces and Volumes.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mixd.load.html b/_generated/gustaf.io.mixd.load.html new file mode 100644 index 000000000..f019ed542 --- /dev/null +++ b/_generated/gustaf.io.mixd.load.html @@ -0,0 +1,814 @@ + + + + + + + + + + + gustaf.io.mixd.load — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mixd.load#

+
+
+gustaf.io.mixd.load(simplex=True, volume=False, fname=None, mxyz=None, mien=None, mrng=None)[source]#
+

mixd load. To avoid reading minf, all the crucial info can be given as +params. Default input will try to import mxyz, mien, mrng from +current location and assumes mesh is 2D triangle.

+
+
Parameters:
+
    +
  • simplex (bool) – Default is True. Is it triangle based?

  • +
  • volume (bool) – Default is False. Is it 3D?

  • +
  • fname (str) – Default is None. Specify your mixd file names with “.xns” postfix. +Ex) “gustaf.xns” will try to load “gustaf.mxyz”, “gustaf.mien”, +and “gustaf.mrng”

  • +
  • mxyz (str) – Default is None.

  • +
  • mien (str) – Default is None.

  • +
  • mrng (str) – Default is None. This is optional.

  • +
+
+
Returns:
+

mesh

+
+
Return type:
+

Faces or Volumes

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.mixd.make_mrng.html b/_generated/gustaf.io.mixd.make_mrng.html new file mode 100644 index 000000000..6d98a6798 --- /dev/null +++ b/_generated/gustaf.io.mixd.make_mrng.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.io.mixd.make_mrng — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.mixd.make_mrng#

+
+
+gustaf.io.mixd.make_mrng(mesh)[source]#
+

Builds and return mrng array based on mesh.BC +Supports Faces and Volumes.

+
+
Parameters:
+

mesh (Faces or Volumes) – Number of participating elements

+
+
Returns:
+

boundaries – The mrng-array.

+
+
Return type:
+

ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.nutils.export.html b/_generated/gustaf.io.nutils.export.html new file mode 100644 index 000000000..2bd4935e8 --- /dev/null +++ b/_generated/gustaf.io.nutils.export.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.io.nutils.export — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.nutils.export#

+
+
+gustaf.io.nutils.export(fname, mesh)[source]#
+

Export in Nutils format. Files are saved as np.savez(). +Supports triangle,and tetrahedron Meshes.

+
+
Parameters:
+
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.nutils.html b/_generated/gustaf.io.nutils.html new file mode 100644 index 000000000..89978e120 --- /dev/null +++ b/_generated/gustaf.io.nutils.html @@ -0,0 +1,790 @@ + + + + + + + + + + + gustaf.io.nutils — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.nutils#

+

gustaf/gustaf/io/nutils.py.

+

io functions for nutils.

+

Functions

+ + + + + + + + + + + + +

export(fname, mesh)

Export in Nutils format.

load(fname)

nutils load.

to_nutils_simplex(mesh)

Converts a Gustaf_Mesh to a Dictionary, which can be interpreted by nutils.mesh.simplex(**to_nutils_simplex(mesh)).

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.nutils.load.html b/_generated/gustaf.io.nutils.load.html new file mode 100644 index 000000000..6e08205fe --- /dev/null +++ b/_generated/gustaf.io.nutils.load.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.io.nutils.load — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.nutils.load#

+
+
+gustaf.io.nutils.load(fname)[source]#
+

nutils load. +Loads a nutils (np.savez) file and returns a Gustaf Mesh.

+
+
Parameters:
+

fname (str) – The npz file needs the following keys: +nodes, cnodes, coords, tags, btags, ptags.

+
+
Returns:
+

mesh

+
+
Return type:
+

Faces or Volumes

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.io.nutils.to_nutils_simplex.html b/_generated/gustaf.io.nutils.to_nutils_simplex.html new file mode 100644 index 000000000..2a08c78d3 --- /dev/null +++ b/_generated/gustaf.io.nutils.to_nutils_simplex.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.io.nutils.to_nutils_simplex — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.io.nutils.to_nutils_simplex#

+
+
+gustaf.io.nutils.to_nutils_simplex(mesh)[source]#
+

Converts a Gustaf_Mesh to a Dictionary, which can be interpreted +by nutils.mesh.simplex(**to_nutils_simplex(mesh)). Only works for +Triangles and Tetrahedrons!

+
+
Parameters:
+

mesh (Faces or Volumes)

+
+
Returns:
+

dic_to_nutils

+
+
Return type:
+

dict

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.settings.html b/_generated/gustaf.settings.html new file mode 100644 index 000000000..9b40645b9 --- /dev/null +++ b/_generated/gustaf.settings.html @@ -0,0 +1,776 @@ + + + + + + + + + + + gustaf.settings — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.settings#

+

gustaf/gustaf/settings.py.

+

Global variables/constants that’s used throughout gustaf.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.show.html b/_generated/gustaf.show.html new file mode 100644 index 000000000..7417b2a6a --- /dev/null +++ b/_generated/gustaf.show.html @@ -0,0 +1,790 @@ + + + + + + + + + + + gustaf.show — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.show#

+

gustaf/gustaf/show.py.

+

Everything related to show/visualization.

+

Functions

+ + + + + + + + + + + + +

interpolate_vedo_dictcam(cameras, resolutions)

Interpolate between vedo dict cameras.

make_showable(obj[, as_dict])

Generates a vedo obj based on kind attribute from given obj, as well as show_options.

show(*args, **kwargs)

vedo.show wrapper.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.show.interpolate_vedo_dictcam.html b/_generated/gustaf.show.interpolate_vedo_dictcam.html new file mode 100644 index 000000000..ab7e4ba20 --- /dev/null +++ b/_generated/gustaf.show.interpolate_vedo_dictcam.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.show.interpolate_vedo_dictcam — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.show.interpolate_vedo_dictcam#

+
+
+gustaf.show.interpolate_vedo_dictcam(cameras, resolutions, spline_degree=1)[source]#
+

Interpolate between vedo dict cameras.

+
+
Parameters:
+
    +
  • cameras (list or tuple)

  • +
  • resolutions (int)

  • +
  • spline_degree (int) – if > 1 and splinepy is available and there are more than two cameras, +we interpolate all the entries using spline.

  • +
+
+
Returns:
+

interpolated_cams

+
+
Return type:
+

list

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.show.make_showable.html b/_generated/gustaf.show.make_showable.html new file mode 100644 index 000000000..f46a3c07f --- /dev/null +++ b/_generated/gustaf.show.make_showable.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.show.make_showable — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.show.make_showable#

+
+
+gustaf.show.make_showable(obj, as_dict=False, **kwargs)[source]#
+

Generates a vedo obj based on kind attribute from given obj, as well +as show_options.

+
+
Parameters:
+
    +
  • obj (gustaf obj)

  • +
  • as_dict (bool) – If True, returns vedo objects in a dict. Corresponding main objects will +be available with [“main”] key. Else, returns vedo.Assembly object, +where all the objects are grouped together.

  • +
  • **kwargs (kwargs) – Will try to overwrite applicable items.

  • +
+
+
Returns:
+

vedo_obj

+
+
Return type:
+

vedo obj

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.show.show.html b/_generated/gustaf.show.show.html new file mode 100644 index 000000000..2933444e1 --- /dev/null +++ b/_generated/gustaf.show.show.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.show.show — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.show.show#

+
+
+gustaf.show.show(*args, **kwargs)[source]#
+

vedo.show wrapper. Each args represent one section of window. In other +words len(args) == N, where N corresponds to the parameter for vedo.show().

+
+
Parameters:
+

*args (Union[List[Union[gustaf_obj, vedo_obj]], Dict[str, Any]]])

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.bounds.html b/_generated/gustaf.utils.arr.bounds.html new file mode 100644 index 000000000..2673bf5ce --- /dev/null +++ b/_generated/gustaf.utils.arr.bounds.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.utils.arr.bounds — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.bounds#

+
+
+gustaf.utils.arr.bounds(arr)[source]#
+

Return bounds.

+
+
Parameters:
+

arr ((n, d) array-like)

+
+
Returns:
+

bounds

+
+
Return type:
+

(2, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.bounds_diagonal.html b/_generated/gustaf.utils.arr.bounds_diagonal.html new file mode 100644 index 000000000..46cba1520 --- /dev/null +++ b/_generated/gustaf.utils.arr.bounds_diagonal.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.utils.arr.bounds_diagonal — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.bounds_diagonal#

+
+
+gustaf.utils.arr.bounds_diagonal(arr)[source]#
+

Returns diagonal vector of the bounds.

+

bounds[1] - bounds[0]

+
+
Parameters:
+

arr ((n, d) array-like)

+
+
Returns:
+

bounds_diagonal

+
+
Return type:
+

(n,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.bounds_mean.html b/_generated/gustaf.utils.arr.bounds_mean.html new file mode 100644 index 000000000..944c1a3d0 --- /dev/null +++ b/_generated/gustaf.utils.arr.bounds_mean.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.utils.arr.bounds_mean — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.bounds_mean#

+
+
+gustaf.utils.arr.bounds_mean(arr)[source]#
+

Returns mean of the bounds.

+
+
Parameters:
+

arr ((n, d) array-like)

+
+
Returns:
+

bounds_mean

+
+
Return type:
+

(n,) array-like

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.bounds_norm.html b/_generated/gustaf.utils.arr.bounds_norm.html new file mode 100644 index 000000000..578ddde96 --- /dev/null +++ b/_generated/gustaf.utils.arr.bounds_norm.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.utils.arr.bounds_norm — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.bounds_norm#

+
+
+gustaf.utils.arr.bounds_norm(arr)[source]#
+

Returns norm of the bounds.

+
+
Parameters:
+

arr ((n, d) array-like)

+
+
Returns:
+

bounds_norm

+
+
Return type:
+

float

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.close_rows.html b/_generated/gustaf.utils.arr.close_rows.html new file mode 100644 index 000000000..6d02630d1 --- /dev/null +++ b/_generated/gustaf.utils.arr.close_rows.html @@ -0,0 +1,815 @@ + + + + + + + + + + + gustaf.utils.arr.close_rows — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.close_rows#

+
+
+gustaf.utils.arr.close_rows(arr, tolerance=None, return_intersection=False, nthreads=None, **_kwargs)[source]#
+

Similar to unique_rows, but if data type is floats, use this one. +Performs radius search using KDTree. Currently uses +scipy.spatial.cKDTree.

+
+
Parameters:
+
    +
  • arr ((n, d) array-like)

  • +
  • tolerance ((float)) – Defaults to None.

  • +
  • return_intersection (bool) – Default is False. Returns intersection. For vertices with singular +points, this will take a lot of memory space.

  • +
  • nthreads (int) – number of concurrent query. In case of napf, concurrent build as well. +Default is taken from settings.NTHREADS

  • +
+
+
Returns:
+

    +
  • unique_arrays ((n, d) np.ndarray)

  • +
  • unique_ids ((m) np.ndarray)

  • +
  • inverse ((n) np.ndarray)

  • +
  • overlapping (list(list)) – id of neighbors within the tolerance.

  • +
+

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.cross3d.html b/_generated/gustaf.utils.arr.cross3d.html new file mode 100644 index 000000000..bc0b54997 --- /dev/null +++ b/_generated/gustaf.utils.arr.cross3d.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.arr.cross3d — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.cross3d#

+
+
+gustaf.utils.arr.cross3d(a, b)[source]#
+

Cross product for two 3D arrays. Usually faster than np.cross +as it just targets 3d.

+
+
Parameters:
+
    +
  • a ((n, 3) np.ndarray)

  • +
  • b ((n, 3) np.ndarray)

  • +
+
+
Returns:
+

crossed

+
+
Return type:
+

(n, 3) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.derivatives_to_normals.html b/_generated/gustaf.utils.arr.derivatives_to_normals.html new file mode 100644 index 000000000..c60d5d344 --- /dev/null +++ b/_generated/gustaf.utils.arr.derivatives_to_normals.html @@ -0,0 +1,805 @@ + + + + + + + + + + + gustaf.utils.arr.derivatives_to_normals — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.derivatives_to_normals#

+
+
+gustaf.utils.arr.derivatives_to_normals(derivatives, normalize=True)[source]#
+
+
Parameters:
+
    +
  • derivatives ((n, (d - 1), d) np.ndarray) – Surface jacobian transposed.

  • +
  • normalize (bool)

  • +
+
+
Returns:
+

normals

+
+
Return type:
+

(n, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.enforce_len.html b/_generated/gustaf.utils.arr.enforce_len.html new file mode 100644 index 000000000..6d1f57b38 --- /dev/null +++ b/_generated/gustaf.utils.arr.enforce_len.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.arr.enforce_len — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.enforce_len#

+
+
+gustaf.utils.arr.enforce_len(value, n_len)[source]#
+

Given int, float, np.ndarray, tuple, list, returns an array with n_len +len(). In case of iterable, it asserts n_len, else, repeats.

+
+
Parameters:
+
    +
  • value (int, float or iterable)

  • +
  • n_len (int) – Size of desired array

  • +
+
+
Returns:
+

len_n_array

+
+
Return type:
+

(n_len,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.html b/_generated/gustaf.utils.arr.html new file mode 100644 index 000000000..801a797db --- /dev/null +++ b/_generated/gustaf.utils.arr.html @@ -0,0 +1,835 @@ + + + + + + + + + + + gustaf.utils.arr — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr#

+

gustaf/gustaf/utils/arr.py.

+

Useful functions for array / point operations. Named arr, since +array is python library and it sounds funny.

+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

bounds(arr)

Return bounds.

bounds_diagonal(arr)

Returns diagonal vector of the bounds.

bounds_mean(arr)

Returns mean of the bounds.

bounds_norm(arr)

Returns norm of the bounds.

close_rows(arr[, tolerance, ...])

Similar to unique_rows, but if data type is floats, use this one.

cross3d(a, b)

Cross product for two 3D arrays.

derivatives_to_normals(derivatives[, normalize])

+
param derivatives:
+

Surface jacobian transposed.

+
+
+

enforce_len(value, n_len)

Given int, float, np.ndarray, tuple, list, returns an array with n_len len().

is_one_of_shapes(arr, shapes[, strict])

Tuple/list of given shapes, iterates and checks with is_shape.

is_shape(arr, shape[, strict])

Checks if arr matches given shape.

make_c_contiguous(array[, dtype])

Make given array like object a c contiguous np.ndarray.

rotate(arr, rotation[, rotation_axis, degree])

Rotates given arrays.

rotation_matrix(rotation[, degree])

Compute rotation matrix.

rotation_matrix_around_axis([axis, ...])

Compute rotation matrix given the axis of rotation.

select_with_ranges(arr, ranges)

Select array with ranges of each column.

unique_rows(in_arr[, return_index, ...])

Find unique rows using np.unique, but apply tricks.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.is_one_of_shapes.html b/_generated/gustaf.utils.arr.is_one_of_shapes.html new file mode 100644 index 000000000..715ba9c53 --- /dev/null +++ b/_generated/gustaf.utils.arr.is_one_of_shapes.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.utils.arr.is_one_of_shapes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.is_one_of_shapes#

+
+
+gustaf.utils.arr.is_one_of_shapes(arr, shapes, strict=False)[source]#
+

Tuple/list of given shapes, iterates and checks with is_shape. Useful if +you have multiple acceptable shapes.

+
+
Parameters:
+
    +
  • arr (np.ndarray)

  • +
  • shapes (tuple or list) – tuple/list of tuple/list

  • +
  • strict (bool)

  • +
+
+
Returns:
+

matches

+
+
Return type:
+

bool

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.is_shape.html b/_generated/gustaf.utils.arr.is_shape.html new file mode 100644 index 000000000..78416bf6b --- /dev/null +++ b/_generated/gustaf.utils.arr.is_shape.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.arr.is_shape — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.is_shape#

+
+
+gustaf.utils.arr.is_shape(arr, shape, strict=False)[source]#
+

Checks if arr matches given shape. shape can have negative numbers.

+
+
Parameters:
+
    +
  • arr (np.ndarray)

  • +
  • shape (tuple)

  • +
  • strict (bool) – raises ValueError if shapes do not match

  • +
+
+
Returns:
+

matches

+
+
Return type:
+

bool

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.make_c_contiguous.html b/_generated/gustaf.utils.arr.make_c_contiguous.html new file mode 100644 index 000000000..74e43fe5d --- /dev/null +++ b/_generated/gustaf.utils.arr.make_c_contiguous.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.arr.make_c_contiguous — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.make_c_contiguous#

+
+
+gustaf.utils.arr.make_c_contiguous(array, dtype=None)[source]#
+

Make given array like object a c contiguous np.ndarray. dtype is +optional. If None is given, just returns None.

+
+
Parameters:
+
    +
  • array (array-like)

  • +
  • dtype (type or str) – (Optional) numpy interpretable type or str, describing type.

  • +
+
+
Returns:
+

c_contiguous_array

+
+
Return type:
+

np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.rotate.html b/_generated/gustaf.utils.arr.rotate.html new file mode 100644 index 000000000..071ef35f8 --- /dev/null +++ b/_generated/gustaf.utils.arr.rotate.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.utils.arr.rotate — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.rotate#

+
+
+gustaf.utils.arr.rotate(arr, rotation, rotation_axis=None, degree=True)[source]#
+

Rotates given arrays. Arrays shape[1] should equal to either 2 or 3 For +more information, see rotation_matrix().

+
+
Parameters:
+
    +
  • arr ((n, (2 or 3)) list-like)

  • +
  • rotation (list or float) – angle of rotation (around each axis)

  • +
  • rotation_axis ((n, (2 or 3)) or (2 or 3) list-like) – center of rotation

  • +
+
+
Returns:
+

rotated_points

+
+
Return type:
+

(n, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.rotation_matrix.html b/_generated/gustaf.utils.arr.rotation_matrix.html new file mode 100644 index 000000000..c57fb9978 --- /dev/null +++ b/_generated/gustaf.utils.arr.rotation_matrix.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.utils.arr.rotation_matrix — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.rotation_matrix#

+
+
+gustaf.utils.arr.rotation_matrix(rotation, degree=True)[source]#
+

Compute rotation matrix. Works for both 2D and 3D point sets. In 2D, it +can rotate along the (virtual) z-axis. In 3D, it can rotate along [x, y, +z]-axis. Uses scipy.spatial.transform.Rotation.

+
+
Parameters:
+
    +
  • rotation (list or float) – Amount of rotation along [x,y,z] axis. Default is in degrees. +In 2D, it can be float.

  • +
  • degree (bool) – (Optional) rotation given in degrees. +Default is True. If False, in radian.

  • +
+
+
Returns:
+

rotation_matrix

+
+
Return type:
+

np.ndarray (3,3)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.rotation_matrix_around_axis.html b/_generated/gustaf.utils.arr.rotation_matrix_around_axis.html new file mode 100644 index 000000000..962d34be0 --- /dev/null +++ b/_generated/gustaf.utils.arr.rotation_matrix_around_axis.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.utils.arr.rotation_matrix_around_axis — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.rotation_matrix_around_axis#

+
+
+gustaf.utils.arr.rotation_matrix_around_axis(axis=None, rotation=None, degree=True)[source]#
+

Compute rotation matrix given the axis of rotation. Works for both 2D +and 3D Uses Rodrigues’ formula.

+

If axis is not specified, 2D rotation matrix is assumed.

+
+
Parameters:
+
    +
  • axis (list or np.ndarray) – Axis of rotation in 3D

  • +
  • rotation (float) – angle of rotation in either radiant or degrees

  • +
  • degree (bool) – (Optional) rotation given in degrees. +Default is True. If False, in radian.

  • +
+
+
Returns:
+

rotation_matrix

+
+
Return type:
+

np.ndarray (3,3) of np.ndarray (2,2)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.select_with_ranges.html b/_generated/gustaf.utils.arr.select_with_ranges.html new file mode 100644 index 000000000..d9de02ca6 --- /dev/null +++ b/_generated/gustaf.utils.arr.select_with_ranges.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.utils.arr.select_with_ranges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.select_with_ranges#

+
+
+gustaf.utils.arr.select_with_ranges(arr, ranges)[source]#
+

Select array with ranges of each column. Always parsed as:

+

[[greater_than, less_than], [….], …]

+
+
Parameters:
+

ranges ((d, 2) array-like) – Takes None.

+
+
Returns:
+

ids

+
+
Return type:
+

(n,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.arr.unique_rows.html b/_generated/gustaf.utils.arr.unique_rows.html new file mode 100644 index 000000000..f8c64ddfc --- /dev/null +++ b/_generated/gustaf.utils.arr.unique_rows.html @@ -0,0 +1,814 @@ + + + + + + + + + + + gustaf.utils.arr.unique_rows — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.arr.unique_rows#

+
+
+gustaf.utils.arr.unique_rows(in_arr, return_index=True, return_inverse=True, return_counts=True, dtype_name=None)[source]#
+

Find unique rows using np.unique, but apply tricks. Adapted from +skimage.util.unique_rows. +url: github.com/scikit-image/scikit-image/blob/main/skimage/util/unique.py/ +Suitable for int types.

+
+
Parameters:
+
    +
  • in_arr ((n, m) 2D array-like)

  • +
  • return_index (bool)

  • +
  • return_inverse (bool)

  • +
  • return_counts (bool)

  • +
  • dtype_name (str)

  • +
+
+
Returns:
+

    +
  • unique_arr ((p, q) np.ndarray)

  • +
  • unique_ind ((w,) np.ndarray)

  • +
  • unique_inv ((t,) np.ndarray)

  • +
+

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.faces_to_edges.html b/_generated/gustaf.utils.connec.faces_to_edges.html new file mode 100644 index 000000000..98dfdcb42 --- /dev/null +++ b/_generated/gustaf.utils.connec.faces_to_edges.html @@ -0,0 +1,820 @@ + + + + + + + + + + + gustaf.utils.connec.faces_to_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.faces_to_edges#

+
+
+gustaf.utils.connec.faces_to_edges(faces)[source]#
+

Compute edges based on following edge scheme.

+
Ref: (node_ind), edge_ind
+
+    (0)
+     /\
+  0 /  \2
+   /____\
+(1)  1   (2)
+
+      2
+(3)*-----*(2)
+   |     |
+ 3 |     | 1
+(0)*-----*(1)
+      0
+
+
+

Note: if edges index matter for tets, reorder it!

+
+
Parameters:
+

faces ((n, 3) or (n, 4) np.ndarray)

+
+
Returns:
+

edges

+
+
Return type:
+

(n * 3, 2) or (n * 4, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.hexa_to_quad.html b/_generated/gustaf.utils.connec.hexa_to_quad.html new file mode 100644 index 000000000..ca0971189 --- /dev/null +++ b/_generated/gustaf.utils.connec.hexa_to_quad.html @@ -0,0 +1,827 @@ + + + + + + + + + + + gustaf.utils.connec.hexa_to_quad — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.hexa_to_quad#

+
+
+gustaf.utils.connec.hexa_to_quad(volumes)[source]#
+

Computes quad faces based on following index scheme.

+

Hexahedron

+
        (6)    (7)
+        *------*
+        |      |
+ (6) (2)| 3    |(3)   (7)    (6)
+ *------*------*------*------*
+ |      |      |      |      |
+ | 2    | 0    | 4    | 5    |
+ *------*------*------*------*
+ (5) (1)|      |(0)   (4)    (5)
+        | 1    |
+        *------*
+        (5)    (4)
+
+face_ind | node_ind
+---------|----------
+0        | 1 0 3 2
+1        | 0 1 5 4
+2        | 1 2 6 5
+3        | 2 3 7 6
+4        | 3 0 4 7
+5        | 4 5 6 7
+
+
+
+
Parameters:
+

volumes ((n, 8) np.ndarray)

+
+
Returns:
+

faces

+
+
Return type:
+

(n * 8, 4) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.html b/_generated/gustaf.utils.connec.html new file mode 100644 index 000000000..7a4844743 --- /dev/null +++ b/_generated/gustaf.utils.connec.html @@ -0,0 +1,822 @@ + + + + + + + + + + + gustaf.utils.connec — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec#

+

gustaf/gustaf/utils/connec.py.

+

Useful functions for connectivity operation. Ranging from edges to +volumes. Named connec because connectivity is too long. Would have been +even cooler, if it was palindrome.

+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

faces_to_edges(faces)

Compute edges based on following edge scheme.

hexa_to_quad(volumes)

Computes quad faces based on following index scheme.

make_hexa_volumes(resolutions)

Given number of nodes per each dimension, returns connectivity information of structured hexahedron elements.

make_quad_faces(resolutions)

Given number of nodes per each dimension, returns connectivity information of a structured mesh.

range_to_edges(range_[, closed, continuous])

Given range, for example (a, b), returns an edge sequence that sequentially connects indices.

sequence_to_edges(seq[, closed])

Given a sequence of int, "connect" to turn them into edges.

sequentialize_edges(edges[, start, ...])

Organize edge connectivities to describe polygon or a line.

sorted_unique(connectivity[, sorted_])

Given connectivity array, finds unique entries, based on its axis=1 sorted values.

subdivide_edges(edges)

Subdivide edges.

subdivide_quad(mesh[, return_dict])

Subdivide quads.

subdivide_tri(mesh[, return_dict])

Subdivide triangles.

tet_to_tri(volumes)

Computes tri faces based on following index scheme.

volumes_to_faces(volumes)

Guidance function for tet_to_tri and hexa_to_quad.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.make_hexa_volumes.html b/_generated/gustaf.utils.connec.make_hexa_volumes.html new file mode 100644 index 000000000..9000d7606 --- /dev/null +++ b/_generated/gustaf.utils.connec.make_hexa_volumes.html @@ -0,0 +1,815 @@ + + + + + + + + + + + gustaf.utils.connec.make_hexa_volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.make_hexa_volumes#

+
+
+gustaf.utils.connec.make_hexa_volumes(resolutions)[source]#
+

Given number of nodes per each dimension, returns connectivity +information of structured hexahedron elements. Counter clock wise +connectivity.

+
   (7)*-------*(6)
+     /|      /|
+    / | (5) / |
+(4)*-------*  |
+   |  *----|--*(2)
+   | /(3)  | /
+   |/      |/
+(0)*-------*(1)
+
+
+
+
Parameters:
+

resolutions (list)

+
+
Returns:
+

elements

+
+
Return type:
+

(n, 8) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.make_quad_faces.html b/_generated/gustaf.utils.connec.make_quad_faces.html new file mode 100644 index 000000000..72f053972 --- /dev/null +++ b/_generated/gustaf.utils.connec.make_quad_faces.html @@ -0,0 +1,810 @@ + + + + + + + + + + + gustaf.utils.connec.make_quad_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.make_quad_faces#

+
+
+gustaf.utils.connec.make_quad_faces(resolutions)[source]#
+

Given number of nodes per each dimension, returns connectivity +information of a structured mesh. Counter clock wise connectivity.

+
(3)*------*(2)
+   |      |
+   |      |
+(0)*------*(1)
+
+
+
+
Parameters:
+

resolutions (list)

+
+
Returns:
+

faces

+
+
Return type:
+

(n, 4) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.range_to_edges.html b/_generated/gustaf.utils.connec.range_to_edges.html new file mode 100644 index 000000000..96f6fd5e5 --- /dev/null +++ b/_generated/gustaf.utils.connec.range_to_edges.html @@ -0,0 +1,809 @@ + + + + + + + + + + + gustaf.utils.connec.range_to_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.range_to_edges#

+
+
+gustaf.utils.connec.range_to_edges(range_, closed=False, continuous=True)[source]#
+

Given range, for example (a, b), returns an edge sequence that +sequentially connects indices. If int is given as range, it is considered +as (0, value). Used to be called “closed/open_loop_index_train”.

+
+
Parameters:
+
    +
  • range (list, tuple, or int)

  • +
  • closed (bool)

  • +
  • continuous (bool)

  • +
+
+
Returns:
+

edges

+
+
Return type:
+

(n, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.sequence_to_edges.html b/_generated/gustaf.utils.connec.sequence_to_edges.html new file mode 100644 index 000000000..fa3c53011 --- /dev/null +++ b/_generated/gustaf.utils.connec.sequence_to_edges.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.utils.connec.sequence_to_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.sequence_to_edges#

+
+
+gustaf.utils.connec.sequence_to_edges(seq, closed=False)[source]#
+

Given a sequence of int, “connect” to turn them into edges.

+
+
Parameters:
+
    +
  • seq ((n,) array-like)

  • +
  • closed (bool)

  • +
+
+
Returns:
+

edges

+
+
Return type:
+

(m, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.sequentialize_edges.html b/_generated/gustaf.utils.connec.sequentialize_edges.html new file mode 100644 index 000000000..91d467d69 --- /dev/null +++ b/_generated/gustaf.utils.connec.sequentialize_edges.html @@ -0,0 +1,823 @@ + + + + + + + + + + + gustaf.utils.connec.sequentialize_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.sequentialize_edges#

+
+
+gustaf.utils.connec.sequentialize_edges(edges, start=None, return_edges=False, directed=False)[source]#
+

Organize edge connectivities to describe polygon or a line. +This supports edges that describes separated/individual polygons and lines. +In other words, it doesn’t support edges of overlapping vertices.

+
+
Parameters:
+
    +
  • edges ((n, 2) list-like)

  • +
  • start (int) – (Optional) Specify starting point. It will take minimum index otherwise.

  • +
  • return_edges (bool) – (Optional) Default is False. If set True, returns sequences as edges.

  • +
  • directed (bool) – (Optional) Default is False. Set True, if given edges are directed. +It should return the result faster.

  • +
+
+
Returns:
+

    +
  • sequences (list) – list of vertex ids. Or edges iff return_edges is True.

  • +
  • is_polygon (list) – Tells if the sequence is a polygon or a line.

  • +
+

+
+
+

Examples

+
>>> e = gus.Edges(vertices, edges)
+>>> ordered_sequence, is_polygon = sequentialize_edges(e.edges)
+
+
+
>>> f = gus.Faces(vertices, faces)
+>>> ordered_sequence, is_polygon = sequentialize_edges(
+...     f.edges()[f.single_edges()]
+... )
+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.sorted_unique.html b/_generated/gustaf.utils.connec.sorted_unique.html new file mode 100644 index 000000000..4621c767a --- /dev/null +++ b/_generated/gustaf.utils.connec.sorted_unique.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.connec.sorted_unique — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.sorted_unique#

+
+
+gustaf.utils.connec.sorted_unique(connectivity, sorted_=False)[source]#
+

Given connectivity array, finds unique entries, based on its axis=1 +sorted values. Returned value will be sorted.

+
+
Parameters:
+
    +
  • connectivity ((n, d) np.ndarray)

  • +
  • sorted (bool)

  • +
+
+
Returns:
+

unique_info

+
+
Return type:
+

Unique2DIntegers

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.subdivide_edges.html b/_generated/gustaf.utils.connec.subdivide_edges.html new file mode 100644 index 000000000..d5ebb2229 --- /dev/null +++ b/_generated/gustaf.utils.connec.subdivide_edges.html @@ -0,0 +1,817 @@ + + + + + + + + + + + gustaf.utils.connec.subdivide_edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.subdivide_edges#

+
+
+gustaf.utils.connec.subdivide_edges(edges)[source]#
+

Subdivide edges. We assume that mid point is newly added points.

+

Subdivided Edges

+
Edges (Lines)
+
+Ref: (node_ids), edge_ids
+
+(0)      (2)      (1)
+ *--------*--------*
+
+edge_ids | node_ids
+---------|----------
+0        | 0 2
+1        | 2 1
+
+
+
+
Parameters:
+

edges ((n, 2) np.ndarray)

+
+
Returns:
+

subdivided_edges

+
+
Return type:
+

(n * 2, 2) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.subdivide_quad.html b/_generated/gustaf.utils.connec.subdivide_quad.html new file mode 100644 index 000000000..c069a9953 --- /dev/null +++ b/_generated/gustaf.utils.connec.subdivide_quad.html @@ -0,0 +1,809 @@ + + + + + + + + + + + gustaf.utils.connec.subdivide_quad — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.subdivide_quad#

+
+
+gustaf.utils.connec.subdivide_quad(mesh, return_dict=False)[source]#
+

Subdivide quads.

+
+
Parameters:
+
    +
  • mesh (Mesh)

  • +
  • return_dict (bool)

  • +
+
+
Returns:
+

    +
  • new_vertices ((n, d) np.ndarray)

  • +
  • subdivided_faces ((m, 4) np.ndarray)

  • +
  • mesh_dict (dict) – iff return_dict=True, +returns dict(vertices=new_vertices, faces=subdivided_faces).

  • +
+

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.subdivide_tri.html b/_generated/gustaf.utils.connec.subdivide_tri.html new file mode 100644 index 000000000..45b981de2 --- /dev/null +++ b/_generated/gustaf.utils.connec.subdivide_tri.html @@ -0,0 +1,831 @@ + + + + + + + + + + + gustaf.utils.connec.subdivide_tri — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.subdivide_tri#

+
+
+gustaf.utils.connec.subdivide_tri(mesh, return_dict=False)[source]#
+

Subdivide triangles. Each triangle is divided into 4 meshes.

+

Subdivided Faces

+
Triangles
+
+Ref: (node_ind), face_ind
+
+         (0)
+             _/|
+           _/ 0|
+    (3)  _/____|(5)
+       _/|    /|
+     _/ 1| 3/ 2|
+    /____|/____|
+  (1)   (4)    (2)
+
+face_ind | node_ind
+---------|----------
+0        | 0 3 5
+1        | 1 4 3
+2        | 2 5 4
+3        | 3 4 5
+
+
+
+
Parameters:
+
    +
  • mesh (Mesh)

  • +
  • return_dict (bool)

  • +
+
+
Returns:
+

    +
  • new_vertices ((n, d) np.ndarray)

  • +
  • subdivided_faces ((m, 3) np.ndarray)

  • +
  • mesh_dict (dict) – iff return_dict=True, +returns dict(vertices=new_vertices, faces=subdivided_faces).

  • +
+

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.tet_to_tri.html b/_generated/gustaf.utils.connec.tet_to_tri.html new file mode 100644 index 000000000..a9916780b --- /dev/null +++ b/_generated/gustaf.utils.connec.tet_to_tri.html @@ -0,0 +1,823 @@ + + + + + + + + + + + gustaf.utils.connec.tet_to_tri — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.tet_to_tri#

+
+
+gustaf.utils.connec.tet_to_tri(volumes)[source]#
+

Computes tri faces based on following index scheme.

+

Tetrahedron

+
Ref: (node_ind), face_ind
+
+              (0)
+             _/|
+           _/ 1|
+    (1)  _/____| (3)
+       _/|    /|
+     _/ 0| 2/ 3|
+    /____|/____|
+  (0)   (2)    (0)
+
+face_ind | node_ind
+---------|----------
+0        | 0 2 1
+1        | 1 3 0
+2        | 2 3 1
+3        | 3 2 0
+
+
+
+
Parameters:
+

volumes ((n, 4) np.ndarray)

+
+
Returns:
+

faces

+
+
Return type:
+

(n * 4, 3) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.connec.volumes_to_faces.html b/_generated/gustaf.utils.connec.volumes_to_faces.html new file mode 100644 index 000000000..dac054adb --- /dev/null +++ b/_generated/gustaf.utils.connec.volumes_to_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.utils.connec.volumes_to_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.connec.volumes_to_faces#

+
+
+gustaf.utils.connec.volumes_to_faces(volumes)[source]#
+

Guidance function for tet_to_tri and hexa_to_quad.

+
+
Parameters:
+

volumes ((n, 4) or (m, 8) np.ndarray)

+
+
Returns:
+

faces

+
+
Return type:
+

(n*4, 3) or (m*6, 4) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.html b/_generated/gustaf.utils.html new file mode 100644 index 000000000..5329bbdb7 --- /dev/null +++ b/_generated/gustaf.utils.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.utils — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + + + + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.configure.html b/_generated/gustaf.utils.log.configure.html new file mode 100644 index 000000000..086871735 --- /dev/null +++ b/_generated/gustaf.utils.log.configure.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.utils.log.configure — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log.configure#

+
+
+gustaf.utils.log.configure(debug=False, logfile=None)[source]#
+

Logging configurator.

+
+
Parameters:
+
    +
  • debug (bool)

  • +
  • logfile (str)

  • +
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.debug.html b/_generated/gustaf.utils.log.debug.html new file mode 100644 index 000000000..96537e25b --- /dev/null +++ b/_generated/gustaf.utils.log.debug.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.utils.log.debug — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log.debug#

+
+
+gustaf.utils.log.debug(*log)[source]#
+

Debug logger.

+
+
Parameters:
+

*log (Tuple[str])

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.html b/_generated/gustaf.utils.log.html new file mode 100644 index 000000000..b38b16823 --- /dev/null +++ b/_generated/gustaf.utils.log.html @@ -0,0 +1,796 @@ + + + + + + + + + + + gustaf.utils.log — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log#

+

gustaf/gustaf/utils/log.py.

+

Thin logging wrapper.

+

Functions

+ + + + + + + + + + + + + + + + + + +

configure([debug, logfile])

Logging configurator.

debug(*log)

Debug logger.

info(*log)

Info logger.

prepended_log(message, log_func)

Prepend message before a logging function.

warning(*log)

warning logger.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.info.html b/_generated/gustaf.utils.log.info.html new file mode 100644 index 000000000..191c432df --- /dev/null +++ b/_generated/gustaf.utils.log.info.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.utils.log.info — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log.info#

+
+
+gustaf.utils.log.info(*log)[source]#
+

Info logger.

+
+
Parameters:
+

*log (Tuple[str])

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.prepended_log.html b/_generated/gustaf.utils.log.prepended_log.html new file mode 100644 index 000000000..f7d538e3e --- /dev/null +++ b/_generated/gustaf.utils.log.prepended_log.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.utils.log.prepended_log — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log.prepended_log#

+
+
+gustaf.utils.log.prepended_log(message, log_func)[source]#
+

Prepend message before a logging function.

+
+
Parameters:
+
    +
  • message (str)

  • +
  • log_func (function) – one of the following - {info, debug, warning}

  • +
+
+
Returns:
+

prepended

+
+
Return type:
+

function

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.log.warning.html b/_generated/gustaf.utils.log.warning.html new file mode 100644 index 000000000..386a4bdd8 --- /dev/null +++ b/_generated/gustaf.utils.log.warning.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.utils.log.warning — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.log.warning#

+
+
+gustaf.utils.log.warning(*log)[source]#
+

warning logger.

+
+
Parameters:
+

*log (Tuple[str])

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.tictoc.Tic.html b/_generated/gustaf.utils.tictoc.Tic.html new file mode 100644 index 000000000..746077050 --- /dev/null +++ b/_generated/gustaf.utils.tictoc.Tic.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.utils.tictoc.Tic — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.tictoc.Tic#

+
+
+class gustaf.utils.tictoc.Tic(title='untitled', log_level='debug')[source]#
+

Bases: GustafBase

+

Timer class for easier time measurement.

+

Methods

+ + + + + + + + + + + + +

Tic.now

perf_counter() -> float

Tic.summary([log, print_])

Prints measurement summary to the log.

Tic.toc([name, log])

Adds now to the measurements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.tictoc.Tic.now.html b/_generated/gustaf.utils.tictoc.Tic.now.html new file mode 100644 index 000000000..4b19bd3c1 --- /dev/null +++ b/_generated/gustaf.utils.tictoc.Tic.now.html @@ -0,0 +1,793 @@ + + + + + + + + + + + gustaf.utils.tictoc.Tic.now — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.tictoc.Tic.now#

+
+
+Tic.now()#
+

perf_counter() -> float

+

Performance counter for benchmarking.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.tictoc.Tic.summary.html b/_generated/gustaf.utils.tictoc.Tic.summary.html new file mode 100644 index 000000000..9b0b61ecf --- /dev/null +++ b/_generated/gustaf.utils.tictoc.Tic.summary.html @@ -0,0 +1,811 @@ + + + + + + + + + + + gustaf.utils.tictoc.Tic.summary — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.tictoc.Tic.summary#

+
+
+Tic.summary(log=True, print_=False)[source]#
+

Prints measurement summary to the log.

+
+
Parameters:
+
    +
  • log (bool) – Logs the summary. Default is True.

  • +
  • print (bool) – Prints the summary. Default is False.

  • +
+
+
Returns:
+

records

+
+
Lap timings in a tuple consisting of a list of the lap names and

times for each lap from the timer start (cumulative time).

+
+
+

+
+
Return type:
+

tuple

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.tictoc.Tic.toc.html b/_generated/gustaf.utils.tictoc.Tic.toc.html new file mode 100644 index 000000000..31a9ea761 --- /dev/null +++ b/_generated/gustaf.utils.tictoc.Tic.toc.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.utils.tictoc.Tic.toc — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.tictoc.Tic.toc#

+
+
+Tic.toc(name=None, log=False)[source]#
+

Adds now to the measurements.

+
+
Parameters:
+
    +
  • name (str) – Name of this specific measurement lap. +By default, it assigns a number to this lap.

  • +
  • log (bool) – If True, will log lapsed time. Defaults to None.

  • +
+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.utils.tictoc.html b/_generated/gustaf.utils.tictoc.html new file mode 100644 index 000000000..bbd507f81 --- /dev/null +++ b/_generated/gustaf.utils.tictoc.html @@ -0,0 +1,784 @@ + + + + + + + + + + + gustaf.utils.tictoc — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.utils.tictoc#

+

gustaf/gustaf/utils/tictoc.py.

+

Timer that tics, tocs and logs.

+

Classes

+ + + + + + +

Tic([title, log_level])

Timer class for easier time measurement.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.bounds.html b/_generated/gustaf.vertices.Vertices.bounds.html new file mode 100644 index 000000000..692b9751e --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.bounds.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.bounds — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.bounds#

+
+
+Vertices.bounds()[source]#
+

Returns bounds of the vertices. Bounds means AABB of the geometry.

+
+
Parameters:
+

None

+
+
Returns:
+

bounds

+
+
Return type:
+

(d,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.bounds_diagonal.html b/_generated/gustaf.vertices.Vertices.bounds_diagonal.html new file mode 100644 index 000000000..7d38c96ae --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.bounds_diagonal.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.bounds_diagonal — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.bounds_diagonal#

+
+
+Vertices.bounds_diagonal()[source]#
+

Returns diagonal vector of the bounding box.

+
+
Parameters:
+

None

+
+
Returns:
+

bounds_diagonal – same as bounds[1] - bounds[0]

+
+
Return type:
+

(d,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.html b/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.html new file mode 100644 index 000000000..af78f7b52 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.bounds_diagonal_norm — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.bounds_diagonal_norm#

+
+
+Vertices.bounds_diagonal_norm()[source]#
+

Returns norm of bounds diagonal.

+
+
Parameters:
+

None

+
+
Returns:
+

bounds_diagonal_norm

+
+
Return type:
+

float

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.concat.html b/_generated/gustaf.vertices.Vertices.concat.html new file mode 100644 index 000000000..fe8308cc5 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.concat.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.concat — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.concat#

+
+
+classmethod Vertices.concat(*instances)[source]#
+

Sequentially put them together to make one object.

+
+
Parameters:
+

*instances (List[type(cls)]) – Allows one iterable object also.

+
+
Returns:
+

one_instance

+
+
Return type:
+

type(cls)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.const_vertices.html b/_generated/gustaf.vertices.Vertices.const_vertices.html new file mode 100644 index 000000000..0926fa567 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.const_vertices.html @@ -0,0 +1,801 @@ + + + + + + + + + + + gustaf.vertices.Vertices.const_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.const_vertices#

+
+
+property Vertices.const_vertices#
+

Returns non-mutable view of vertices. Naming inspired by c/cpp +sessions.

+
+
Parameters:
+

None

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.copy.html b/_generated/gustaf.vertices.Vertices.copy.html new file mode 100644 index 000000000..c964b3c68 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.copy.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.copy — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.copy#

+
+
+Vertices.copy()[source]#
+

Returns deepcopy of self.

+
+
Parameters:
+

None

+
+
Returns:
+

self_copy

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.html b/_generated/gustaf.vertices.Vertices.html new file mode 100644 index 000000000..3cc299211 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.html @@ -0,0 +1,856 @@ + + + + + + + + + + + gustaf.vertices.Vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices#

+
+
+class gustaf.vertices.Vertices(vertices=None)[source]#
+

Bases: GustafBase

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Vertices.bounds()

Returns bounds of the vertices.

Vertices.bounds_diagonal()

Returns diagonal vector of the bounding box.

Vertices.bounds_diagonal_norm()

Returns norm of bounds diagonal.

Vertices.concat(*instances)

Sequentially put them together to make one object.

Vertices.copy()

Returns deepcopy of self.

Vertices.merge_vertices([tolerance])

Based on unique vertices, merge vertices if it is mergeable.

Vertices.remove_vertices(ids)

Removes vertices with given vertex ids.

Vertices.select_vertices(ranges)

Returns vertices inside the given range.

Vertices.show(**kwargs)

Show current object using visualization backend.

Vertices.showable(**kwargs)

Returns showable object, meaning object of visualization backend.

Vertices.unique_vertices([tolerance])

Returns a namedtuple that holds unique vertices info.

Vertices.update_vertices(mask[, inverse])

Update vertices with a mask.

+

Attributes

+ + + + + + + + + + + + + + + + + + + + + +

Vertices.const_vertices

Returns non-mutable view of vertices.

Vertices.kind

Vertices.show_options

Returns a show option manager for this object.

Vertices.vertex_data

Returns vertex_data manager.

Vertices.vertices

Returns vertices.

Vertices.whatami

"what am i"?

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.kind.html b/_generated/gustaf.vertices.Vertices.kind.html new file mode 100644 index 000000000..26a97a792 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.kind.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.vertices.Vertices.kind — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.kind#

+
+
+Vertices.kind = 'vertex'#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.merge_vertices.html b/_generated/gustaf.vertices.Vertices.merge_vertices.html new file mode 100644 index 000000000..b50f1866b --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.merge_vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.merge_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.merge_vertices#

+
+
+Vertices.merge_vertices(tolerance=None, **kwargs)[source]#
+

Based on unique vertices, merge vertices if it is mergeable.

+
+
Parameters:
+

tolerance (float) – Default is settings.TOLERANCE

+
+
Returns:
+

merged_self

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.remove_vertices.html b/_generated/gustaf.vertices.Vertices.remove_vertices.html new file mode 100644 index 000000000..ad79a306c --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.remove_vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.remove_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.remove_vertices#

+
+
+Vertices.remove_vertices(ids)[source]#
+

Removes vertices with given vertex ids.

+
+
Parameters:
+

ids ((n,) np.ndarray)

+
+
Returns:
+

new_self

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.select_vertices.html b/_generated/gustaf.vertices.Vertices.select_vertices.html new file mode 100644 index 000000000..4c7a19822 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.select_vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.select_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.select_vertices#

+
+
+Vertices.select_vertices(ranges)[source]#
+

Returns vertices inside the given range.

+
+
Parameters:
+

ranges ((d, 2) array-like) – Takes None.

+
+
Returns:
+

ids

+
+
Return type:
+

(n,) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.show.html b/_generated/gustaf.vertices.Vertices.show.html new file mode 100644 index 000000000..63f6a190b --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.show.html @@ -0,0 +1,800 @@ + + + + + + + + + + + gustaf.vertices.Vertices.show — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.show#

+
+
+Vertices.show(**kwargs)[source]#
+

Show current object using visualization backend.

+
+
Parameters:
+

**kwargs

+
+
Return type:
+

None

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.show_options.html b/_generated/gustaf.vertices.Vertices.show_options.html new file mode 100644 index 000000000..afba08622 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.show_options.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.vertices.Vertices.show_options — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.show_options#

+
+
+property Vertices.show_options#
+

Returns a show option manager for this object. Behaves similar to +dict.

+
+
Parameters:
+

None

+
+
Returns:
+

show_options – A derived class that’s suitable for current class.

+
+
Return type:
+

ShowOption

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.showable.html b/_generated/gustaf.vertices.Vertices.showable.html new file mode 100644 index 000000000..e3d513753 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.showable.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.showable — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.showable#

+
+
+Vertices.showable(**kwargs)[source]#
+

Returns showable object, meaning object of visualization backend.

+
+
Parameters:
+

**kwargs

+
+
Returns:
+

showable – Obj of gustaf.settings.VISUALIZATION_BACKEND

+
+
Return type:
+

obj

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.unique_vertices.html b/_generated/gustaf.vertices.Vertices.unique_vertices.html new file mode 100644 index 000000000..c81f649d6 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.unique_vertices.html @@ -0,0 +1,807 @@ + + + + + + + + + + + gustaf.vertices.Vertices.unique_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.unique_vertices#

+
+
+Vertices.unique_vertices(tolerance=None, **kwargs)[source]#
+

Returns a namedtuple that holds unique vertices info. Unique here +means “close-enough-within-tolerance”.

+
+
Parameters:
+
    +
  • tolerance (float) – (Optional) Default is settings.TOLERANCE

  • +
  • recompute (bool) – Only applicable as keyword argument. Force re-computes.

  • +
+
+
Returns:
+

unique_vertices_info – namedtuple with values, ids, inverse, intersection.

+
+
Return type:
+

Unique2DFloats

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.update_vertices.html b/_generated/gustaf.vertices.Vertices.update_vertices.html new file mode 100644 index 000000000..cfaf32fe4 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.update_vertices.html @@ -0,0 +1,808 @@ + + + + + + + + + + + gustaf.vertices.Vertices.update_vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.update_vertices#

+
+
+Vertices.update_vertices(mask, inverse=None)[source]#
+

Update vertices with a mask. In other words, keeps only masked +vertices. Adapted from github.com/mikedh/trimesh. Updates +connectivity accordingly too.

+
+
Parameters:
+
    +
  • mask ((n,) bool or int)

  • +
  • inverse ((len(self.vertices),) int)

  • +
+
+
Returns:
+

updated_self

+
+
Return type:
+

type(self)

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.vertex_data.html b/_generated/gustaf.vertices.Vertices.vertex_data.html new file mode 100644 index 000000000..1da8195a6 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.vertex_data.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.vertices.Vertices.vertex_data — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.vertex_data#

+
+
+property Vertices.vertex_data#
+

Returns vertex_data manager. Behaves similar to dict() and can be used +to store values/data associated with each vertex.

+
+
Parameters:
+

None

+
+
Returns:
+

vertex_data

+
+
Return type:
+

VertexData

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.vertices.html b/_generated/gustaf.vertices.Vertices.vertices.html new file mode 100644 index 000000000..379174f05 --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.vertices.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.vertices.Vertices.vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.vertices#

+
+
+property Vertices.vertices#
+

Returns vertices.

+
+
Parameters:
+

None

+
+
Returns:
+

vertices

+
+
Return type:
+

(n, d) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.Vertices.whatami.html b/_generated/gustaf.vertices.Vertices.whatami.html new file mode 100644 index 000000000..8592c186c --- /dev/null +++ b/_generated/gustaf.vertices.Vertices.whatami.html @@ -0,0 +1,806 @@ + + + + + + + + + + + gustaf.vertices.Vertices.whatami — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.Vertices.whatami#

+
+
+property Vertices.whatami#
+

“what am i”?

+
+
Parameters:
+

None

+
+
Returns:
+

whatami – vertices

+
+
Return type:
+

str

+
+
Type:
+

Answers deep philosophical question

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.VerticesShowOption.html b/_generated/gustaf.vertices.VerticesShowOption.html new file mode 100644 index 000000000..36492d192 --- /dev/null +++ b/_generated/gustaf.vertices.VerticesShowOption.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.vertices.VerticesShowOption — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices.VerticesShowOption#

+
+
+class gustaf.vertices.VerticesShowOption(helpee)[source]#
+

Bases: ShowOption

+

Show options for vertices.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.vertices.html b/_generated/gustaf.vertices.html new file mode 100644 index 000000000..2b70c4b15 --- /dev/null +++ b/_generated/gustaf.vertices.html @@ -0,0 +1,787 @@ + + + + + + + + + + + gustaf.vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.vertices#

+

gustaf/gustaf/vertices.py.

+

Vertices. Base of all “Mesh” geometries.

+

Classes

+ + + + + + + + + +

Vertices([vertices])

VerticesShowOption(helpee)

Show options for vertices.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.const_faces.html b/_generated/gustaf.volumes.Volumes.const_faces.html new file mode 100644 index 000000000..661e743b8 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.const_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.const_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.const_faces#

+
+
+property Volumes.const_faces#
+

Returns non-writeable view of faces.

+
+
Parameters:
+

None

+
+
Returns:
+

const_faces

+
+
Return type:
+

(n, 2

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.const_volumes.html b/_generated/gustaf.volumes.Volumes.const_volumes.html new file mode 100644 index 000000000..f46df3d43 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.const_volumes.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.const_volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.const_volumes#

+
+
+property Volumes.const_volumes#
+

Returns non-writeable view of volumes.

+
+
Parameters:
+

None

+
+
Returns:
+

const_volumes

+
+
Return type:
+

(n, 4) or (n, 8) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.faces.html b/_generated/gustaf.volumes.Volumes.faces.html new file mode 100644 index 000000000..3335574dc --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.faces#

+
+
+Volumes.faces()[source]#
+

Faces here aren’t main property. So this needs to be computed.

+
+
Parameters:
+

None

+
+
Returns:
+

faces

+
+
Return type:
+

(n, 3) or (n, 4) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.html b/_generated/gustaf.volumes.Volumes.html new file mode 100644 index 000000000..47dd014d8 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.html @@ -0,0 +1,835 @@ + + + + + + + + + + + gustaf.volumes.Volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes#

+
+
+class gustaf.volumes.Volumes(vertices=None, volumes=None, elements=None)[source]#
+

Bases: Faces

+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + +

Volumes.faces()

Faces here aren't main property.

Volumes.sorted_volumes()

Sort volumes along axis=1.

Volumes.to_faces([unique])

Returns Faces obj.

Volumes.unique_volumes()

Returns a namedtuple of unique volumes info.

Volumes.update_faces()

Alias to update_elements.

Volumes.update_volumes(*args, **kwargs)

Alias to update_elements.

Volumes.whatareyou(volume_obj)

overwrites Faces.whatareyou to tell you is this volume is tet or hexa.

+

Attributes

+ + + + + + + + + + + + + + + +

Volumes.const_faces

Returns non-writeable view of faces.

Volumes.const_volumes

Returns non-writeable view of volumes.

Volumes.kind

Volumes.volumes

Returns volumes.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.kind.html b/_generated/gustaf.volumes.Volumes.kind.html new file mode 100644 index 000000000..f6d6cb60d --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.kind.html @@ -0,0 +1,791 @@ + + + + + + + + + + + gustaf.volumes.Volumes.kind — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.kind#

+
+
+Volumes.kind = 'volume'#
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.sorted_volumes.html b/_generated/gustaf.volumes.Volumes.sorted_volumes.html new file mode 100644 index 000000000..a2f7b3585 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.sorted_volumes.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.sorted_volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.sorted_volumes#

+
+
+Volumes.sorted_volumes()[source]#
+

Sort volumes along axis=1.

+
+
Parameters:
+

None

+
+
Returns:
+

volumes_sorted

+
+
Return type:
+

(volumes.shape) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.to_faces.html b/_generated/gustaf.volumes.Volumes.to_faces.html new file mode 100644 index 000000000..26d2f356f --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.to_faces.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.to_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.to_faces#

+
+
+Volumes.to_faces(unique=True)[source]#
+

Returns Faces obj.

+
+
Parameters:
+

unique (bool) – Default is True. If True, only takes unique faces.

+
+
Returns:
+

faces

+
+
Return type:
+

Faces

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.unique_volumes.html b/_generated/gustaf.volumes.Volumes.unique_volumes.html new file mode 100644 index 000000000..f6b7151b8 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.unique_volumes.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.volumes.Volumes.unique_volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.unique_volumes#

+
+
+Volumes.unique_volumes()[source]#
+

Returns a namedtuple of unique volumes info. Similar to +unique_edges.

+
+
Parameters:
+

None

+
+
Returns:
+

unique_info – valid attributes are {values, ids, inverse, counts}

+
+
Return type:
+

Unique2DIntegers

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.update_faces.html b/_generated/gustaf.volumes.Volumes.update_faces.html new file mode 100644 index 000000000..5845ed9de --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.update_faces.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.volumes.Volumes.update_faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.update_faces#

+
+
+Volumes.update_faces()#
+

Alias to update_elements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.update_volumes.html b/_generated/gustaf.volumes.Volumes.update_volumes.html new file mode 100644 index 000000000..33bf1e8aa --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.update_volumes.html @@ -0,0 +1,792 @@ + + + + + + + + + + + gustaf.volumes.Volumes.update_volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.update_volumes#

+
+
+Volumes.update_volumes(*args, **kwargs)[source]#
+

Alias to update_elements.

+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.volumes.html b/_generated/gustaf.volumes.Volumes.volumes.html new file mode 100644 index 000000000..f9cb16f93 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.volumes.html @@ -0,0 +1,803 @@ + + + + + + + + + + + gustaf.volumes.Volumes.volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.volumes#

+
+
+property Volumes.volumes#
+

Returns volumes.

+
+
Parameters:
+

None

+
+
Returns:
+

volumes

+
+
Return type:
+

(n, 4) or (n, 8) np.ndarray

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.Volumes.whatareyou.html b/_generated/gustaf.volumes.Volumes.whatareyou.html new file mode 100644 index 000000000..8074dbce7 --- /dev/null +++ b/_generated/gustaf.volumes.Volumes.whatareyou.html @@ -0,0 +1,804 @@ + + + + + + + + + + + gustaf.volumes.Volumes.whatareyou — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.Volumes.whatareyou#

+
+
+classmethod Volumes.whatareyou(volume_obj)[source]#
+

overwrites Faces.whatareyou to tell you is this volume is tet or +hexa.

+
+
Parameters:
+

volume_obj (Volumes)

+
+
Returns:
+

whatareyou

+
+
Return type:
+

str

+
+
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.VolumesShowOption.html b/_generated/gustaf.volumes.VolumesShowOption.html new file mode 100644 index 000000000..a5f3b7fe0 --- /dev/null +++ b/_generated/gustaf.volumes.VolumesShowOption.html @@ -0,0 +1,798 @@ + + + + + + + + + + + gustaf.volumes.VolumesShowOption — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes.VolumesShowOption#

+
+
+class gustaf.volumes.VolumesShowOption(helpee)[source]#
+

Bases: ShowOption

+

Show options for vertices.

+

Methods

+ + + +
+
+ +
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_generated/gustaf.volumes.html b/_generated/gustaf.volumes.html new file mode 100644 index 000000000..aa955faa5 --- /dev/null +++ b/_generated/gustaf.volumes.html @@ -0,0 +1,786 @@ + + + + + + + + + + + gustaf.volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + +
+
+ + + + + +
+ +
+

gustaf.volumes#

+

gustaf/gustaf/volumes.py.

+

Classes

+ + + + + + + + + +

Volumes([vertices, volumes, elements])

VolumesShowOption(helpee)

Show options for vertices.

+
+ + +
+ + + + + + + +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_images/gustaf-logo.png b/_images/gustaf-logo.png new file mode 100644 index 000000000..a8a33fdca Binary files /dev/null and b/_images/gustaf-logo.png differ diff --git a/_images/quad.png b/_images/quad.png new file mode 100644 index 000000000..c0e8e5c17 Binary files /dev/null and b/_images/quad.png differ diff --git a/_images/tet.png b/_images/tet.png new file mode 100644 index 000000000..62b8f8383 Binary files /dev/null and b/_images/tet.png differ diff --git a/_images/tet_quad.png b/_images/tet_quad.png new file mode 100644 index 000000000..ff55c3069 Binary files /dev/null and b/_images/tet_quad.png differ diff --git a/_images/tet_vertex_data.png b/_images/tet_vertex_data.png new file mode 100644 index 000000000..7887f01b7 Binary files /dev/null and b/_images/tet_vertex_data.png differ diff --git a/_modules/gustaf/create/edges.html b/_modules/gustaf/create/edges.html new file mode 100644 index 000000000..576b5f206 --- /dev/null +++ b/_modules/gustaf/create/edges.html @@ -0,0 +1,616 @@ + + + + + + + + + + gustaf.create.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.create.edges

+"""gustaf/create/edges.py
+Routines to create edges.
+"""
+
+import numpy as np
+
+from gustaf import utils
+from gustaf.edges import Edges
+
+
+
+[docs] +def from_vertices(vertices, closed=False, continuous=True): + """ + Creates Edges with given vertices. If close==True, + last vertices will be connected to the first one. + If continuous==False, it assumes that every two vertices form + an independent line. + + Parameters + ---------- + vertices: (n, d) np.ndarray or Vertices + close: bool + continuous: bool + + Returns + ------- + edges: Edges + """ + if hasattr(vertices, "vertices"): # noqa SIM108 + v = vertices.vertices + else: + v = vertices + + edges = Edges(v, utils.connec.range_to_edges(len(v), closed, continuous)) + + return edges
+ + + +
+[docs] +def from_data(gus_obj, data, scale=None, data_norm=None): + """ + Creates edges from gustaf object with vertices. + Data can be either multi-dim array-like data or a str describing a name + of vertex_data that belongs to given gustaf object. + len(gus_obj.vertices) number of edges will be created, where origin and + end of each edge is created using the following scheme: + [[vertices[0], vertices[0] + (array_data[0] * scale)], ...]. + By default, scaling value will be + max([1, (aabb_diagonal_norm * 0.1 / max_data_norm)]). + If there's dimension mismatch between vertices and the data, will append + zero paddings! + + Parameters + ---------- + gus_obj: Vertices + gus.Vertices or its derived classes + data: str or (n_vertices, d) array-like + If str, will be considered as data and search for saved vertex_data. + scale: float + Absolute value. + data_norm: float or array-like + If float, will be considered as max_norm of the data. Else, searches for + max value. Doesn't enforce len to match. + + Returns + ------- + data_arrow: Edges + """ + if not isinstance(gus_obj, Edges.__boundary_class__): + raise TypeError( + "Invalid input. Expecting gus.Vertices or its subclasses" + ) + + # get origin and increment (= array_data * scale) + origin = gus_obj.const_vertices + if isinstance(data, str): + # will raise if data doesn't exist + increment = gus_obj.vertex_data[data] + elif isinstance(data, (tuple, list, np.ndarray)): + increment = np.asanyarray(data) + if len(increment) != len(origin): + raise ValueError( + f"Data length mismatch: expected ({len(origin)}) / " + "given ({len(increment)})" + ) + else: + raise TypeError(f"Couldn't process {type(data)}-data as input.") + + # data dim check + inc_dim = increment.shape[1] + origin_dim = origin.shape[1] + if inc_dim == 1: + # if data is scalar, it should be addable to any vertices + utils.log.debug( + f"gus.create.edges.from_data() - requested data ({data}) is", + "scalar. Edge orientation will be [1,1,..,1].", + ) + elif inc_dim != origin_dim: + # match data and vertex dim. + utils.log.debug( + "gus.create.edges.from_data() - dimension mismatch between", + f"vertices ({origin_dim}) and data ({inc_dim}). Matching", + "dimension by appending zeros.", + ) + dim_diff = int(inc_dim - origin_dim) + zero_pad = np.zeros((len(origin), abs(dim_diff))) + if dim_diff > 0: + origin = np.hstack((origin, zero_pad)) + else: + increment = np.hstack((increment, zero_pad)) + + # apply default scale + if scale is None: + if isinstance(data, str): + norm = gus_obj.vertex_data.as_scalar(data, None, True) + elif data_norm is None: + norm = np.linalg.norm(increment, axis=1) + else: + norm = np.asanyarray(data_norm) + + max_data_norm = norm.max() + aabb_diagonal_norm = gus_obj.bounds_diagonal_norm() + scale = min((1.0, aabb_diagonal_norm * (0.1) / max_data_norm)) + utils.log.debug( + f"creating edges from data with scaling factor ({scale})" + ) + + # by here, this should be good to go + vs = np.hstack((origin, origin + (increment * scale))).reshape( + -1, origin.shape[1] + ) + + return Edges(vs, utils.connec.range_to_edges(len(vs), continuous=False))
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/create/faces.html b/_modules/gustaf/create/faces.html new file mode 100644 index 000000000..1fe9f031c --- /dev/null +++ b/_modules/gustaf/create/faces.html @@ -0,0 +1,845 @@ + + + + + + + + + + gustaf.create.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.create.faces

+"""gustaf/create/faces.py
+Routines to create faces.
+"""
+
+import numpy as np
+
+from gustaf import create, settings, utils
+from gustaf.faces import Faces
+
+
+
+[docs] +def box(bounds=None, resolutions=None, simplex=False, backslash=False): + """Create structured quadrangle or triangle block mesh. + + Parameters + ----------- + bounds: (2, 2) array + Minimum and maximum coordinates. + resolutions: (2) array + Vertex count in each dimension. + simplex: boolean + If true, Mesh will be triangular (simplex). + + Returns + -------- + face_mesh: Volumes + """ + + if resolutions is None: + resolutions = [2, 2] + if bounds is None: + bounds = [[0, 0], [1, 1]] + if np.array(bounds).shape != (2, 2): + raise ValueError("Bounds must have a dimension of (2, 2).") + if len(resolutions) != 2: + raise ValueError("Resolutions must have two entries.") + if not np.greater(resolutions, 1).all(): + raise ValueError("All resolution values must be at least 2.") + + if simplex: + # create quad mesh as basis + quad_mesh = box(bounds=bounds, resolutions=resolutions) + + # turn into triangles + face_mesh = to_simplex(quad_mesh, backslash) + + else: + vertex_mesh = create.vertices.raster(bounds, resolutions) + connectivity = utils.connec.make_quad_faces(resolutions) + face_mesh = Faces(vertex_mesh.vertices, connectivity) + + return face_mesh
+ + + +
+[docs] +def to_simplex(quad, alternate=False): + """Given quad faces, diagonalize them to turn them into triangles. + + If quad is counterclockwise (CCW), triangle will also be CCW and + vice versa. Will return a tri-mesh, if input is triangular. + Default diagonalization looks like this: + + .. code-block:: text + + (3) *---* (2) + | /| + | / | + |/ | + (0) *---* (1) + + resembling 'slash'. + + .. code-block:: text + + (3) *---* (2) + |\\ | + | \\ | + | \\| + (0) *---* (1) + + resembling 'backslash'. + + If you want to alternate the `slash`-direction, set `alternate`-variable. + + Parameters + ---------- + quad: Faces + Faces representation which is to be converted from a cubic mesh into a + simplex mesh. + alternate: bool + Alternate between forward and back-slash to avoid "favored" meshing + direction (important in some analysis problem). + + Returns + -------- + tri: Faces + Simplexifyed mesh. + """ + + if not isinstance(quad, Faces): + raise ValueError( + "Input to to_simplex needs to be of type Faces, but it's " + + type(quad) + ) + + if quad.whatami.startswith("quad"): + # split variants + split_slash = [[0, 1, 2], [2, 3, 0]] + split_backslash = [[0, 1, 3], [3, 1, 2]] + + quad_faces = quad.faces + tf_half = int(quad_faces.shape[0]) + tri_faces = np.full((tf_half * 2, 3), -1, dtype=settings.INT_DTYPE) + + split = split_backslash if alternate else split_slash + + # If backslash assign every other with backslash else only forward + tri_faces[0:tf_half:2] = quad_faces[0::2, split_slash[0]] + tri_faces[1:tf_half:2] = quad_faces[1::2, split[0]] + tri_faces[tf_half::2] = quad_faces[0::2, split_slash[1]] + tri_faces[(tf_half + 1) :: 2] = quad_faces[1::2, split[1]] + + tri = Faces( + vertices=quad.vertices.copy(), + faces=tri_faces, + ) + else: + tri = quad + utils.log.debug( + "Non quadrilateral mesh provided, return original" " mesh." + ) + + return tri
+ + + +
+[docs] +def to_quad(tri): + """ + In case current mesh is triangle surface mesh, it splits triangle faces + into three quad faces by inserting another vertices in the middle of + each triangle face. Warning: mesh quality could be bad! + + ``(new) Quad Face`` + + .. code-block:: text + + Ref: (node_ind), face_ind + + (2) + / \ + / 2 \ + (5)/\\ /\\(4) + / \\ / \ + / 0 |(6) \ + /_____|___1_\ + (0) (3) (1) + + face_ind | node_ind + ---------|---------- + 0 | 0 3 6 5 + 1 | 1 4 6 3 + 2 | 2 5 6 4 + + Parameters + ----------- + None + + Returns + -------- + quad_mesh: Mesh + Only if current mesh is triangle surface mesh. Otherwise, None. + """ + if tri.elements is None: + return None + + if not tri.whatami.startswith("tri"): + return None + + # Form new vertices: 1. mid edge vertices; 2. center vertices. + edge_mids = tri.to_edges(unique=True).centers() + + # New vertices - current vertices & mid edge vertices & center vertices + vertices = np.vstack( + ( + tri.const_vertices, + edge_mids, + tri.centers(), + ) + ) + em_offset = len(tri.vertices) # edge mid offset + fc_offset = len(tri.vertices) + len(edge_mids) # faces center offset + + # New faces - current faces * 3, as each triangle face should produce + # 3 quad faces + faces = np.empty((tri.faces.shape[0] * 3, 4), dtype=settings.INT_DTYPE) + + # Assign face ind + # First col. + faces[:, 0] = tri.faces.ravel() + # Second col. + edge_mid_column = tri.unique_edges().inverse + em_offset + faces[:, 1] = edge_mid_column + # Third col. + faces[:, 2] = np.repeat(np.arange(len(tri.faces)) + fc_offset, 3) + # Fourth col. + faces[:, 3] = edge_mid_column.reshape(-1, 3)[:, [2, 0, 1]].ravel() + + return Faces(vertices=vertices, faces=faces)
+ + + +
+[docs] +def edges_as_quad(edges, scaled_normals): + """ + Expands edges to hexa with given scaled_normals. + + Parameters + ---------- + edges: Edges + (n, d) vertices, (m, 2) edges + scaled_normals: (n, d) np.ndarray + Values will be used to subtract/add to existing vertices. + + Returns + ------- + expanded: Faces + """ + if edges.whatami != "edges": + raise TypeError("expand currently only supports Edges.") + + size = scaled_normals.shape[0] + dim = scaled_normals.shape[1] + if len(edges.vertices) != size: + raise ValueError("Edges.vertices and scaled_normals size mismatch.") + + if dim != edges.vertices.shape[1]: + raise ValueError( + "Dimension mismatch between Edges.Vertices and scaled_normals" + ) + + vertices = np.empty((size * 2, dim), dtype=settings.FLOAT_DTYPE) + vertices[:size] = edges.vertices - scaled_normals + vertices[size:] = edges.vertices + scaled_normals + + quad = np.empty((len(edges.edges), 4), dtype=settings.INT_DTYPE) + quad[:, :2] = edges.edges + quad[:, 2] = edges.edges[:, 1] + size + quad[:, 3] = edges.edges[:, 0] + size + + return Faces(vertices, quad)
+ + + +
+[docs] +def vertex_normals( + faces, + area_weighting=False, + angle_weighting=False, + return_original_ids=False, +): + """ + Computes vertex normals and saves it in vertex_data. + This calls inplace remove_unreferenced_vertices, but original IDs can be + retrieved using the flag `return_original_ids`. + + The normals are computed on the face-centers and their contributions are + weighted and added to the vertex normals. Per default, all element faces + that are adjacent to a vertex are added with equal contributions, but it is + also possible to use weightings by area of the adjacent element + (`area_weighting`) or by the angle between edges at the corner vertex. + + Parameters + ---------- + faces: Faces + area_weighting : bool (false) + Use the element area as a weighting to its respective normal contribution + angle_weighting : bool (false) + Use the angle of between element edges as a weighting to its respective + normal contribution + return_original_ids : bool (false) + return the original ids in the global mesh + + Returns + ------- + faces: Faces + faces with vertex_data["normals"] computed. + """ + if not faces.whatami.startswith("tri"): + raise ValueError("Vertex normals only supports triangle faces") + + if faces.vertices.shape[1] != 3: + raise ValueError("Vertex normals only support 3d triangles") + + if return_original_ids: + original_ids = np.where(faces.referenced_vertices())[0] + + faces.remove_unreferenced_vertices() + + triangles = faces.vertices[faces.faces] + + # compute (1 - 0) and (2 - 0) + edge_ab = triangles[:, 1] - triangles[:, 0] + edge_bc = triangles[:, 2] - triangles[:, 1] + + # get normal of each faces and normalize + crossed = utils.arr.cross3d(edge_ab, edge_bc) + crossed_length = np.linalg.norm(crossed, axis=1).reshape(-1, 1) + + weights = np.ones_like(crossed, dtype=settings.FLOAT_DTYPE) + + # get area based weights + if area_weighting: + weights *= crossed_length + # crossed /= crossed_length + # else: + crossed /= crossed_length + + # get triangle corner angles (same as faces.faces) + if angle_weighting: + angles = np.empty_like(crossed, dtype=settings.FLOAT_DTYPE) + norm_ab = np.linalg.norm(edge_ab, axis=1) + norm_bc = np.linalg.norm(edge_bc, axis=1) + edge_ca = edge_ab + edge_bc + norm_ca = np.linalg.norm(edge_ca, axis=1) + np.arcsin( + crossed_length.ravel() / (norm_ab * norm_bc).ravel(), + out=angles[:, 0], + ) + np.arccos( + np.einsum("ij,ij->i", edge_bc, edge_ca) / (norm_bc * norm_ca), + out=angles[:, 1], + ) + angles[:, 2] = np.pi - angles[:, 0] - angles[:, 1] + + weights *= angles + + # initialize + normals = np.zeros_like(faces.vertices, dtype=settings.FLOAT_DTYPE) + + # sum normals and weights + np.add.at( + normals, faces.faces[:, 0], crossed * weights[:, 0].reshape(-1, 1) + ) + np.add.at( + normals, faces.faces[:, 1], crossed * weights[:, 1].reshape(-1, 1) + ) + np.add.at( + normals, faces.faces[:, 2], crossed * weights[:, 2].reshape(-1, 1) + ) + + # normalize + normals /= np.linalg.norm(normals, axis=1).reshape(-1, 1) + + faces.vertex_data["normals"] = normals + if return_original_ids: + return (faces, original_ids) + else: + return faces
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/create/vertices.html b/_modules/gustaf/create/vertices.html new file mode 100644 index 000000000..f2e4deff6 --- /dev/null +++ b/_modules/gustaf/create/vertices.html @@ -0,0 +1,527 @@ + + + + + + + + + + gustaf.create.vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.create.vertices

+"""gustaf/create/vertices.py.
+
+Routines to create vertices.
+"""
+
+import numpy as np
+
+from gustaf.utils.arr import enforce_len
+from gustaf.vertices import Vertices
+
+
+
+[docs] +def raster( + bounds, + resolutions, +): + """Simple wrapper of np.mgrid to extract raster points of desired bounds + and resolutions. + + Parameters + ----------- + bounds: (2, d) array-like + float + resolutions: (d,) array-like or int + int. It will be casted to int. + In case int is given, it will be repeated to match the length of + each bounds + + Returns + -------- + raster_vertices: Vertices + """ + if isinstance(resolutions, (int, float)): + resolutions = enforce_len(resolutions, len(bounds[0])) + + if len(resolutions) != len(bounds[0]) == len(bounds[1]): + raise ValueError("Length of resolutions and bounds should match.") + + slices = [] + for b0, b1, r in zip(bounds[0], bounds[1], resolutions): + slices.append(slice(b0, b1, int(r) * 1j)) + + # Organize it nicely: 2D np.ndarray with shape (prod(resolutions), dim) + points = np.mgrid[slices].T.reshape(-1, len(resolutions)) + + return Vertices(points)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/create/volumes.html b/_modules/gustaf/create/volumes.html new file mode 100644 index 000000000..3a8b747bf --- /dev/null +++ b/_modules/gustaf/create/volumes.html @@ -0,0 +1,523 @@ + + + + + + + + + + gustaf.create.volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.create.volumes

+"""gustaf/create/volumes.py
+Routines to create volumes.
+"""
+
+import numpy as np
+
+from gustaf import create, utils
+from gustaf.volumes import Volumes
+
+
+
+[docs] +def box(bounds=None, resolutions=None): + """Create structured hexahedron block mesh. + + Parameters + ----------- + bounds: (2, 3) array + Minimum and maximum coordinates. + resolutions: (3) array + Vertex count in each dimension. + + Returns + -------- + volume_mesh: Volumes + """ + + if resolutions is None: + resolutions = [2, 2, 2] + if bounds is None: + bounds = [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]] + if np.array(bounds).shape != (2, 3): + raise ValueError("Bounds must have a dimension of (2, 3).") + if len(resolutions) != 3: + raise ValueError("Resolutions must have three entries.") + if not np.greater(resolutions, 1).all(): + raise ValueError("All resolution values must be at least 2.") + + vertex_mesh = create.vertices.raster(bounds, resolutions) + connectivity = utils.connec.make_hexa_volumes(resolutions) + volume_mesh = Volumes(vertex_mesh.vertices, connectivity) + + return volume_mesh
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/edges.html b/_modules/gustaf/edges.html new file mode 100644 index 000000000..7af643a71 --- /dev/null +++ b/_modules/gustaf/edges.html @@ -0,0 +1,1008 @@ + + + + + + + + + + gustaf.edges — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.edges

+"""gustaf/gustaf/edges.py.
+
+Edges. Also known as lines.
+"""
+
+from copy import deepcopy
+
+import numpy as np
+
+from gustaf import helpers, settings, show, utils
+from gustaf.helpers.options import Option
+from gustaf.vertices import Vertices
+
+
+
+[docs] +class EdgesShowOption(helpers.options.ShowOption): + """ + Show options for vertices. + """ + + _valid_options = helpers.options.make_valid_options( + *helpers.options.vedo_common_options, + Option( + "vedo", + "lw", + "Width of edges (lines) in pixel units.", + (float, int), + ), + Option("vedo", "as_arrows", "Show edges as arrows.", (bool,)), + Option( + "vedo", + "head_radius", + "Radius of arrow head. Applicable if as_arrows is True", + (float, int), + ), + Option( + "vedo", + "head_length", + "Length of arrow head. Applicable if as_arrows is True", + (float, int), + ), + Option( + "vedo", + "shaft_radius", + "Radius of arrow shaft. Applicable if as_arrows is True", + (float, int), + ), + ) + + _helps = "Edges" + + def _initialize_showable(self): + """ + Initializes edges as either vedo.Lines or vedo.Arrows + + Parameters + ---------- + None + + Returns + ------- + edges: vedo.Lines or vedo.Arrows + """ + if self.get("as_arrows", False): + init_options = ("head_radius", "head_length", "shaft_radius") + return show.vedo.Arrows( + self._helpee.const_vertices[self._helpee.edges], + **self[init_options], + ) + + else: + init_options = ("lw",) + return show.vedo.Lines( + self._helpee.const_vertices[self._helpee.edges], + **self[init_options], + )
+ + + +
+[docs] +class Edges(Vertices): + kind = "edge" + + __slots__ = ( + "_edges", + "_const_edges", + ) + + __show_option__ = EdgesShowOption + __boundary_class__ = Vertices + + def __init__( + self, + vertices=None, + edges=None, + elements=None, + ): + """Edges. It has vertices and edges. Also known as lines. + + Parameters + ----------- + vertices: (n, d) np.ndarray + edges: (n, 2) np.ndarray + """ + super().__init__(vertices=vertices) + + if edges is not None: + self.edges = edges + + elif elements is not None: + self.edges = elements + + @property + def edges(self): + """Returns edges. If edges is not its original property. + + Parameters + ----------- + None + + Returns + -------- + edges: (n, 2) np.ndarray + """ + self._logd("returning edges") + return self._edges + + @edges.setter + def edges(self, es): + """Edges setter. Similar to vertices, this is a tracked array. + + Parameters + ----------- + es: (n, 2) np.ndarray + + Returns + -------- + None + """ + self._logd("setting edges") + + self._edges = helpers.data.make_tracked_array( + es, settings.INT_DTYPE, copy=False + ) + + # shape check + if es is not None: + utils.arr.is_shape(es, (-1, 2), strict=True) + + # same, but non-writeable view of tracked array + self._const_edges = self._edges.view() + self._const_edges.flags.writeable = False + + @property + def const_edges(self): + """Returns non-writeable version of edges. + + Parameters + ----------- + None + + Returns + -------- + const_edges (n, 2) np.ndarray + """ + return self._const_edges + + @property + def whatami(self): + """whatami? + + Parameters + ----------- + None + + Returns + -------- + whatami: str + """ + return "edges" + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def sorted_edges(self): + """Sort edges along axis=1. + + Parameters + ----------- + None + + Returns + -------- + edges_sorted: (n_edges, 2) np.ndarray + """ + edges = self._get_attr("edges") + + return np.sort(edges, axis=1)
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def unique_edges(self): + """Returns a named tuple of unique edge info. Info includes unique + values, ids of unique edges, inverse ids, count of each unique values. + + Parameters + ----------- + None + + Returns + -------- + unique_info: Unique2DIntegers + valid attributes are {values, ids, inverse, counts} + """ + unique_info = utils.connec.sorted_unique( + self.sorted_edges(), sorted_=True + ) + + edges = self._get_attr("edges") + + # tuple is not assignable, but entry is mutable... + unique_info.values[:] = edges[unique_info.ids] + + return unique_info
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def single_edges(self): + """Returns indices of very unique edges: edges that appear only once. + For well constructed faces, this can be considered as outlines. + + Parameters + ----------- + None + + Returns + -------- + outlines: (m,) np.ndarray + """ + unique_info = self.unique_edges() + + return unique_info.ids[unique_info.counts == 1]
+ + + @property + def elements(self): + """Returns current connectivity. A short cut in FE friendly term. + Elements mean different things for different classes: Vertices -> + vertices Edges -> edges Faces -> faces Volumes -> volumes. + + Parameters + ----------- + None + + Returns + -------- + elements: (n, d) np.ndarray + int. iff elements=None + """ + elem_name = type(self).__qualname__.lower() + self._logd(f"returning {elem_name}") + + return getattr(self, elem_name) + + @elements.setter + def elements(self, elements): + """Calls corresponding connectivity setter. A short cut in FEM friendly + term. Vertices -> vertices Edges -> edges Faces -> faces Volumes -> + volumes. + + Parameters + ----------- + elements: (n, d) np.ndarray + + Returns + -------- + None + """ + # naming rule in gustaf + elem_name = type(self).__qualname__.lower() + self._logd(f"Setting {elem_name}'s connectivity.") + return setattr(self, elem_name, elements) + + @property + def const_elements(self): + """Returns non-mutable version of elements. + + Parameters + ----------- + None + + Returns + -------- + non_mutable_elements: (n, d) TrackedArray + """ + self._logd("returning const_elements") + return getattr(self, "const_" + type(self).__qualname__.lower()) + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices", "elements"]) + def centers(self): + """Center of elements. + + Parameters + ----------- + None + + Returns + -------- + centers: (n_elements, d) np.ndarray + """ + self._logd("computing centers") + + return self.const_vertices[self.const_elements].mean(axis=1)
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices", "elements"]) + def referenced_vertices( + self, + ): + """Returns mask of referenced vertices. + + Parameters + ----------- + None + + Returns + -------- + referenced: (n,) np.ndarray + """ + referenced = np.zeros(len(self.const_vertices), dtype=bool) + referenced[self.const_elements] = True + + return referenced
+ + +
+[docs] + def remove_unreferenced_vertices(self): + """Remove unreferenced vertices. Adapted from + `github.com/mikedh/trimesh` + + Parameters + ----------- + None + + Returns + -------- + new_self: type(self) + """ + referenced = self.referenced_vertices() + + inverse = np.zeros(len(self.vertices), dtype=settings.INT_DTYPE) + inverse[referenced] = np.arange(referenced.sum()) + + return self.update_vertices( + mask=referenced, + inverse=inverse, + )
+ + +
+[docs] + def update_elements(self, mask): + """Similar to update_vertices, but for elements. + + Parameters + ----------- + mask: bool or (m,) np.ndarray + + Returns + -------- + new_self: type(self) + """ + self.elements = self.elements[mask] + + return self.remove_unreferenced_vertices()
+ + +
+[docs] + def update_edges(self, *args, **kwargs): + """Alias to update_elements.""" + return self.update_elements(*args, **kwargs)
+ + +
+[docs] + def dashed(self, spacing=None): + """Turn edges into dashed edges(=lines). Given spacing, it will try to + chop edges as close to it as possible. Pattern should look: + + ``dashed edges`` + + .. code-block:: text + + o--------o o--------o o--------o + |<------>| |<-->| + (chop length) (chop length / 2) + + Parameters + ----------- + spacing: float + Default is None and it will use self.bounds_diagonal_norm() / 50 + + Returns + -------- + dashing_edges: Edges + """ + if self.kind != "edge": + raise NotImplementedError("dashed is only for edges.") + + if spacing is None: + # apply "automatic" spacing + spacing = self.bounds_diagonal_norm() / 50 + + v0s = self.vertices[self.edges[:, 0]] + v1s = self.vertices[self.edges[:, 1]] + + distances = np.linalg.norm(v0s - v1s, axis=1) + linspaces = (((distances // (spacing * 1.5)) + 1) * 3).astype(np.int32) + + # chop vertices! + new_vs = [] + for v0, v1, lins in zip(v0s, v1s, linspaces): + new_vs.append(np.linspace(v0, v1, lins)) + + # we need all chopped vertices. + # there might be duplicating vertices. you can use merge_vertices + new_vs = np.vstack(new_vs) + # all mid points are explicitly defined, but they aren't required + # so, rm. + mask = np.ones(len(new_vs), dtype=bool) + mask[1::3] = False + new_vs = new_vs[mask] + + # prepare edges + tmp_es = utils.connec.range_to_edges((0, len(new_vs)), closed=False) + new_es = tmp_es[::2] + + return Edges(vertices=new_vs, edges=new_es)
+ + +
+[docs] + def shrink(self, ratio=0.8, map_vertex_data=True): + """Returns shrunk elements. + + Parameters + ----------- + ratio: float + Default is 0.8 + map_vertex_data: bool + Default is True. Maps all vertex_data. + + Returns + -------- + s_elements: Elements + shrunk elements + """ + elements = self.const_elements + vs = np.vstack(self.vertices[elements]) + es = np.arange(len(vs)) + + nodes_per_element = elements.shape[1] + es = es.reshape(-1, nodes_per_element) + + mids = np.repeat(self.centers(), nodes_per_element, axis=0) + + vs -= mids + vs *= ratio + vs += mids + + s_elements = type(self)(vertices=vs, elements=es) + + if map_vertex_data: + elements_flat = elements.ravel() + for key, value in self.vertex_data.items(): + s_elements.vertex_data[key] = value[elements_flat] + + # probably wanna take visualization options too + s_elements._show_options._options = deepcopy( + self.show_options._options + ) + + return s_elements
+ + +
+[docs] + def to_vertices(self): + """Returns Vertices obj. + + Parameters + ----------- + None + + Returns + -------- + vertices: Vertices + """ + return Vertices(self.vertices)
+ + + def _get_attr(self, attr): + """Internal function to get attribute that maybe property or callable. + Some properties are replaced by callable in subclasses as it may depend + on other properties of subclass. + + Parameters + ----------- + attr: str + + Returns + -------- + attrib: Any + """ + attrib = getattr(self, attr) + return attrib() if callable(attrib) else attrib
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/faces.html b/_modules/gustaf/faces.html new file mode 100644 index 000000000..d29555b5e --- /dev/null +++ b/_modules/gustaf/faces.html @@ -0,0 +1,843 @@ + + + + + + + + + + gustaf.faces — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.faces

+"""gustaf/gustaf/faces.py."""
+
+import numpy as np
+
+from gustaf import helpers, settings, show, utils
+from gustaf.edges import Edges
+from gustaf.helpers.options import Option
+
+# special types for face texture option
+try:
+    import vedo
+
+    vedoPicture = vedo.Picture
+    # there are other ways to get here, but this is exact path for our use
+    vtkTexture = vedo.vtkclasses.vtkTexture
+except ImportError as err:
+    vedoPicture = helpers.raise_if.ModuleImportRaiser("vedo", err)
+    vtkTexture = helpers.raise_if.ModuleImportRaiser("vedo", err)
+
+
+
+[docs] +class FacesShowOption(helpers.options.ShowOption): + """ + Show options for vertices. + """ + + _valid_options = helpers.options.make_valid_options( + *helpers.options.vedo_common_options, + Option("vedo", "lw", "Width of edges (lines) in pixel units.", (int,)), + Option( + "vedo", "lc", "Color of edges (lines).", (int, str, tuple, list) + ), + Option( + "vedo", + "texture", + "Texture of faces in array, vedo.Picture, vtk.vtkTexture, " + "or path to an image.", + (np.ndarray, tuple, list, str, vedoPicture, vtkTexture), + ), + ) + + _helps = "Faces" + + def _initialize_showable(self): + """ + Initializes Faces as vedo.Mesh + + Parameters + ---------- + None + + Returns + ------- + faces: vedo.Mesh + """ + + faces = show.vedo.Mesh( + [self._helpee.const_vertices, self._helpee.const_faces], + ) + + for option in ["lw", "lc", "texture"]: + val = self.get(option, False) + if val: + getattr(faces, option)(val) + + return faces
+ + + +
+[docs] +class Faces(Edges): + kind = "face" + + const_edges = helpers.raise_if.invalid_inherited_attr( + "Edges.const_edges", + __qualname__, + property_=True, + ) + update_edges = helpers.raise_if.invalid_inherited_attr( + "Edges.update_edges", + __qualname__, + property_=False, + ) + dashed = helpers.raise_if.invalid_inherited_attr( + "Edges.dashed", + __qualname__, + property_=False, + ) + + __slots__ = ( + "_faces", + "_const_faces", + "BC", + ) + + __show_option__ = FacesShowOption + __boundary_class__ = Edges + + def __init__( + self, + vertices=None, + faces=None, + elements=None, + ): + """Faces. It has vertices and faces. Faces could be triangles or + quadrilaterals. + + Parameters + ----------- + vertices: (n, d) np.ndarray + faces: (n, 3) or (n, 4) np.ndarray + """ + super().__init__(vertices=vertices) + if faces is not None: + self.faces = faces + + elif elements is not None: + self.faces = elements + + self.BC = {} + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def edges(self): + """Edges from here aren't main property. So this needs to be computed. + + Parameters + ----------- + None + + Returns + -------- + edges: (n, 2) np.ndarray + """ + self._logd("computing edges") + faces = self._get_attr("faces") + + return utils.connec.faces_to_edges(faces)
+ + + @property + def whatami(self): + """Determines whatami. + + Parameters + ----------- + None + + Returns + -------- + None + """ + return type(self).whatareyou(self) + +
+[docs] + @classmethod + def whatareyou(cls, face_obj): + """classmethod that tells you if the Faces is tri or quad or invalid + kind. + + Parameters + ----------- + face_obj: Faces + + Returns + -------- + whatareyou: str + """ + if not cls.kind.startswith(face_obj.kind): + raise TypeError("Given obj is not {cls.__qualname__}") + + if face_obj.faces.shape[1] == 3: + return "tri" + + elif face_obj.faces.shape[1] == 4: + return "quad" + + else: + raise ValueError( + "Invalid faces connectivity shape. It should be (n, 3) or " + f"(n, 4), but given: {face_obj.faces.shape}" + )
+ + + @property + def faces(self): + """Returns faces. + + Parameters + ----------- + None + + Returns + -------- + faces + """ + self._logd("returning faces") + return self._faces + + @faces.setter + def faces(self, fs): + """Faces setter. Similar to vertices, this will be a tracked array. + + Parameters + ----------- + fs: (n, 2) np.ndarray + + Returns + -------- + None + """ + self._logd("setting faces") + + self._faces = helpers.data.make_tracked_array( + fs, + settings.INT_DTYPE, + copy=False, + ) + # shape check + if fs is not None: + utils.arr.is_one_of_shapes( + fs, + ((-1, 3), (-1, 4)), + strict=True, + ) + + # same, but non-writeable view of tracked array + self._const_faces = self._faces.view() + self._const_faces.flags.writeable = False + + @property + def const_faces(self): + """Returns non-writeable view of faces. + + Parameters + ----------- + None + + Returns + -------- + const_faces: (n, 2 + """ + return self._const_faces + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def sorted_faces(self): + """Similar to edges_sorted but for faces. + + Parameters + ----------- + None + + Returns + -------- + sorted_faces: (self.faces.shape) np.ndarray + """ + faces = self._get_attr("faces") + + return np.sort(faces, axis=1)
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def unique_faces(self): + """Returns a namedtuple of unique faces info. Similar to unique_edges. + + Parameters + ----------- + None + + Returns + -------- + unique_info: Unique2DIntegers + valid attributes are {values, ids, inverse, counts} + """ + unique_info = utils.connec.sorted_unique( + self.sorted_faces(), sorted_=True + ) + + faces = self._get_attr("faces") + + unique_info.values[:] = faces[unique_info.ids] + + return unique_info
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def single_faces(self): + """Returns indices of very unique faces: faces that appear only once. + For well constructed volumes, this can be considered as surfaces. + + Parameters + ----------- + None + + Returns + -------- + single_faces: (m,) np.ndarray + """ + unique_info = self.unique_faces() + + return unique_info.ids[unique_info.counts == 1]
+ + +
+[docs] + def update_faces(self, *args, **kwargs): + """Alias to update_elements.""" + self.update_elements(*args, **kwargs)
+ + +
+[docs] + def to_edges(self, unique=True): + """Returns Edges obj. + + Parameters + ----------- + unique: bool + Default is True. If True, only takes unique edges. + + Returns + -------- + edges: Edges + """ + return Edges( + self.vertices, + edges=self.unique_edges().values if unique else self.edges(), + )
+ + +
+[docs] + def to_subelements( + self, + unique=True, # noqa ARG002 # used inside the return eval str + ): + """Returns current elements represented as its boundary element class. + For faces, this is equivalent to `to_edges()`. + For volumes, `to_faces()`. + + Parameters + ---------- + unique: bool + Default is True. If True, only takes unique edges. + + Returns + ------- + subelements: boundary class + """ + return getattr( + self, f"to_{self.__boundary_class__.__qualname__.lower()}" + )(unique)
+
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/helpers/data.html b/_modules/gustaf/helpers/data.html new file mode 100644 index 000000000..b05df1283 --- /dev/null +++ b/_modules/gustaf/helpers/data.html @@ -0,0 +1,1250 @@ + + + + + + + + + + gustaf.helpers.data — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.helpers.data

+"""gustaf/gustaf/helpers/data.py.
+
+Helps helpee to manage data. Some useful data structures.
+"""
+
+from collections import namedtuple
+from functools import wraps
+
+import numpy as np
+
+from gustaf.helpers._base import HelperBase
+
+
+
+[docs] +class TrackedArray(np.ndarray): + """numpy array object that keeps mirroring inplace changes to the source. + Meant to help control_points. + """ + + __slots__ = ( + "_super_arr", + "_modified", + ) + + def __array_finalize__(self, obj): + """Sets default flags for any arrays that maybe generated based on + physical space array. For more information, + see https://numpy.org/doc/stable/user/basics.subclassing.html""" + self._super_arr = None + self._modified = True + + # for arrays created based on this subclass + if isinstance(obj, type(self)): + # this is copy. nothing to worry here + if self.base is None: + return None + + # first child array + if self.base is obj: + # make sure this is not a recursively born child + # for example, `arr[[1,2]][:,2]` + # we should have set _super_arr to True + # if we made this array using `make_tracked_array` + if obj._super_arr is True: + self._super_arr = obj + return None + + # multi generation child array + if obj._super_arr is not None and self.base is obj.base: + self._super_arr = obj._super_arr + return None + + return None + + @property + def modified(self): + """ + Modified flag getter + """ + # have super arr and self is not super_arr, + if self._super_arr is not None and self._super_arr is not True: + return self._super_arr._modified + + return self._modified + + @modified.setter + def modified(self, m): + if self._super_arr is not None and self._super_arr is not True: + self._super_arr._modified = m + else: + self._modified = m + +
+[docs] + def copy(self, *args, **kwargs): + """copy creates regular numpy array""" + return np.array(self, *args, copy=True, **kwargs)
+ + +
+[docs] + def view(self, *args, **kwargs): + """Set writeable flags to False for the view.""" + v = super(self.__class__, self).view(*args, **kwargs) + v.flags.writeable = False + return v
+ + + def __iadd__(self, *args, **kwargs): + sr = super(self.__class__, self).__iadd__(*args, **kwargs) + self.modified = True + return sr + + def __isub__(self, *args, **kwargs): + sr = super(self.__class__, self).__isub__(*args, **kwargs) + self.modified = True + return sr + + def __imul__(self, *args, **kwargs): + sr = super(self.__class__, self).__imul__(*args, **kwargs) + self.modified = True + return sr + + def __idiv__(self, *args, **kwargs): + sr = super(self.__class__, self).__idiv__(*args, **kwargs) + self.modified = True + return sr + + def __itruediv__(self, *args, **kwargs): + sr = super(self.__class__, self).__itruediv__(*args, **kwargs) + self.modified = True + return sr + + def __imatmul__(self, *args, **kwargs): + sr = super(self.__class__, self).__imatmul__(*args, **kwargs) + self.modified = True + return sr + + def __ipow__(self, *args, **kwargs): + sr = super(self.__class__, self).__ipow__(*args, **kwargs) + self.modified = True + return sr + + def __imod__(self, *args, **kwargs): + sr = super(self.__class__, self).__imod__(*args, **kwargs) + self.modified = True + return sr + + def __ifloordiv__(self, *args, **kwargs): + sr = super(self.__class__, self).__ifloordiv__(*args, **kwargs) + self.modified = True + return sr + + def __ilshift__(self, *args, **kwargs): + sr = super(self.__class__, self).__ilshift__(*args, **kwargs) + self.modified = True + return sr + + def __irshift__(self, *args, **kwargs): + sr = super(self.__class__, self).__irshift__(*args, **kwargs) + self.modified = True + return sr + + def __iand__(self, *args, **kwargs): + sr = super(self.__class__, self).__iand__(*args, **kwargs) + self.modified = True + return sr + + def __ixor__(self, *args, **kwargs): + sr = super(self.__class__, self).__ixor__(*args, **kwargs) + self.modified = True + return sr + + def __ior__(self, *args, **kwargs): + sr = super(self.__class__, self).__ior__(*args, **kwargs) + self.modified = True + return sr + + def __setitem__(self, key, value): + # set first. invalid setting will cause error + sr = super(self.__class__, self).__setitem__(key, value) + self.modified = True + return sr
+ + + +
+[docs] +def make_tracked_array(array, dtype=None, copy=True): + """Motivated by nice implementations of `trimesh` (see LICENSE.txt). + `https://github.com/mikedh/trimesh/blob/main/trimesh/caching.py`. + + Factory-like wrapper function for TrackedArray. + If you want to use TrackedArray, it is recommended to use this function. + + Parameters + ------------ + array: array- like object + To be turned into a TrackedArray + dtype: np.dtype + Which dtype to use for the array + copy: bool + Default is True. copy if True. + + Returns + ------------ + tracked : TrackedArray + Contains input array data + """ + # if someone passed us None, just create an empty array + if array is None: + array = [] + + if copy: + array = np.array(array, dtype=dtype) + else: + array = np.asanyarray(array, dtype=dtype) + + tracked = array.view(TrackedArray) + + # this marks original array + tracked._super_arr = True + + return tracked
+ + + +
+[docs] +class DataHolder(HelperBase): + __slots__ = ("_saved",) + + def __init__(self, helpee): + """Base class for any data holder. Behaves similar to dict. + + Parameters + ----------- + helpee: object + GustafBase objects would probably make the most sense here. + """ + self._helpee = helpee + self._saved = {} + + def __setitem__(self, key, value): + """Raise Error to disable direct value setting. + + Parameters + ----------- + key: str + value: object + """ + raise NotImplementedError( + "Sorry, you can't set items directly for " + f"{type(self).__qualname__}" + ) + + def __getitem__(self, key): + """Returns stored item if the key exists. + + Parameters + ----------- + key: str + + Returns + -------- + value: object + """ + if key in self._saved: + return self._saved[key] + + else: + raise KeyError(f"`{key}` is not stored for {type(self._helpee)}") + + def __contains__(self, key): + """Returns if saved data contains the given key. + + Parameters + ---------- + key: str + + Returns + ------- + value + """ + return key in self._saved + + def __len__(self): + """ + Returns number of items. + + Parameters + ---------- + None + + Returns + ------- + len: int + """ + return len(self._saved) + +
+[docs] + def pop(self, key, default=None): + """ + Applied pop() to saved data + + Parameters + ---------- + key: str + default: object + + Returns + ------- + value: object + """ + return self._saved.pop(key, default)
+ + +
+[docs] + def clear(self): + """ + Clears saved data by reassigning new dict + """ + self._saved = {}
+ + +
+[docs] + def get(self, key, default_values=None): + """Returns stored item if the key exists. Else, given default value. If + the key exist, default value always exists, since it is initialized + that way. + + Parameters + ----------- + key: str + default_values: object + + Returns + -------- + value: object + """ + if key in self._saved: + return self._saved[key] + else: + return default_values
+ + +
+[docs] + def keys(self): + """Returns keys of data holding dict. + + Returns + -------- + keys: dict_keys + """ + return self._saved.keys()
+ + +
+[docs] + def values(self): + """Returns values of data holding dict. + + Returns + -------- + values: dict_values + """ + return self._saved.values()
+ + +
+[docs] + def items(self): + """Returns items of data holding dict. + + Returns + -------- + values: dict_values + """ + return self._saved.items()
+ + +
+[docs] + def update(self, **kwargs): + """ + Updates given kwargs using __setitem__. + + Parameters + ---------- + **kwargs: kwargs + + Returns + ------- + None + """ + self._saved.update(**kwargs)
+
+ + + +
+[docs] +class ComputedData(DataHolder): + _depends = None + _inv_depends = None + + __slots__ = () + + def __init__(self, helpee, **_kwargs): + """Stores last computed values. + + Keys are expected to be the same as helpee's function that computes the + value. + + Parameters + ----------- + helpee: GustafBase + """ + super().__init__(helpee) + +
+[docs] + @classmethod + def depends_on(cls, var_names, make_property=False): + """Decorator as classmethod. + + checks if the key should be computed. Two cases, where the answer is + yes: + + 1. there's modification on arrays that the key depend on. + ->erases all other + 2. is corresponding value None? + + Supports multi-dependency + + Parameters + ----------- + var_name: list + make_property: + """ + + def inner(func): + # following are done once while modules are loaded + # just subclass this class to make a special helper + # for each helpee class. + assert isinstance(var_names, list), "var_names should be a list" + # initialize property + # _depends is dict(str: list) + if cls._depends is None: + cls._depends = {} + if cls._depends.get(func.__name__, None) is None: + cls._depends[func.__name__] = [] + # add dependency info + cls._depends[func.__name__].extend(var_names) + + # _inv_depends is dict(str: list) + if cls._inv_depends is None: + cls._inv_depends = {} + # add inverse dependency + for vn in var_names: + if cls._inv_depends.get(vn, None) is None: + cls._inv_depends[vn] = [] + + cls._inv_depends[vn].append(func.__name__) + + @wraps(func) + def compute_or_return_saved(*args, **kwargs): + """Check if the key should be computed,""" + # extract some related info + self = args[0] # the helpee itself + + # explicitly settable kwargs. + # unless recompute flag is set False, + # it will always recompute and save them + # if you call the same function without kwargs + # the last one with kwargs will be returned + recompute = False + if kwargs: + recompute = kwargs.get("recompute", True) + + # computed arrays are called _computed. + # loop over dependencies and check if they are modified + for dependee_str in cls._depends[func.__name__]: + dependee = getattr(self, dependee_str) + # is modified? + if dependee._modified: + for inv in cls._inv_depends[dependee_str]: + self._computed._saved[inv] = None + + # is saved / want to recompute? + # recompute is added for computed values that accepts params. + saved = self._computed._saved.get(func.__name__, None) + if saved is not None and not recompute: + return saved + + # we've reached this point because we have to compute this + computed = func(*args, **kwargs) + if isinstance(computed, np.ndarray): + computed.flags.writeable = False # configurable? + self._computed._saved[func.__name__] = computed + + # so, all fresh. we can press NOT-modified button + for dependee_str in cls._depends[func.__name__]: + dependee = getattr(self, dependee_str) + dependee._modified = False + + return computed + + if make_property: + return property(compute_or_return_saved) + else: + return compute_or_return_saved + + return inner
+
+ + + +
+[docs] +class VertexData(DataHolder): + """ + Minimal manager for vertex data. Checks input array size, transforms + data on request. __setitem__ and __getitem__ will perform length checks. + key(), values(), items(), and get() will return whatever is currently + stored. + + gustaf supports two kinds of data representation: scalar-data with cmap + and vector-data with arrows. + """ + + __slots__ = () + + def __init__(self, helpee): + """Checks if helpee has vertices as attr beforehand. + + Parameters + ---------- + helpee: Vertices + Vertices and its derived classes. + """ + if not hasattr(helpee, "vertices"): + raise AttributeError("Helpee does not have `vertices`.") + + super().__init__(helpee) + + def _validate_len(self, value=None, raise_=True): + """Checks if given value is a valid vertex_data based of its length. + + If raise_, throws error, else, deletes all incompatible values. + Only checks len(). If array has (1, len) shape, this will still return + False. + + Parameters + ---------- + value: array-like + Default is None. If None, checks all existing values. + raise_: bool + Default is True, If True, raises in case of incompatibility. + + Returns + ------- + validity: bool + If raise_ is False. + """ + valid = True + helpee_len = len(self._helpee.vertices) + if value is not None: + if len(value) != helpee_len: + valid = False + + if raise_ and not valid: + raise ValueError( + f"Expected ({helpee_len}) length data, " + f"Given ({len(value)})" + ) + + return valid + + # here, check all saved values. + to_pop = [] + for key, value in self._saved.items(): + if len(value) != helpee_len: + valid = False + + if not valid: + if raise_: + raise ValueError( + f"`{key}`-data len ({len(value)}) doesn't match " + f"expected len ({helpee_len})" + ) + else: + self._logd( + f"`{key}`-data len ({len(value)}) doesn't match " + f"expected len ({helpee_len}). Deleting `{key}`." + ) + # pop invalid data + to_pop.append(key) + to_pop.append(key + "__norm") + + # pop if needed + for tp in to_pop: + self._saved.pop(tp, None) + + return valid + + def __setitem__(self, key, value): + """ + Performs len() based check before storing vertex_data. + + Parameters + ---------- + key: str + value: object + + Returns + ------- + None + """ + self._validate_len(value, raise_=True) + + # we are here because this is valid + self._saved[key] = make_tracked_array(value, copy=False).reshape( + len(self._helpee.vertices), -1 + ) + + # if "data" or "arrow_data" is empty in show_options, we want to + # set this data to show. We will always set this as "data". + show_options = getattr(self._helpee, "show_options", None) + if show_options is not None: + if "data" in show_options or "arrow_data" in show_options: + return None + show_options["data"] = key + + def __getitem__(self, key): + """ + Validates data length before returning item. + + Parameters + ---------- + key: str + + Returns + ------- + data: array-like + """ + value = super().__getitem__(key) # raises KeyError + valid = self._validate_len(value, raise_=False) + if valid: + return value + else: + raise KeyError( + "Either requested data is not stored or deleted due to " + "changes in number of vertices." + ) + +
+[docs] + def as_scalar(self, key, default=None): + """ + Returns scalar version of requested data. If it is already a scalar, + will return as is. Else, will return a norm. using `np.linalg.norm()`. + + Parameters + ---------- + key: str + default: object + + Returns + ------- + data_as_scalar: (n, 1) np.ndarray + """ + if key not in self.keys(): + return default + + # interpret scalar as norm + # save the norm once it is called. + if "__norm" not in key: + norm_key = key + "__norm" + else: + norm_key = key + key = key.replace("__norm", "") + + if norm_key in self.keys(): + saved = self[norm_key] # performs len check + # return if original is not modified + if not self[key]._modified: # check if original data is modified + return saved + else: + self._saved.pop(norm_key) + + # we are here because we have to compute norm. let's save norm + value = self[key] + if value.shape[1] == 1: + value_norm = value + else: + value_norm = np.linalg.norm(value, axis=1).reshape(-1, 1) + + # save norm + self[norm_key] = value_norm + # considered not modified + self[key]._modified = False + + return value_norm
+ + +
+[docs] + def as_arrow(self, key, default=None, raise_=True): + """ + Returns an array as is, only if it is showable as arrow. + + Parameters + ---------- + key: str + default: object + raise_: bool + + Returns + ------- + data: (n, d) np.ndarray + """ + if key not in self.keys(): + return default + + value = self[key] + if value.shape[1] == 1: + self._logd(f"as_arrow() requested data ({key}) is 1D data.") + if raise_: + raise ValueError( + f"`{key}`-data is 1D and cannot be represented as arrows." + ) + + return value
+
+ + + +Unique2DFloats = namedtuple( + "Unique2DFloats", ["values", "ids", "inverse", "intersection"] +) +Unique2DFloats.__doc__ = """ +namedtuple to hold unique information of float type arrays. +Note that for float types, "close enough" might be a better name than unique. +This way, all tracked arrays, as long as they are 2D, have a dot separated +syntax to access unique info. For example, `mesh.unique_vertices.ids`. +""" +Unique2DFloats.values.__doc__ = """`(n, d) np.ndarray` + Field number 0""" +Unique2DFloats.ids.__doc__ = """`(n, d) np.ndarray` + Field number 1""" +Unique2DFloats.inverse.__doc__ = """`(n, d) np.ndarray` + Field number 2""" +Unique2DFloats.intersection.__doc__ = """`(m) list of list` + given original array's index, returns overlapping arrays, including itself. + Field number 3 +""" + +Unique2DIntegers = namedtuple( + "Unique2DIntegers", ["values", "ids", "inverse", "counts"] +) +Unique2DIntegers.__doc__ = """ +namedtuple to hold unique information of integer type arrays. +Similar approach to Unique2DFloats. +""" + +Unique2DIntegers.values.__doc__ = """`(n, d) np.ndarray` + Field number 0""" +Unique2DIntegers.ids.__doc__ = """`(n) np.ndarray` + Field number 1""" +Unique2DIntegers.inverse.__doc__ = """`(m) np.ndarray` + Field number 2""" +Unique2DIntegers.counts.__doc__ = """`(n) np.ndarray` + Field number 3""" + + +
+[docs] +class ComputedMeshData(ComputedData): + """A class to hold computed-mesh-data. + + Subclassed to keep its own dependency info. + """ + + pass
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/helpers/notebook.html b/_modules/gustaf/helpers/notebook.html new file mode 100644 index 000000000..f2eb1b5f8 --- /dev/null +++ b/_modules/gustaf/helpers/notebook.html @@ -0,0 +1,652 @@ + + + + + + + + + + gustaf.helpers.notebook — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.helpers.notebook

+"""gustaf/gustaf/helpers/notebook.py.
+
+Enables the plotting in ipynb with k3d.
+
+There are no import guards since they are in the place where this module is
+imported. This should be enough since I do not think that this module
+will/should be used outside this place.
+"""
+
+import importlib
+
+import numpy as np
+import vedo
+from IPython.display import display
+from ipywidgets import GridspecLayout
+
+from gustaf._base import GustafBase
+
+
+
+[docs] +def get_shape(N, x, y): + """Taken verbatim from vedo plotter:show function. + + Args: + N (_type_): _description_ + x (_type_): _description_ + y (_type_): _description_ + + Returns: + _type_: _description_ + """ + nx = int(np.sqrt(int(N * y / x) + 1)) + ny = int(np.sqrt(int(N * x / y) + 1)) + lm = [ + (nx, ny), + (nx, ny + 1), + (nx - 1, ny), + (nx + 1, ny), + (nx, ny - 1), + (nx - 1, ny + 1), + (nx + 1, ny - 1), + (nx + 1, ny + 1), + (nx - 1, ny - 1), + ] + ind, minl = 0, 1000 + for i, m in enumerate(lm): + l_something = m[0] * m[1] + if N <= l_something < minl: + ind = i + minl = l_something + return lm[ind]
+ + + +
+[docs] +class K3DPlotterN(GridspecLayout, GustafBase): + """Helper to plot in notebooks with k3d. + + Sets up K3D plotter especially if multiple plots are to be shown in the + notebook. + """ + + def __init__(self, N, size, background=0xFFFFFF): + """Setups the plotter with potentially multiple plots. + + Parameters + ---------- + N: int + Number of plots to be shown. + size: (str, list) + See vedo.Plotter for details. + background: ((color, str), optional) + See vedo.Plotter for details. Defaults to 0xFFFFFF. + """ + if importlib.util.find_spec("k3d") is None: + raise ImportError( + "k3d is not installed. Please install it with `pip " + "install k3d`." + ) + self.N = N + self.x, self.y = get_shape(N, *(2160, 1440)) + self.shape = (self.x, self.y) + super().__init__(self.x, self.y) + self.vedo_plotters = [] + for _ in range(N): + self.vedo_plotters.append( + vedo.Plotter( + size=size, + bg=background, + ) + ) + + def _at_get_location(self, N): + """Gets the grid coordinate of the wanted renderer. + + Parameters + ---------- + N: int + Render id. + + Returns: + (int, int): Grid Coordinate of the wanted renderer. + """ + if (self.x * self.y) < N: + return (self.x - 1, self.y - 1) + return (N // (self.y), N % self.y) + +
+[docs] + def show( + self, list_of_showables, at, interactive, camera, axes, *args, **kwargs + ): + """Add the showables to the renderer at the given location. + + Parameters + ----------- + list_of_showables: Any + at: int + Render id. + interactive: bool + See vedo.Plotter.show for details. + camera: Any + See vedo.Plotter.show for details. + axes: bool + Add axes to the plot. Will also cast int to bool. + """ + if len(args) != 0 or len(kwargs) != 0: + self._logd(f"*args ({args}) and **kwargs ({kwargs}) ignored") + + # this converts vedo plotter to k3d plot. + # after this, vedo plotter has no relevance to what you see + self[self._at_get_location(at)] = self.vedo_plotters[at].show( + list_of_showables, + interactive=interactive, + camera=camera, + axes=axes, + )
+ + +
+[docs] + def display(self, close=True): + """Display the plotter. + + This is needed in case the plotter is the last thing in a cell. In that + case the IPython will try to call this function to display this. + """ + display(self) + + # we add option to close here, as we set default_autoclose = False + if close: + self.clear() + self.close()
+ + +
+[docs] + def clear(self, *args, **kwargs): + """Clear the plotters.""" + for v_plotter in self.vedo_plotters: + v_plotter.clear(*args, deep=True, **kwargs)
+ + +
+[docs] + def close(self): + """Closes all vedo.Plotters""" + for v_plotter in self.vedo_plotters: + v_plotter.close()
+
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/helpers/options.html b/_modules/gustaf/helpers/options.html new file mode 100644 index 000000000..ebaf076ac --- /dev/null +++ b/_modules/gustaf/helpers/options.html @@ -0,0 +1,1029 @@ + + + + + + + + + + gustaf.helpers.options — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.helpers.options

+"""gustaf/gustaf/helpers/options.py
+
+Classes to help organize options.
+"""
+
+from copy import deepcopy
+
+from gustaf.helpers._base import HelperBase
+from gustaf.helpers.raise_if import ModuleImportRaiser
+
+
+
+[docs] +class Option: + """ + Minimal Class to hold each options. Mainly to replace nested dict. + + Parameters + ---------- + backends: set + set of strings. + key: str + description: str + allowed_types: set + set of types + default: one of allwed_types + Optional. Default is None + """ + + __slots__ = ( + "backends", + "key", + "description", + "allowed_types", + "default", + ) + + def __init__( + self, backends, key, description, allowed_types, default=None + ): + """ + Check types + """ + if isinstance(backends, str): + self.backends = {backends} + elif getattr(backends, "__iter__", False): + self.backends = set(backends) + else: + raise TypeError("Invalid backends type") + + if isinstance(key, str): + self.key = key + else: + raise TypeError("Invalid key type") + + if isinstance(description, str): + self.description = description + else: + raise TypeError("Invalid description type") + + if isinstance(allowed_types, (tuple, list, set)): + self.allowed_types = tuple(allowed_types) + else: + raise TypeError("Invalid allowed_types type") + + if default is None or type(default) in self.allowed_types: + self.default = default + else: + raise TypeError(f"{type(default)} is invalid default type") + + def __repr__(self): + specific = "\n".join( + [ + "", + self.key, + "=" * len(self.key), + f"backends: {self.backends}", + "description:", + f" {self.description}", + "allowed_types:", + f" {self.allowed_types}", + super().__repr__(), + "", + ] + ) + return specific
+ + + +
+[docs] +class SetDefault: + """ + Default setter object. Can use as argument in `make_valid_options` + """ + + __slots__ = ("key", "default") + + def __init__(self, key, default): + self.key = key + self.default = default
+ + + +# predefine recurring options +vedo_common_options = ( + Option( + "vedo", + "c", + "Color in {rgb, RGB, str of (hex, name), int}", + (str, tuple, list, int), + ), + Option("vedo", "alpha", "Transparency in range [0, 1].", (float, int)), + Option( + "vedo", + "data", + "Name of vertex_data to show. " + "Object must have vertex_data with the same name.", + (str,), + ), + Option("vedo", "vertex_ids", "Show ids of vertices", (bool,)), + Option("vedo", "element_ids", "Show ids of elements", (bool,)), + Option( + "vedo", + "lighting", + "Lighting options {'default', 'metallic', 'plastic', 'shiny', " + "'glossy', 'ambient', 'off'}", + (str,), + ), + Option("vedo", "cmap", "Colormap for vertex_data plots.", (str,)), + Option("vedo", "vmin", "Minimum value for cmap", (float, int)), + Option("vedo", "vmax", "Maximum value for cmap", (float, int)), + Option( + "vedo", + "cmap_alpha", + "Colormap Transparency in range [0, 1].", + (float, int), + ), + Option( + "vedo", + "cmap_n_colors", + "Set the number of available colors", + (int,), + ), + Option( + "vedo", + "scalarbar", + "Scalarbar describing cmap. At least an empty dict or " + "dict with following items are accepted: " + "{title: str, pos: tuple, title_yoffset: int, font_size: int, " + "nlabels: int, c: str, horizontal: bool, use_alpha: bool, " + "label_format: str}. Setting bool will add a default scalarbar", + (bool, dict), + ), + Option( + "vedo", + "scalarbar3d", + "3D scalarbar describing cmap. At least an empty dict or " + "dict with following items are accepted: " + "{title: str, pos: tuple, size: list, title_font: str, " + "title_xoffset: float, title_yoffset: float, title_size: float, " + "title_rotation: float, nlabels: int, label_font:str, " + "label_size: float, label_offset: float, label_rotation: int, " + "label_format: str, draw_box: bool, above_text: str, below_text: str, " + "nan_text: str, categories: list}", + (bool, dict), + ), + Option( + "vedo", + "arrow_data", + "Name of vertex_data to plot as arrow. Corresponding data should be " + "at least 2D. If you want more control over arrows, consider creating " + "edges using gus.create.edges.from_data().", + (str,), + ), + Option( + "vedo", + "arrow_data_scale", + "Scaling factor for arrow data.", + (float, int), + ), + Option( + "vedo", + "arrow_data_color", + "Color for arrow data. Can be either cmap name or color. For " + "cmap, colors are based on the size of the arrows.", + (str, tuple, list, int), + ), + Option( + "vedo", + "axes", + "Configure a specific axes with options. Expect dict(), but setting " + "True will set a default axes. For full options, see " + "https://vedo.embl.es/autodocs/content/vedo/addons.html" + "#vedo.addons.Axes", + (bool, dict), + ), +) + + +
+[docs] +def make_valid_options(*options): + """ + Forms valid options. Should run only once during module loading. + + Parameters + ---------- + *options: Option + + Returns + ------- + valid_options: dict() + """ + valid_options = {} + for opt in options: + if isinstance(opt, Option): + # copy option object to avoid overwriting defaults + # only exception is if this option is a backend object + # and wrapped by ModuleImportRaiser + allowed_types = [] + for at in opt.allowed_types: + if isinstance(at, ModuleImportRaiser): + continue + allowed_types.append(at) + opt.allowed_types = tuple(allowed_types) + + valid_options[opt.key] = deepcopy(opt) + elif isinstance(opt, SetDefault): + # overwrite default of existing option. + if opt.key not in valid_options: + raise KeyError("Given key is not in valid_option.") + + if type(opt.default) not in valid_options[opt.key].allowed_types: + raise TypeError("Invalid default type") + valid_options[opt.key].default = opt.default + else: + raise TypeError("Please use `Option` to define options.") + + return valid_options
+ + + +
+[docs] +class ShowOption(HelperBase): + """ + Behaves similar to dict, but will only accept a set of options that's + applicable to the helpee class. Intended use is to create a + subclass that would define valid options for helpee. + Options should be described by Option object. + Helps all the way up to initializing backend showables up to their backend + specific common routines. ShowOption and ShowManager in a sense. + """ + + __slots__ = ("_options",) + + _valid_options = {} + + _helps = None + + def __init__(self, helpee): + """ + Parameters + ---------- + helpee: object + """ + self._helpee = helpee + if not type(helpee).__qualname__.startswith(self._helps): + raise TypeError( + f"This show option is for {self._helps}. " + f"Given helpee is {type(helpee)}." + ) + self._options = {} + + def __repr__(self): + """ + Friendly info prints for show option. + + Parameters + ---------- + None + + Returns + ------- + description: str + """ + valid_and_current = [] + for vo in self._valid_option.values(): + valid = str(vo) + current = "" + if vo.key in self.keys(): + current = "current option: " + str(self[vo.key]) + valid_and_current.append(valid + current) + + header = [ + f"ShowOption for {self._helps}", + ] + return "\n".join(header + valid_and_current) + + def __setitem__(self, key, value): + """ + Sets option after checking its validity. + + Parameters + ---------- + key: str + value: object + + Returns + ------- + None + """ + if key in self._valid_options: + # valid type check + if not isinstance(value, self._valid_options[key].allowed_types): + raise TypeError( + f"{type(value)} is invalid value type for '{key}'. " + f"Details for '{key}':\n" + f"{self._valid_options[key]}" + ) + + # types are valid. let's add + self._options[key] = value + + else: + raise ValueError(f"{key} is an invalid option for {self._helps}.") + + def __getitem__(self, key): + """ + operator[] + + Parameters + ---------- + key: str or iterable + + Returns + ------- + items: object or dict + """ + if isinstance(key, str): + return self._options[key] + elif hasattr(key, "__iter__"): + items = {} + for k in key: + if k in self._options: + items[k] = self._options[k] + return items + else: + raise TypeError(f"Invalid key type for {type(self)}") + + def __contains__(self, key): + """Returns if current option contains given key. + + Parameters + ---------- + key: str + + Returns + ------- + contains: bool + """ + return key in self._options + +
+[docs] + def get(self, key, default=None): + """ + Gets value from key and default. Similar to dict.get(), + but this is always safe, as it will always return None + + Parameters + ---------- + key: stir + default: object + + Returns + ------- + values: object + """ + if default is not None: + return self._options.get(key, default) + + # overwrite default with valid option's + default = getattr(self._valid_options.get(key, None), "default", None) + + return self._options.get(key, default)
+ + +
+[docs] + def update(self, **kwargs): + """ + Calls __setitem__ iteratively for validity check. + + Parameters + ---------- + **kwargs: kwargs + + Returns + ------- + None + """ + for k, v in kwargs.items(): + self.__setitem__(k, v)
+ + +
+[docs] + def valid_keys(self): + """ + Returns valid keys. + + Parameters + ---------- + None + + Returns + ------- + valid_keys: dict_keys + """ + return self._valid_options.keys()
+ + +
+[docs] + def keys(self): + """ + Registered option keys. + + Parameters + ---------- + None + + Returns + ------- + keys: dict_keys + """ + return self._options.keys()
+ + +
+[docs] + def values(self): + """ + Registered option values. + + Parameters + ---------- + None + + Returns + ------- + keys: dict_values + """ + return self._options.values()
+ + +
+[docs] + def items(self): + """ + Registered option items. + + Parameters + ---------- + None + + Returns + ------- + items: dict_items + """ + return self._options.items()
+ + +
+[docs] + def clear(self): + """ + Clears all the options. + + Parameters + ---------- + None + + Returns + ------- + None + """ + self._options.clear()
+ + +
+[docs] + def pop(self, *args, **kwargs): + """ + Calls pop() on current options + + Parameters + ---------- + None + + Returns + ------- + value: object + """ + self._options.pop(*args, **kwargs)
+ + +
+[docs] + def copy_valid_options(self, copy_to, keys=None): + """ + Copies valid option to other show_option. Simply iterates and tries. + + Parameters + ---------- + copy_to: ShowOption + keys: tuple or list + Can specify keys + + Returns + ------- + None + """ + if not isinstance(copy_to, ShowOption): + raise TypeError("copy_to should be a ShowOption") + valid_keys = copy_to.valid_keys() + + items = self[keys].items() if keys is not None else self.items() + + for key, value in items: + if key in valid_keys: + copy_to[key] = deepcopy(value) # is deepcopy necessary?
+ + + def _initialize_showable(self): + """ + Creates basic showable all the way up to backend common procedures. + + Parameters + ---------- + None + + Returns + ------- + showable: object + """ + raise NotImplementedError("Derived class must implement this method")
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/helpers/raise_if.html b/_modules/gustaf/helpers/raise_if.html new file mode 100644 index 000000000..c71b7efce --- /dev/null +++ b/_modules/gustaf/helpers/raise_if.html @@ -0,0 +1,585 @@ + + + + + + + + + + gustaf.helpers.raise_if — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.helpers.raise_if

+"""gustaf/gustaf/helpers/raise_if.py.
+
+Collection of wrapper functions/classes that raises Error with certain
+behavior
+"""
+
+from typing import Any, Optional
+
+
+
+[docs] +def invalid_inherited_attr(attr_name, qualname, property_=False): + """Returns a function that would behave the same as given function, but + would raise AttributeError. This needs to be defined in class level. + + Parameters + ---------- + func: (function) + _description_ + qualname: (class) + _description_ + property_: (bool, optional) + is this function a property?. Defaults to False. + + Returns + ------- + raiser: function + behaves same as func if `property_` is correctly defined + """ + + def raiser(): + raise AttributeError( + f"{attr_name} is not supported from {qualname} " + "and its subclasses thereof." + ) + + if property_: + return property(raiser) + + else: + return raiser
+ + + +
+[docs] +class ModuleImportRaiser: + """Mock imports optional modules if they are not installed. + + Class used to have better import error handling in the case that a + package package is not installed. This is necessary due to that some + packages are not a dependency of `gustaf`, but some parts require + them to function. Examples are `splinepy` and `vedo`. + """ + + def __init__(self, lib_name: str, error_message: Optional[str] = None): + original_message = "" + if error_message is not None: + original_message = f"\nOriginal error message - {error_message}" + self._message = str( + f"Cannot load {lib_name} package, on which requested " + "functionality depends. " + "Please refer to the installation instructions " + "[tataratat.github.io/gustaf] for more information." + f"{original_message}" + ) + + def __call__(self, *_args: Any, **_kwargs: Any) -> Any: + """Is called when the object is called by object(). + + Will notify the user, that the functionality is not accessible + and how to proceed to access the functionality. + """ + raise ImportError(self._message) + + def __getattr__(self, __name: str) -> Any: + """Is called when any attribute of the object is accessed by + object.attr. + + Will notify the user, that the functionality is not accessible + and how to proceed to access the functionality. + """ + if __name == "_ModuleImportRaiser__message": + return object.__getattr__(self, __name[-8:]) + else: + raise ImportError(self._message) + + def __setattr__(self, __name: str, __value: Any) -> None: + """ + Is called when any attribute of the object is set by object.attr = new. + Will notify the user, that the functionality is not accessible and how + to proceed to access the functionality. + """ + if __name == "_message": + object.__setattr__(self, __name, __value) + else: + raise ImportError(self._message) + + def __getitem__(self, key): + """Is called when the object is subscripted object[x]. + + Will notify the user, that the functionality is not accessible + and how to proceed to access the functionality. + """ + raise ImportError(self._message)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/default.html b/_modules/gustaf/io/default.html new file mode 100644 index 000000000..ae2794dfc --- /dev/null +++ b/_modules/gustaf/io/default.html @@ -0,0 +1,519 @@ + + + + + + + + + + gustaf.io.default — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.default

+import pathlib
+
+from gustaf.io import meshio, mfem, mixd
+
+
+
+[docs] +def load(fname): + """Load function for all supported file formats. + + This function tries to guess the correct io module for the given file. + + Parameters + ----------- + fname: Union[str, pathlib.Path] + Name of the file to be loaded. + + Returns + -------- + MESH_TYPES: + Loaded mesh. + """ + extensions_to_load_functions = { + ".mixd": mixd.load, + ".mfem": mfem.load, + ".msh": meshio.load, + } + + fname = pathlib.Path(fname).resolve() + + if fname.suffix in extensions_to_load_functions: + return extensions_to_load_functions[fname.suffix](fname) + + else: + raise ValueError( + f"Failed to load given file with '{fname.suffix}' extension. " + "Valid extensions are: " + f"{tuple(extensions_to_load_functions.keys())}." + )
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/ioutils.html b/_modules/gustaf/io/ioutils.html new file mode 100644 index 000000000..ffdb36b30 --- /dev/null +++ b/_modules/gustaf/io/ioutils.html @@ -0,0 +1,536 @@ + + + + + + + + + + gustaf.io.ioutils — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.ioutils

+"""gustaf/gustaf/io/ioutils.py.
+
+utils for lord load and his expected expertise, export.
+"""
+
+import os
+
+
+
+[docs] +def abs_fname(fname): + """Checks if fname is abs. If not, returns abs. Tilde safe. + + Parameters + ----------- + fname: str + + Returns + -------- + abs_fname: str + Maybe same as fname, maybe not. + """ + if os.path.isabs(fname): + pass + # elif fname.startswith("~"): + elif "~" in fname: + fname = os.path.expanduser(fname) + else: + fname = os.path.abspath(fname) + + return fname
+ + + +
+[docs] +def check_and_makedirs(fname): + """Checks if the directories of the path exists. If not, makedirs! + + Parameters + ----------- + fname: str + + Returns + -------- + None + """ + dirs = os.path.dirname(fname) + + if dirs == "": + return None + + if not os.path.isdir(dirs): + os.makedirs(dirs) + + return None
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/meshio.html b/_modules/gustaf/io/meshio.html new file mode 100644 index 000000000..3fe5ef3ad --- /dev/null +++ b/_modules/gustaf/io/meshio.html @@ -0,0 +1,674 @@ + + + + + + + + + + gustaf.io.meshio — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.meshio

+"""Import a meshio based mesh,
+
+Export can only happen after it is possible to save and define boundaries in
+gustaf.
+"""
+
+import pathlib
+
+import numpy as np
+
+from gustaf.edges import Edges
+from gustaf.faces import Faces
+from gustaf.helpers.raise_if import ModuleImportRaiser
+from gustaf.utils import log
+from gustaf.vertices import Vertices
+from gustaf.volumes import Volumes
+
+try:
+    import meshio
+except ModuleNotFoundError as err:
+    meshio = ModuleImportRaiser("meshio", err)
+
+_meshio2gus = {
+    "hexahedron": Volumes,
+    "tetra": Volumes,
+    "quad": Faces,
+    "triangle": Faces,
+    "line": Edges,
+    "vertex": Vertices,
+}
+
+
+
+[docs] +def load(fname): + """Load mesh in meshio format. Loads vertices and their connectivity. + Currently cannot process boundary. + + Note + ----- + This is more or less a direct copy from the original gustav implementation. + A lot of the meshio information are lost. When boundaries and multi-patch + definitions are added this needs to be revisited and extended. + + Parameters + ------------ + fname: str | pathlib.Path + + Returns + -------- + MESH_TYPES | List[MESH_TYPES] + """ + # fname sanity check + fname = pathlib.Path(fname) + if not (fname.exists() and fname.is_file()): + raise ValueError( + "The given file does not point to file. The given path is: " + f"{fname.resolve()}" + ) + + # load + meshio_mesh: meshio.Mesh = meshio.read(fname) + + # first get vertices + vertices = meshio_mesh.points + + # early exit if cells doesn't exist + if len(meshio_mesh.cells_dict) == 0: + return Vertices(vertices) + + meshes = [] + for element_type, elements in meshio_mesh.cells_dict.items(): + # skip unsupported + if element_type not in _meshio2gus: + log.warning( + f"`{element_type}`-elements are not supported in gustaf" + ) + continue + if element_type.startswith("vertex"): + meshes.append(Vertices(vertices[elements.ravel()])) + else: + meshes.append( + _meshio2gus[element_type](vertices, elements=elements) + ) + + return meshes[0] if len(meshes) == 1 else meshes
+ + + +
+[docs] +def export(fname, mesh, submeshes=None, **kwargs): + """Export mesh elements and vertex data into meshio and use its write + function. The definition of submeshes with identical vertex coordinates + is possible. In that case vertex numbering and data from the main mesh + are used. For more export options, refer to meshio's documentation + https://github.com/nschloe/meshio . + + .. code-block:: python + + import gustaf + + # define coordinates + v = np.array( + [ + [0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [0.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + ] + ) + # define triangle connectivity + tf = np.array( + [ + [1, 0, 2], + [0, 1, 5], + [3, 2, 6], + [2, 0, 4], + [4, 5, 7], + [2, 3, 1], + [7, 5, 1], + [6, 7, 3], + [4, 6, 2], + [7, 6, 4], + ] + ) + # init tri faces + mesh = gus.Faces( + vertices=v, + faces=tf, + ) + gustaf.io.meshio.export(mesh, "tri-mesh.stl") + + Parameters + ------------ + fname: Union[str, pathlib.Path] + File to save the mesh in. + mesh: Edges, Faces or Volumes + Input mesh + submeshes: Iterable + Submeshes where the vertices are identical to the main mesh. The element + type can be identical to mesh.elements or lower-dimensional (e.g. + boundary elements). + **kwargs : Any + Any additional argument will be passed to the respective meshio `write` + function. See meshio docs for more information + + Raises + ------- + NotImplementedError: + For mesh types that are not implemented. + ValueError: + Raises a value error, if the vertices indexed in a subset are not + present in the main mesh. + """ + + # Mapping between meshio cell types and gustaf cell types + meshio_dict = { + "edges": "line", + "tri": "triangle", + "quad": "quad", + "tet": "tetra", + "hexa": "hexahedron", + } + + cells = [] + # Merge main mesh and submeshes in one list + meshes = mesh if isinstance(mesh, list) else [mesh] + + if submeshes is not None: + meshes.extend(submeshes) + + # Iterate the meshes and extract the element information in meshio format + for m in meshes: + whatami = m.whatami + if whatami not in meshio_dict: + raise NotImplementedError( + f"{whatami}-type meshes not supported (yet)." + ) + elif np.any(m.elements > len(m.vertices) - 1): + raise ValueError("Invalid vertex IDs in submesh connectivity.") + else: + cells.append((meshio_dict[whatami], m.elements)) + + # Export data to meshio and write file + meshio.Mesh( + points=mesh.vertices, + cells=cells, + point_data=mesh.vertex_data._saved, + ).write(fname, **kwargs)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/mfem.html b/_modules/gustaf/io/mfem.html new file mode 100644 index 000000000..deed20751 --- /dev/null +++ b/_modules/gustaf/io/mfem.html @@ -0,0 +1,688 @@ + + + + + + + + + + gustaf.io.mfem — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.mfem

+"""gustaf/gustaf/io/mfem.py.
+
+io functions for mfem. Supports simple linear elements (straight meshes)
+For detailed information, see: https://mfem.org/mesh-
+format-v1.0/#straight-meshes
+"""
+
+import numpy as np
+
+from gustaf import settings
+from gustaf.faces import Faces
+from gustaf.volumes import Volumes
+
+geometry_types = {
+    "POINT": 0,
+    "SEGMENT": 1,
+    "TRIANGLE": 2,
+    "SQUARE": 3,
+    "TETRAHEDRON": 4,
+    "CUBE": 5,
+    "PRISM": 6,
+}
+
+
+
+[docs] +def load(fname): + """Load mesh in MFEM format. Loads vertices and their connectivity. + Currently cannot process boundary. + + Parameters + ------------ + fname: str + + Returns + ------------ + mesh + """ + + def extract_values(fname, start_index, n_lines, total_lines, dtype): + """Extract information from file. Reads [n_lines] lines from file + [fname] starting at line [start_index] and returns array of type + [dtype]. + + Parameters + ------------ + fname: str + start_index: int + n_lines: int + total_lines: int + Number of total lines of file + dtype: (NumPy) data type + + Returns + ------------ + NumPy Array + """ + end_index = total_lines - (start_index + n_lines + 2) + return np.genfromtxt( + fname, + delimiter=" ", + skip_header=start_index, + skip_footer=end_index, + dtype=dtype, + ) + + with open(fname) as f: + lines = f.readlines() + total_lines = len(lines) + + # Read values of keywords + keywords = ["dimension", "elements", "boundary", "vertices"] + indices = [lines.index(f"{keyword}\n") for keyword in keywords] + dimension, n_elements, n_boundaries, n_vertices = ( + int(lines[index + 1]) for index in indices + ) + vdim = int(lines[indices[-1] + 2]) + # Extract values + elements = extract_values( + fname, indices[1] + 2, n_elements, total_lines, settings.INT_DTYPE + ) + if elements.shape[0] != n_elements: + raise ValueError("Number of elements do not match.") + boundary = extract_values( + fname, + indices[2] + 2, + n_boundaries, + total_lines, + settings.INT_DTYPE, + ) + if boundary.shape[0] != n_boundaries: + raise ValueError("Number of boundaries do not match.") + vertices = extract_values( + fname, + indices[3] + 3, + n_vertices, + total_lines, + settings.FLOAT_DTYPE, + ) + if vertices.shape != (n_vertices, vdim): + raise ValueError("Number of vertices do not match.") + + connectivity = elements[:, 2:] + if dimension == 2: + mesh = Faces(vertices=vertices, faces=connectivity) + elif dimension == 3: + mesh = Volumes(vertices=vertices, volumes=connectivity) + + return mesh
+ + + +
+[docs] +def export(fname, mesh): + """Export mesh in MFEM format. Supports 2D triangle and quadrilateral + meshes. Does not support different element attributes or difference in + vertex dimension and mesh dimension. + + Parameters + ------------ + fname: str + mesh: Faces + + Returns + ------------ + None + """ + # Basic infos + nvertices, dim = mesh.vertices.shape + + def format_array(array): + """Format NumPy array into string. Each entry in a row is separated by + a blank space and every row is separated by a new line. + + Parameters + ------------ + array: NumPy array + + Returns + ------------ + str + """ + row_strings = [" ".join(map(str, row)) for row in array] + return "\n".join(row_strings) + + # Export 2D mesh + if dim == 2: + # Elements + element_attribute = 1 # Other numbers not yet supported + elements = mesh.elements + n_elements, n_element_vertices = elements.shape + if n_element_vertices == 3: + geometry_type = geometry_types["TRIANGLE"] + elif n_element_vertices == 4: + geometry_type = geometry_types["SQUARE"] + else: + raise NotImplementedError( + "Sorry, we cannot export mesh with elements " + f"with {n_element_vertices} vertices." + ) + e = np.ones((n_elements, 1), dtype=settings.INT_DTYPE) + elements_array = np.hstack( + (element_attribute * e, geometry_type * e, elements) + ) + elements_array_string = format_array(elements_array) + elements_string = f"elements\n{n_elements}\n" + elements_string += f"{elements_array_string}\n\n" + + # Boundary + edges = mesh.edges() + nboundary_edges = sum(map(len, mesh.BC.values())) + boundary_array = np.empty( + (nboundary_edges, 4), dtype=settings.INT_DTYPE + ) + startrow = 0 + # Add boundary one by one as SEGMENTs + for bid, edgeids in mesh.BC.items(): + nedges = len(edgeids) + e = np.ones(nedges).reshape(-1, 1) + vertex_list = edges[edgeids, :] + boundary_array[startrow : (startrow + nedges), :] = np.hstack( + (int(bid) * e, geometry_types["SEGMENT"] * e, vertex_list) + ) + startrow += nedges + + boundary_array_string = format_array(boundary_array) + boundary_string = f"boundary\n{nboundary_edges}\n" + boundary_string += f"{boundary_array_string}\n\n" + + # Vertices + vdim = 2 # Currently only option + vertices_array_string = format_array(mesh.vertices) + vertices_string = f"vertices\n{nvertices}\n{vdim}\n" + vertices_string += f"{vertices_array_string}" + + with open(fname, "w") as f: + f.write("MFEM mesh v1.0\n\n") + f.write(f"dimension\n{dim}\n\n") + f.write(elements_string) + f.write(boundary_string) + f.write(vertices_string) + + # Export 3D mesh + else: + raise NotImplementedError( + f"Sorry, we cannot export mesh of dimension {dim}." + )
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/mixd.html b/_modules/gustaf/io/mixd.html new file mode 100644 index 000000000..721995b3c --- /dev/null +++ b/_modules/gustaf/io/mixd.html @@ -0,0 +1,798 @@ + + + + + + + + + + gustaf.io.mixd — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.mixd

+"""gustaf/gustaf/io/mixd.py.
+
+io functions for mixd.
+"""
+
+import os
+import struct
+
+import numpy as np
+
+from gustaf import settings
+from gustaf.faces import Faces
+from gustaf.io.ioutils import abs_fname, check_and_makedirs
+from gustaf.utils import log
+from gustaf.utils.arr import close_rows
+from gustaf.volumes import Volumes
+
+
+
+[docs] +def load( + simplex=True, + volume=False, + fname=None, + mxyz=None, + mien=None, + mrng=None, +): + """mixd load. To avoid reading minf, all the crucial info can be given as + params. Default input will try to import `mxyz`, `mien`, `mrng` from + current location and assumes mesh is 2D triangle. + + Parameters + ----------- + simplex: bool + Default is True. Is it triangle based? + volume: bool + Default is False. Is it 3D? + fname: str + Default is None. Specify your mixd file names with ".xns" postfix. + Ex) "gustaf.xns" will try to load "gustaf.mxyz", "gustaf.mien", + and "gustaf.mrng" + mxyz: str + Default is None. + mien: str + Default is None. + mrng: str + Default is None. This is optional. + + Returns + -------- + mesh: Faces or Volumes + """ + # figure out input type + specified_input = mxyz is not None # bare minimum input + fname_input = (fname is not None) and not specified_input + default_input = not (fname_input or specified_input) + + if default_input: + mxyz = "mxyz" + mien = "mien" + mrng = "mrng" + + elif fname_input: + fname = abs_fname(fname) + fbase, ext = os.path.splitext(fname) + + if os.path.basename(fbase) == "_": + fbase = fbase[:-1] + else: + fbase += "." + + mxyz = fbase + "mxyz" + mien = fbase + "mien" + mrng = fbase + "mrng" + + # vertices + vertices = np.fromfile(mxyz, dtype=">d").astype(np.float64) + + # connec + connec = None + try: + connec = (np.fromfile(mien, dtype=">i") - 1).astype(np.int32) + except BaseException: + log.debug(f"mien file, `{mien}`, does not exist. Skipping.") + + # boundary conditions + bcs = {} + try: + bcs_in = np.fromfile(mrng, dtype=">i").astype(np.int32) # flattened + uniq_bcs_in = np.unique(bcs_in) + uniq_bcs_in = uniq_bcs_in[uniq_bcs_in > 0] # keep only natural nums + sub_elem_ids = np.arange(bcs_in.size) + + for ubci in uniq_bcs_in: + bcs.update({str(ubci): sub_elem_ids[bcs_in == ubci]}) + + except BaseException: + log.debug(f"mrng file, `{mrng}`, does not exist. Skipping.") + + # reshape vertices + vertices = vertices.reshape(-1, 3) if volume else vertices.reshape(-1, 2) + + # reshape connec + if connec is not None: + ncol = 3 if simplex and not volume else 4 + ncol = 8 if ncol == 4 and volume and not simplex else ncol + + connec = connec.reshape(-1, ncol) + + mesh = Volumes(vertices, connec) if volume else Faces(vertices, connec) + + # bc + if len(bcs) != 0: + mesh.BC = bcs + + return mesh
+ + + +
+[docs] +def export( + fname, + mesh, + space_time=False, + dual=False, +): + """Export in mixd format. Supports triangle, quadrilateral, tetrahedron, + and hexahedron semi-discrete and (flat) space-time mesh output. + + Parameters + ----------- + mesh: Faces or Volumes + fname: str + space_time: bool + Export Mesh as Space-Time Slab for discontinuous space-time + dual: bool + Includes dual-subelement information. + + Returns + -------- + None + """ + # did you give us an acceptable mesh? + acceptable_shapes = ["tri", "quad", "tet", "hexa"] + whatami = mesh.whatami + + if whatami not in acceptable_shapes: + raise NotImplementedError( + f"Sorry, we can't export {whatami}-shape in mixd format." + ) + + # prepare export location + fname = abs_fname(fname) + check_and_makedirs(fname) + + # basic infos + dim = mesh.vertices.shape[1] + big_endian_int = ">i" + big_endian_double = ">d" + + # prep files + fbase, ext = os.path.splitext(fname) + + if ext.startswith(".xns"): + # frequently used case in practice. no base export + if os.path.basename(fbase) == "_": + fdir = os.path.dirname(fbase) + vert_file = os.path.join(fdir, "mxyz") + connec_file = os.path.join(fdir, "mien") + bc_file = os.path.join(fdir, "mrng") + info_file = os.path.join(fdir, "minf") + dual_file = os.path.join(fdir, "dual") + + else: + fbase += "." + vert_file = fbase + "mxyz" + connec_file = fbase + "mien" + bc_file = fbase + "mrng" + info_file = fbase + "minf" + dual_file = fbase + "dual" + + else: + raise NotImplementedError("`mixd` format only supports xns.") + + # write v + with open(vert_file, "wb") as vf: + for v in mesh.vertices.ravel(): + vf.write(struct.pack(big_endian_double, v)) + + if space_time: + for v in mesh.vertices.ravel(): + vf.write(struct.pack(big_endian_double, v)) + + # write connec + with open(connec_file, "wb") as cf: + for c in mesh.elements.ravel() + 1: + cf.write(struct.pack(big_endian_int, c)) + + # get boundaries of each element - subelement interface array + sub_interface = make_mrng(mesh) + + # write bc first - after writing it, we can modify inplace for dual. + with open(bc_file, "wb") as bf: + for b in sub_interface: + bf.write(struct.pack(big_endian_int, b)) + + # if dual is True, we fill dual infos. + if dual: + sub_elements = mesh.to_subelements(False) + # this should be always dividable without remnants + n_subelem_per_elem, rem = divmod( + len(sub_elements.elements), len(mesh.elements) + ) + if rem != 0: + raise ValueError( + "something went wrong with subelement creation." + "Please report this issue, thank you!" + ) + + # get intersection - can use this info to determine duals + _, _, _, intersections = close_rows( + sub_elements.centers(), settings.TOLERANCE, True + ) + + # loop intersections and look for 2 intersections + for i, intersection in enumerate(intersections): + n_inter = len(intersection) + + # we modify interface only if there're 2 intersections. + if n_inter == 2: + # intersection is always sorted. + # we don't want dual to point to itself + dual_id = 0 if i != intersection[0] else 1 + + # get element number and apply fortran's offset, 1 + sub_interface[i] = -int( + intersection[dual_id] // n_subelem_per_elem + 1 + ) + continue + + # intersection should be at most 2. Otherwise, it either means + # that you have a bad mesh or to big tolerance + if n_inter > 2: + raise ValueError( + f"{i}-th subelement overlaps more than once. " + "Please check your elements or decrease " + "gustaf.settings.TOLERANCE." + ) + + # write dual + with open(dual_file, "wb") as df: + for d in sub_interface: + df.write(struct.pack(big_endian_int, d)) + + # write info + with open(info_file, "w") as infof: # if and inf... just can't + infof.write(f"# dim: {dim}\n") + infof.write(f"# mesh type: {whatami}\n\n") + + st_factor = 2 if space_time else 1 + infof.write(f"nn {int(mesh.vertices.shape[0] * st_factor)}\n") + infof.write(f"ne {int(mesh.elements.shape[0])}\n") + infof.write(f"nsd {dim}\n") + infof.write(f"nen {int(mesh.elements.shape[1] * st_factor)}\n") + + if space_time: + infof.write("space-time on\n\n\n") + else: + infof.write("semi-discrete on\n\n\n") + + # BC guide + infof.write("# boundary name : referenced number.\n") + for i, bname in enumerate(mesh.BC.keys()): + infof.write(f"# {bname} : {i + 1}\n") + + # signature + infof.write("\n\n\n# MIXD generated using `gustaf`.\n")
+ + + +
+[docs] +def make_mrng(mesh): + """ + Builds and return mrng array based on `mesh.BC` + Supports `Faces` and `Volumes`. + + Parameters + ----------- + mesh: Faces or Volumes + Number of participating elements + + Returns + -------- + boundaries : ndarray + The mrng-array. + """ + + # determine number of sub elements + whatami = mesh.whatami + nbelem = 3 + + if whatami.startswith("quad") or whatami.startswith("tet"): + nbelem += 1 + elif whatami.startswith("hexa"): + nbelem += 3 + + # init boundaries with 0, as boundaries are marked with positive numbers + # staring from 1 and dual infos with negative values, starting with -1 + boundaries = np.empty(mesh.elements.shape[0] * nbelem, dtype=int) + boundaries[:] = 0 + + for i, belem_ids in enumerate(mesh.BC.values()): + boundaries[belem_ids] = i + 1 # bid starts at 1 + + return boundaries
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/io/nutils.html b/_modules/gustaf/io/nutils.html new file mode 100644 index 000000000..a5780040d --- /dev/null +++ b/_modules/gustaf/io/nutils.html @@ -0,0 +1,642 @@ + + + + + + + + + + gustaf.io.nutils — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.io.nutils

+"""gustaf/gustaf/io/nutils.py.
+
+io functions for nutils.
+"""
+
+import numpy as np
+
+from gustaf.faces import Faces
+from gustaf.io import mixd
+from gustaf.io.ioutils import abs_fname, check_and_makedirs
+from gustaf.volumes import Volumes
+
+
+
+[docs] +def load(fname): + """nutils load. + Loads a nutils (np.savez) file and returns a Gustaf Mesh. + + Parameters + ----------- + fname: str + The npz file needs the following keys: + nodes, cnodes, coords, tags, btags, ptags. + + Returns + -------- + mesh: Faces or Volumes + """ + npz_file = np.load(fname, allow_pickle=True) + nodes = npz_file["nodes"] + _ = npz_file["cnodes"] + coords = npz_file["coords"] + _ = npz_file["tags"].item() + btags = npz_file["btags"].item() + _ = npz_file["ptags"].item() + + if nodes.shape[0] == 0: + raise TypeError("Can not find nodes. Check nutils mesh description.") + if coords.shape[0] == 0: + raise TypeError("Can not find coords. Check nutils mesh description.") + + vertices = coords + + # connec + simplex = True + connec = nodes + + volume = vertices.shape[1] != 2 + + # reshape connec + try: + ncol = 3 if simplex and not volume else 4 + connec = connec.reshape(-1, ncol) + mesh = Volumes(vertices, connec) if volume else Faces(vertices, connec) + except BaseException: + raise RuntimeError( + "Can not generate a mesh from the nutils input." + "Check nutils mesh description." + ) + + mesh.BC = btags + return mesh
+ + + +
+[docs] +def export(fname, mesh): + """Export in Nutils format. Files are saved as np.savez(). + Supports triangle,and tetrahedron Meshes. + + Parameters + ----------- + fname: str + mesh: Faces or Volumes + + Returns + -------- + None + """ + + dic = to_nutils_simplex(mesh) + + # prepare export location + fname = abs_fname(fname) + check_and_makedirs(fname) + + np.savez(fname, **dic)
+ + + +
+[docs] +def to_nutils_simplex(mesh): + """Converts a Gustaf_Mesh to a Dictionary, which can be interpreted + by ``nutils.mesh.simplex(**to_nutils_simplex(mesh))``. Only works for + Triangles and Tetrahedrons! + + Parameters + ----------- + mesh: Faces or Volumes + + Returns + -------- + dic_to_nutils: dict + """ + + vertices = mesh.vertices + faces = mesh.faces + whatami = mesh.whatami + + # In 2D, element = face. In 3D, element = volume. + if whatami.startswith("tri"): + dimension = 2 + permutation = [1, 2, 0] + elements = faces + elif whatami.startswith("tet"): + dimension = 3 + permutation = [2, 3, 1, 0] + volumes = mesh.volumes + elements = volumes + else: + raise TypeError("Only Triangle and Tetrahedrons are accepted.") + + dic_to_nutils = {} + + # Sort the Node IDs for each Element. + sort_array = np.argsort(elements, axis=1) + elements_sorted = np.take_along_axis(elements, sort_array, axis=1) + + # Let`s get the Boundaries + bcs = {} + bcs_in = mixd.make_mrng(mesh) + bcs_in = np.ndarray.reshape( + bcs_in, (int(len(bcs_in) / (dimension + 1)), (dimension + 1)) + ) + + bound_id = np.unique(bcs_in) + bound_id = bound_id[bound_id > 0] + + # Reorder the mrng according to nutils permutation: swap columns + bcs_in[:, :] = bcs_in[:, permutation] + + # Let's reorder the bcs file with the sort_array + bcs_sorted = np.take_along_axis(bcs_in, sort_array, axis=1) + + for bi in bound_id: + bcs[str(bi)] = np.argwhere(bcs_sorted == bi) + + dic_to_nutils.update( + { + "nodes": elements_sorted, + "cnodes": elements_sorted, + "coords": vertices, + "tags": {}, + "btags": bcs, + "ptags": {}, + } + ) + + return dic_to_nutils
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/show.html b/_modules/gustaf/show.html new file mode 100644 index 000000000..eef7eba18 --- /dev/null +++ b/_modules/gustaf/show.html @@ -0,0 +1,1016 @@ + + + + + + + + + + gustaf.show — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.show

+"""gustaf/gustaf/show.py.
+
+Everything related to show/visualization.
+"""
+
+import sys
+
+import numpy as np
+
+from gustaf import utils
+
+try:
+    from gustaf.helpers.notebook import K3DPlotterN
+except ImportError as err:
+    from gustaf.helpers.raise_if import ModuleImportRaiser
+
+    K3DPlotterN = ModuleImportRaiser("IPython and ipywidgets", err)
+
+# @linux it raises error if vedo is imported inside the function.
+try:
+    import vedo
+
+    # class name UGrid is deprecated since 2023.5.0
+    # After *.5.1 release, we could remove this part by bumping min. version
+    # requirement
+    if vedo.__version__ < "2023.5.0":
+        vedoUGrid = vedo.UGrid
+    else:
+        vedoUGrid = vedo.UnstructuredGrid
+except ImportError as err:
+    # overwrites the vedo module with an object which will throw an error
+    # as soon as it is used the first time. This means that any non vedo
+    # functionality works as before, but as soon as vedo is used a
+    # comprehensive exception will be raised which is understandable in
+    # contrast to the possible errors previously possible
+    from gustaf.helpers.raise_if import ModuleImportRaiser
+
+    vedo = ModuleImportRaiser("vedo", err)
+    vedoUGrid = vedo
+
+
+# enable `gus.show()`
+# taken from https://stackoverflow.com/questions/1060796/callable-modules
+# will use this until this module is renamed
+class _CallableShowDotPy(sys.modules[__name__].__class__):
+    def __call__(self, *args, **kwargs):
+        """call show()"""
+        return show(*args, **kwargs)
+
+
+sys.modules[__name__].__class__ = _CallableShowDotPy
+
+
+# True if the current environment is IPython else False.
+try:
+    from IPython import get_ipython
+
+    is_ipython = get_ipython() is not None
+except ImportError:
+    is_ipython = False
+
+
+
+[docs] +def show(*args, **kwargs): + """`vedo.show` wrapper. Each args represent one section of window. In other + words len(args) == N, where N corresponds to the parameter for vedo.show(). + + Parameters + ----------- + *args: Union[List[Union[gustaf_obj, vedo_obj]], Dict[str, Any]]] + """ + # vedo plotter parameter + N = len(args) + offs = kwargs.get("offscreen", False) + interact = kwargs.get("interactive", True) + plt = kwargs.get("vedoplot", None) + skip_clear = kwargs.get("skip_clear", False) + close = kwargs.get("close", None) + size = kwargs.get("size", "auto") + cam = kwargs.get("cam", None) + title = kwargs.get("title", "gustaf") + background = kwargs.get("background", "white") + return_show_list = kwargs.get("return_showable_list", False) + axes = kwargs.get("axes", None) + + def clear_vedo_plotter(plotter, num_renderers, skip_cl=skip_clear): + """enough said.""" + # for whatever reason it is desired + if skip_cl: + return None + + # tmp workaround for linux + vedo_renderers = getattr(plotter, "renderers", None) + if vedo_renderers is not None and len(vedo_renderers) < num_renderers: + return None + + for i in range(num_renderers): + plotter.clear(at=i, deep=True) + + return None + + def cam_tuple_to_list(dict_cam): + """if entity is tuple, turns it into list.""" + if dict_cam is None: + return None + + for key, value in dict_cam.items(): + if isinstance(value, tuple): + dict_cam[key] = list(value) + + return dict_cam + + # get plotter + if plt is None: + if is_ipython and vedo.settings.default_backend == "k3d": + vedo.settings.backend_autoclose = False + plt = K3DPlotterN(N, size, background) + else: + if is_ipython: + utils.log.warning( + "Gustaf plotting in notebooks is only supported with k3d" + "backend. To use this backend, set " + "vedo.settings.default_backend = 'k3d' in your notebook." + " Using the default backend might give unexpected results " + "and errors." + ) + plt = vedo.Plotter( + N=N, + sharecam=False, + offscreen=offs, + size=size, + title=title, + bg=background, + ) + + else: + if is_ipython: + utils.log.warning( + "Please do not provide a plotter in IPython applications." + "This will produce an error shortly." + ) + # check if plt has enough Ns + trueN = np.prod(plt.shape) + clear_vedo_plotter(plt, trueN) # always clear. + if trueN != N: + utils.log.warning( + "Number of args exceed given vedo.Plotter's capacity.", + "Assigning a new one", + ) + title = plt.title + if close: # only if it is explicitly stated + plt.close() # Hope that this truly releases.. + # assign a new one + plt = vedo.Plotter( + N=N, + sharecam=False, + offscreen=offs, + size=size, + title=title, + bg=background, + ) + + # loop and plot + for i, arg in enumerate(args): + # form valid input type. + if isinstance(arg, dict): + show_list = list(arg.values()) + elif isinstance(arg, list): + show_list = arg.copy() + else: + # raise TypeError( + # "For vedo_show, only list or dict is valid input") + utils.log.debug( + "one of args for show_vedo is neither `dict` nor", + "`list`. Putting it naively into a list.", + ) + show_list = [arg] + + # quick check if the list is gustaf or non-gustaf + # if gustaf, make it vedo-showable. + # if there's spline, we need to pop the element and + # extend showables to the list. + # A show_list is a list to be plotted into a single sub frame of the + # plot + list_of_showables = [] + for sl in show_list: + if not isinstance(sl, list): + sl = [sl] # noqa: PLW2901 + for _k, item in enumerate(sl): + if hasattr(item, "showable"): + tmp_showable = item.showable(**kwargs) + # splines return dict + # - maybe it is time to do some typing.. + if isinstance(tmp_showable, dict): + # add to extend later + list_of_showables.extend(list(tmp_showable.values())) + else: + # replace gustaf_obj with vedo_obj. + list_of_showables.append(tmp_showable) + else: + list_of_showables.extend(sl) + # set interactive to true at last element + if int(i + 1) == len(args): + plt.show( + list_of_showables, + at=i, + interactive=interact, + camera=cam_tuple_to_list(cam), + axes=axes, + ) + + else: + plt.show( + list_of_showables, + at=i, + interactive=False, + camera=cam_tuple_to_list(cam), + axes=axes, + ) + + if is_ipython: + plt.display(close=close) + return None + + if interact and not offs: + # only way to ensure memory is released + clear_vedo_plotter(plt, np.prod(plt.shape)) + + if close or close is None: # explicitly given or None. + # It seems to leak some memory, but here it goes. + plt.close() # if i close it, this cannot be reused... + plt = None + if return_show_list: + return (plt, list_of_showables) + else: + return plt
+ + + +
+[docs] +def make_showable(obj, as_dict=False, **kwargs): + """Generates a vedo obj based on `kind` attribute from given obj, as well + as show_options. + + Parameters + ----------- + obj: gustaf obj + as_dict: bool + If True, returns vedo objects in a dict. Corresponding main objects will + be available with ["main"] key. Else, returns vedo.Assembly object, + where all the objects are grouped together. + **kwargs: kwargs + Will try to overwrite applicable items. + + Returns + -------- + vedo_obj: vedo obj + """ + # in case kwargs are defined, we will make a copy of the object and + # try to overwrite all the applicable kwargs. + if kwargs: + # keep original ones and assign new show_options temporarily + orig_show_options = obj.show_options + obj._show_options = obj.__show_option__(obj) + orig_show_options.copy_valid_options(obj.show_options) + for key, value in kwargs.items(): + try: + obj.show_options[key] = value + except BaseException: + utils.log.debug( + f"Skipping invalid option {key} for " + f"{obj.show_options._helps}" + ) + continue + + # minimal-initialization of vedo objects + vedo_obj = obj.show_options._initialize_showable() + # as dict? + if as_dict: + return_as_dict = {} + + # set common values. Could be a perfect place to try :=, but we want to + # support p3.6. + c = obj.show_options.get("c", None) + if c is not None: + vedo_obj.c(c) + + alpha = obj.show_options.get("alpha", None) + if alpha is not None: + vedo_obj.alpha(alpha) + + lighting = obj.show_options.get("lighting", None) + if lighting is not None: + vedo_obj.lighting(lighting) + + vertex_ids = obj.show_options.get("vertex_ids", False) + element_ids = obj.show_options.get("element_ids", False) + # special treatment for vertex + if obj.kind.startswith("vertex"): + vertex_ids = vertex_ids | element_ids + if element_ids: + utils.log.debug( + "`element_ids` option is True for Vertices. Overwriting it as" + "vertex_ids." + ) + element_ids = False + if vertex_ids: + # use vtk font. supposedly faster. And differs from cell id. + vertex_ids = vedo_obj.labels("id", on="points", font="VTK") + if not as_dict: + vedo_obj += vertex_ids + else: + return_as_dict["vertex_ids"] = vertex_ids + if element_ids: + # should only reach here if this obj is not vertex + element_ids = vedo.Points(obj.centers()).labels("id", on="points") + if not as_dict: + vedo_obj += element_ids + else: + return_as_dict["element_ids"] = element_ids + + # data plotting + data = obj.show_options.get("data", None) + vertex_data = obj.vertex_data.as_scalar(data, None) + if data is not None and vertex_data is not None: + # transfer data + if obj.kind.startswith("edge"): + vedo_obj.pointdata[data] = vertex_data[obj.edges].reshape( + -1, vertex_data.shape[1] + ) + else: + vedo_obj.pointdata[data] = vertex_data + + # form cmap kwargs for init + cmap_keys = ("vmin", "vmax") + cmap_kwargs = obj.show_options[cmap_keys] + # set a default cmap if needed + cmap_kwargs["input_cmap"] = obj.show_options.get("cmap", "plasma") + cmap_kwargs["alpha"] = obj.show_options.get("cmap_alpha", 1) + # Discrete set of colors (vedo default is 256) + cmap_kwargs["n_colors"] = obj.show_options.get("cmap_n_colors", 256) + # add data + cmap_kwargs["input_array"] = data + + # set cmap + # pass input_cmap as positional arg to support 2023.4.3. + # arg name changed in 2023.4.4 + vedo_obj.cmap(cmap_kwargs.pop("input_cmap"), **cmap_kwargs) + + # at last, scalarbar + sb_kwargs = obj.show_options.get("scalarbar", None) + if sb_kwargs is not None and sb_kwargs is not False: + sb_kwargs = {} if isinstance(sb_kwargs, bool) else sb_kwargs + vedo_obj.add_scalarbar(**sb_kwargs) + + sb3d_kwargs = obj.show_options.get("scalarbar3d", None) + if sb3d_kwargs is not None and sb3d_kwargs is not False: + sb3d_kwargs = {} if isinstance(sb3d_kwargs, bool) else sb3d_kwargs + vedo_obj.add_scalarbar3d(**sb3d_kwargs) + + elif data is not None and vertex_data is None: + utils.log.debug(f"No vertex_data named '{data}' for {obj}. Skipping") + + # arrow plots - this is independent from data plotting. + arrow_data = obj.show_options.get("arrow_data", None) + # will raise if data is scalar + arrow_data_value = obj.vertex_data.as_arrow(arrow_data, None, True) + if arrow_data is not None and arrow_data_value is not None: + from gustaf.create.edges import from_data + + # we are here because this data is not a scalar + # is showable? + if arrow_data_value.shape[1] not in (2, 3): + raise ValueError( + "Only 2D or 3D data can be shown.", + f"Requested data is {arrow_data_value.shape[1]}", + ) + + as_edges = from_data( + obj, + arrow_data_value, + obj.show_options.get("arrow_data_scale", None), + data_norm=obj.vertex_data.as_scalar(arrow_data), + ) + arrows = vedo.Arrows( + as_edges.vertices[as_edges.edges], + c=obj.show_options.get("arrow_data_color", "plasma"), + ) + if not as_dict: + vedo_obj += arrows + else: + return_as_dict["arrow_data"] = arrows + + axes_kw = obj.show_options.get("axes", None) + # need to explicitly check if it is false + if axes_kw is not None and axes_kw is not False: + axes_kw = {} if isinstance(axes_kw, bool) else axes_kw + axes = vedo.Axes(vedo_obj, **axes_kw) + if not as_dict: + vedo_obj += axes + else: + return_as_dict["axes"] = axes + + # set back temporary show_options if needed + if kwargs: + obj._show_options = orig_show_options + + if not as_dict: + return vedo_obj + else: + return_as_dict["main"] = vedo_obj + return return_as_dict
+ + + +# possibly relocate, is this actually used? +# could not find any usage in this repo +
+[docs] +def interpolate_vedo_dictcam(cameras, resolutions, spline_degree=1): + """Interpolate between vedo dict cameras. + + Parameters + ------------ + cameras: list or tuple + resolutions: int + spline_degree: int + if > 1 and splinepy is available and there are more than two cameras, + we interpolate all the entries using spline. + + Returns + -------- + interpolated_cams: list + """ + try: + import splinepy + + spp = True + + except ImportError: + spp = False + + # quick type check loop + cam_keys = ["pos", "focalPoint", "viewup", "distance", "clippingRange"] + for cam in cameras: + if not isinstance(cam, dict): + raise TypeError("Only `dict` description of vedo cam is allowed.") + else: + for key in cam_keys: + if cam[key] is None: + raise ValueError( + f"One of the camera does not contain `{key}` info" + ) + + interpolated_cams = [] + total_cams = int(resolutions) * (len(cameras) - 1) + + if spp and spline_degree > 1 and len(cameras) > 2: + if spline_degree > len(cameras): + raise ValueError( + "Not enough camera to interpolate with " + f"spline degree {spline_degree}" + ) + + ps = [] + fs = [] + vs = [] + ds = [] + cs = [] + for cam in cameras: + ps.append(list(cam[cam_keys[0]])) + fs.append(list(cam[cam_keys[1]])) + vs.append(list(cam[cam_keys[2]])) + ds.append([float(cam[cam_keys[3]])]) + cs.append(list(cam[cam_keys[4]])) + + interpolated = {} + for i, prop in enumerate([ps, fs, vs, ds, cs]): + i_spline = splinepy.BSpline() + i_spline.interpolate_curve( + query_points=prop, + degree=spline_degree, + save_query=False, + ) + interpolated[cam_keys[i]] = i_spline.sample([total_cams]) + + for i in range(total_cams): + interpolated_cams.append( + { + cam_keys[0]: interpolated[cam_keys[0]][i].tolist(), + cam_keys[1]: interpolated[cam_keys[1]][i].tolist(), + cam_keys[2]: interpolated[cam_keys[2]][i].tolist(), + cam_keys[3]: interpolated[cam_keys[3]][i][0], # float? + cam_keys[4]: interpolated[cam_keys[4]][i].tolist(), + } + ) + + else: + i = 0 + for start_cam, end_cam in zip(cameras[:-1], cameras[1:]): + if i == 0: + interpolated = [ + np.linspace( + start_cam[ckeys], + end_cam[ckeys], + resolutions, + ).tolist() + for ckeys in cam_keys + ] + + else: + interpolated = [ + np.linspace( + start_cam[ckeys], + end_cam[ckeys], + int(resolutions + 1), + )[1:].tolist() + for ckeys in cam_keys + ] + + i += 1 + + for j in range(resolutions): + interpolated_cams.append( + { + cam_keys[0]: interpolated[0][j], + cam_keys[1]: interpolated[1][j], + cam_keys[2]: interpolated[2][j], + cam_keys[3]: interpolated[3][j], # float? + cam_keys[4]: interpolated[4][j], + } + ) + + return interpolated_cams
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/utils/arr.html b/_modules/gustaf/utils/arr.html new file mode 100644 index 000000000..22951a6e0 --- /dev/null +++ b/_modules/gustaf/utils/arr.html @@ -0,0 +1,1134 @@ + + + + + + + + + + gustaf.utils.arr — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.utils.arr

+"""gustaf/gustaf/utils/arr.py.
+
+Useful functions for array / point operations. Named `arr`, since
+`array` is python library and it sounds funny.
+"""
+
+import numpy as np
+
+from gustaf import settings
+from gustaf.helpers.raise_if import ModuleImportRaiser
+
+has_funi = has_napf = has_scipy = False
+try:
+    import funi
+
+    has_funi = True
+except ImportError:
+    funi = ModuleImportRaiser("funi")
+try:
+    import napf
+
+    has_napf = True
+except ImportError:
+    napf = ModuleImportRaiser("napf")
+try:
+    import scipy
+
+    has_scipy = True
+except ImportError:
+    scipy = ModuleImportRaiser("scipy")
+
+
+
+[docs] +def make_c_contiguous(array, dtype=None): + """Make given array like object a c contiguous np.ndarray. dtype is + optional. If None is given, just returns None. + + Parameters + ----------- + array: array-like + dtype: type or str + (Optional) `numpy` interpretable type or str, describing type. + + Returns + -------- + c_contiguous_array: np.ndarray + """ + if array is None: + return None + + if isinstance(array, np.ndarray) and array.flags.c_contiguous: + if dtype is not None and array.dtype != dtype: + return array.astype(dtype) + + return array + + if dtype: + return np.ascontiguousarray(array, dtype=dtype) + + else: + return np.ascontiguousarray(array)
+ + + +
+[docs] +def enforce_len(value, n_len): + """Given int, float, np.ndarray, tuple, list, returns an array with n_len + len(). In case of iterable, it asserts n_len, else, repeats. + + Parameters + ---------- + value: int, float or iterable + n_len: int + Size of desired array + + Returns + ------- + len_n_array: (n_len,) np.ndarray + """ + if isinstance(value, (int, float)): + return np.repeat(value, n_len) + elif isinstance(value, (np.ndarray, tuple, list)): + if len(value) != n_len: + raise ValueError( + f"Invalid value length ({len(value)}). ", + f"Expected length is ({n_len})", + ) + return np.asarray(value) + else: + raise TypeError( + f"Invalid value type ({type(value)}). " + "Supports {int, float, np.ndarray, tuple, list}." + )
+ + + +
+[docs] +def unique_rows( + in_arr, + return_index=True, + return_inverse=True, + return_counts=True, + dtype_name=None, +): + """ + Find unique rows using np.unique, but apply tricks. Adapted from + `skimage.util.unique_rows`. + url: github.com/scikit-image/scikit-image/blob/main/skimage/util/unique.py/ + Suitable for int types. + + Parameters + ----------- + in_arr: (n, m) 2D array-like + return_index: bool + return_inverse: bool + return_counts: bool + dtype_name: str + + Returns + -------- + unique_arr: (p, q) np.ndarray + unique_ind: (w,) np.ndarray + unique_inv: (t,) np.ndarray + """ + if dtype_name is None: + dtype_name = settings.INT_DTYPE + + in_arr = make_c_contiguous(in_arr, dtype_name) + + if len(in_arr.shape) != 2: + raise ValueError("unique_rows can be only applied for 2D arrays") + + in_arr_row_view = in_arr.view(f"|S{in_arr.itemsize * in_arr.shape[1]}") + + unique_stuff = np.unique( + in_arr_row_view, + return_index=True, + return_inverse=return_inverse, + return_counts=return_counts, + ) + unique_stuff = list(unique_stuff) # list, to allow item assignment + + # switch view to original + unique_stuff[0] = in_arr[unique_stuff[1]] + if not return_index: + # pop return index + unique_stuff.pop(1) + + return unique_stuff
+ + + +
+[docs] +def close_rows( + arr, tolerance=None, return_intersection=False, nthreads=None, **_kwargs +): + """Similar to unique_rows, but if data type is floats, use this one. + Performs radius search using KDTree. Currently uses + `scipy.spatial.cKDTree`. + + Parameters + ----------- + arr: (n, d) array-like + tolerance: (float) + Defaults to None. + return_intersection: bool + Default is False. Returns intersection. For vertices with singular + points, this will take a lot of memory space. + nthreads: int + number of concurrent query. In case of napf, concurrent build as well. + Default is taken from settings.NTHREADS + + Returns + -------- + unique_arrays: (n, d) np.ndarray + unique_ids: (m) np.ndarray + inverse: (n) np.ndarray + overlapping: list(list) + id of neighbors within the tolerance. + """ + if tolerance is None: + tolerance = settings.TOLERANCE + + if nthreads is None: + nthreads = settings.NTHREADS + + if has_funi and not return_intersection: + return ( + *funi.unique_rows(arr, tolerance, True, "l"), + [], + ) + + if has_napf: + kdt = napf.KDT(arr, nthread=nthreads) + + # call the function that's prepared for this moment + return kdt.unique_data_and_inverse( + tolerance, True, return_intersection, nthread=nthreads + ) + + if has_scipy: + from scipy.spatial import cKDTree as scipy_KDTree + + # Build kd tree + kdt = scipy_KDTree(arr) + + # Ball point query, taking tolerance as radius + neighbors = kdt.query_ball_point( + arr, + tolerance, + return_sorted=True, + ) + + # inverse based on original vertices. + o_inverse = np.array( + [n[0] for n in neighbors], + dtype=settings.INT_DTYPE, + ) + + # unique of o_inverse, and inverse based on that + (_, uniq_id, inv) = np.unique( + o_inverse, + return_index=True, + return_inverse=True, + ) + + if not return_intersection: + neighbors = [] + + return arr[uniq_id], uniq_id, inv, neighbors + + raise ImportError( + "gus.utils.arr.close_rows() requires either funi, napf, or " + "scipy package." + )
+ + + +
+[docs] +def bounds(arr): + """Return bounds. + + Parameters + ----------- + arr: (n, d) array-like + + Returns + -------- + bounds: (2, d) np.ndarray + """ + return np.vstack( + ( + np.min(arr, axis=0).ravel(), + np.max(arr, axis=0).ravel(), + ) + )
+ + + +
+[docs] +def bounds_diagonal(arr): + """Returns diagonal vector of the bounds. + + bounds[1] - bounds[0] + + Parameters + ----------- + arr: (n, d) array-like + + Returns + -------- + bounds_diagonal: (n,) np.ndarray + """ + b = bounds(arr) + return b[1] - b[0]
+ + + +
+[docs] +def bounds_norm(arr): + """Returns norm of the bounds. + + Parameters + ----------- + arr: (n, d) array-like + + Returns + -------- + bounds_norm: float + """ + return np.linalg.norm(bounds_diagonal(arr))
+ + + +
+[docs] +def bounds_mean(arr): + """Returns mean of the bounds. + + Parameters + ----------- + arr: (n, d) array-like + + Returns + -------- + bounds_mean: (n,) array-like + """ + return np.mean(bounds(arr), axis=0)
+ + + +
+[docs] +def select_with_ranges(arr, ranges): + """Select array with ranges of each column. Always parsed as: + + [[greater_than, less_than], [....], ...] + + Parameters + ----------- + ranges: (d, 2) array-like + Takes None. + + Returns + -------- + ids: (n,) np.ndarray + """ + masks = [] + for i, r in enumerate(ranges): + if r is None: + continue + + else: + lower = arr[:, i] > r[0] + upper = arr[:, i] < r[1] + if r[1] > r[0]: + masks.append(np.logical_and(lower, upper)) + else: + masks.append(np.logical_or(lower, upper)) + + if len(masks) > 1: + mask = np.zeros(arr.shape[0], dtype=bool) + for i, m in enumerate(masks): + mask = ( + np.logical_or(mask, m) if i == 0 else np.logical_and(mask, m) + ) + + else: + mask = masks[0] + + return np.arange(arr.shape[0])[mask]
+ + + +
+[docs] +def rotation_matrix(rotation, degree=True): + """Compute rotation matrix. Works for both 2D and 3D point sets. In 2D, it + can rotate along the (virtual) z-axis. In 3D, it can rotate along [x, y, + z]-axis. Uses `scipy.spatial.transform.Rotation`. + + Parameters + ----------- + rotation: list or float + Amount of rotation along [x,y,z] axis. Default is in degrees. + In 2D, it can be float. + degree: bool + (Optional) rotation given in degrees. + Default is `True`. If `False`, in radian. + + Returns + -------- + rotation_matrix: np.ndarray (3,3) + """ + from scipy.spatial.transform import Rotation as R + + rotation = np.asarray(rotation).ravel() + + if degree: + rotation = np.radians(rotation) + + # 2D + if len(rotation) == 1: + return R.from_rotvec([0, 0, rotation]).as_matrix()[:2, :2] + + # 3D + elif len(rotation) == 3: + return R.from_rotvec(rotation).as_matrix()
+ + + +
+[docs] +def rotate(arr, rotation, rotation_axis=None, degree=True): + """Rotates given arrays. Arrays shape[1] should equal to either 2 or 3 For + more information, see `rotation_matrix()`. + + Parameters + ----------- + arr: (n, (2 or 3)) list-like + rotation: list or float + angle of rotation (around each axis) + rotation_axis: (n, (2 or 3)) or (2 or 3) list-like + center of rotation + + Returns + -------- + rotated_points: (n, d) np.ndarray + """ + arr = make_c_contiguous(arr, settings.FLOAT_DTYPE) + if rotation_axis is not None: + rotation_axis = np.asanyarray(rotation_axis) + + if rotation_axis is None: + return np.matmul(arr, rotation_matrix(rotation, degree)) + + else: + rotated_array = arr - rotation_axis + rotated_array = np.matmul( + rotated_array, rotation_matrix(rotation, degree) + ) + rotated_array += rotation_axis + + return rotated_array
+ + + +
+[docs] +def rotation_matrix_around_axis(axis=None, rotation=None, degree=True): + """Compute rotation matrix given the axis of rotation. Works for both 2D + and 3D Uses Rodrigues' formula. + + If axis is not specified, 2D rotation matrix is assumed. + + Parameters + ----------- + axis: list or np.ndarray + Axis of rotation in 3D + rotation: float + angle of rotation in either radiant or degrees + degree: bool + (Optional) rotation given in degrees. + Default is `True`. If `False`, in radian. + + Returns + -------- + rotation_matrix: np.ndarray (3,3) of np.ndarray (2,2) + """ + # Assure angle is specified + if rotation is None: + raise ValueError("No rotation angle specified.") + elif degree: + rotation = np.radians(rotation) + + # Check Problem dimensions + if axis is None: + problem_dimension = 2 + else: + axis = np.asarray(axis).ravel() + if axis.shape[0] != 3: + raise ValueError("Axis dimension must be 3D") + problem_dimension = 3 + + # Assemble rotation matrix + if problem_dimension == 2: + rotation_matrix = np.array( + [ + [np.cos(rotation), -np.sin(rotation)], + [np.sin(rotation), np.cos(rotation)], + ] + ) + else: + # See Rodrigues' formula + rotation_matrix = np.array( + [ + [0, -axis[2], axis[1]], + [axis[2], 0, -axis[0]], + [-axis[1], axis[0], 0], + ] + ) + rotation_matrix = ( + np.eye(3) + + np.sin(rotation) * rotation_matrix + + ( + (1 - np.cos(rotation)) + * np.matmul(rotation_matrix, rotation_matrix) + ) + ) + + return rotation_matrix
+ + + +
+[docs] +def is_shape(arr, shape, strict=False): + """Checks if arr matches given shape. shape can have negative numbers. + + Parameters + ----------- + arr: np.ndarray + shape: tuple + strict: bool + raises ValueError if shapes do not match + + Returns + -------- + matches: bool + """ + arr = np.asanyarray(arr) + + if arr.ndim != len(shape): + if strict: + raise ValueError(f"array should be {len(shape)}D") + return False + + for i, (a, s) in enumerate(zip(arr.shape, shape)): + if s < 0: + continue + if a != s: + if strict: + raise ValueError(f"array should have {s} shape in {i}-D") + return False + + return True
+ + + +
+[docs] +def is_one_of_shapes(arr, shapes, strict=False): + """Tuple/list of given shapes, iterates and checks with is_shape. Useful if + you have multiple acceptable shapes. + + Parameters + ----------- + arr: np.ndarray + shapes: tuple or list + tuple/list of tuple/list + strict: bool + + Returns + -------- + matches: bool + """ + arr = np.asanyarray(arr) + matches = False + for s in shapes: + m = is_shape(arr, s, strict=False) + if m: + matches = True + + if not matches: + if strict: + raise ValueError( + f"array's shape {arr.shape} is not one of f{shapes}" + ) + return False + + return True
+ + + +
+[docs] +def derivatives_to_normals(derivatives, normalize=True): + """ + Parameters + ---------- + derivatives: (n, (d - 1), d) np.ndarray + Surface jacobian transposed. + normalize: bool + + Returns + ------- + normals: (n, d) np.ndarray + """ + if derivatives.ndim != 3: + raise ValueError("derivatives for normals expect 3D arrays") + + shape = derivatives.shape + if shape[0] != shape[1] - 1: + raise ValueError("derivatives are expected to have (d-1, d) shape") + + # 2D is simple index flip + if shape[2] == 2: + der = derivatives.reshape(-1, shape[2]) + normals = np.empty_like(der) + normals[:, 0] = der[:, 1] + normals[:, 1] = -der[:, 0] + + elif shape[2] == 3: + der = derivatives.reshape(shape[0] * shape[1], shape[2]) + normals = cross3d(der[::2], der[1::2]) + + if normalize: + normals /= np.linalg.norm(normals, axis=1).reshape(-1, 1) + + return normals
+ + + +
+[docs] +def cross3d(a, b): + """ + Cross product for two 3D arrays. Usually faster than np.cross + as it just targets 3d. + + Parameters + ---------- + a: (n, 3) np.ndarray + b: (n, 3) np.ndarray + + Returns + ------- + crossed: (n, 3) np.ndarray + """ + # (1 5 - 2 4, 2 3 - 0 5, 0 4 - 1 3). + # or from two arrays + # (1 2 - 2 1, 2 0 - 0 2, 0 1 - 1 0). + o = np.empty_like(a) + + # temporary aux arrays + size = len(a) + t0 = np.empty(size) + t1 = np.empty(size) + + # short cuts + a0, a1, a2 = a[..., 0], a[..., 1], a[..., 2] + b0, b1, b2 = b[..., 0], b[..., 1], b[..., 2] + o0, o1, o2 = o[..., 0], o[..., 1], o[..., 2] + + np.multiply(a1, b2, out=t0) + np.multiply(a2, b1, out=t1) + np.subtract(t0, t1, out=o0) + + np.multiply(a2, b0, out=t0) + np.multiply(a0, b2, out=t1) + np.subtract(t0, t1, out=o1) + + np.multiply(a0, b1, out=t0) + np.multiply(a1, b0, out=t1) + np.subtract(t0, t1, out=o2) + + return o
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/utils/connec.html b/_modules/gustaf/utils/connec.html new file mode 100644 index 000000000..6fdf6d1a1 --- /dev/null +++ b/_modules/gustaf/utils/connec.html @@ -0,0 +1,1346 @@ + + + + + + + + + + gustaf.utils.connec — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.utils.connec

+"""gustaf/gustaf/utils/connec.py.
+
+Useful functions for connectivity operation. Ranging from edges to
+volumes. Named connec because connectivity is too long. Would have been
+even cooler, if it was palindrome.
+"""
+
+import collections
+
+import numpy as np
+
+try:
+    import napf
+except ImportError:
+    from gustaf.helpers.raise_if import ModuleImportRaiser
+
+    napf = ModuleImportRaiser("napf")
+
+from gustaf import helpers, settings
+from gustaf.utils import arr
+
+
+
+[docs] +def tet_to_tri(volumes): + """Computes tri faces based on following index scheme. + + ``Tetrahedron`` + + .. code-block:: text + + Ref: (node_ind), face_ind + + (0) + _/| + _/ 1| + (1) _/____| (3) + _/| /| + _/ 0| 2/ 3| + /____|/____| + (0) (2) (0) + + face_ind | node_ind + ---------|---------- + 0 | 0 2 1 + 1 | 1 3 0 + 2 | 2 3 1 + 3 | 3 2 0 + + Parameters + ----------- + volumes: (n, 4) np.ndarray + + Returns + -------- + faces: (n * 4, 3) np.ndarray + """ + volumes = np.asanyarray(volumes, settings.INT_DTYPE) + + if volumes.ndim != 2 or volumes.shape[1] != 4: + raise ValueError("Given volumes are not `tet` volumes") + + fpe = 4 # faces per element + faces = ( + np.ones(((volumes.shape[0] * fpe), 3), dtype=settings.INT_DTYPE) * -1 + ) # -1 for safety check + + faces[:, 0] = volumes.ravel() + faces[::fpe, [1, 2]] = volumes[:, [2, 1]] + faces[1::fpe, [1, 2]] = volumes[:, [3, 0]] + faces[2::fpe, [1, 2]] = volumes[:, [3, 1]] + faces[3::fpe, [1, 2]] = volumes[:, [2, 0]] + + if (faces == -1).any(): + raise ValueError("Something went wrong while computing faces") + + return faces
+ + + +
+[docs] +def hexa_to_quad(volumes): + """Computes quad faces based on following index scheme. + + ``Hexahedron`` + + .. code-block:: text + + + (6) (7) + *------* + | | + (6) (2)| 3 |(3) (7) (6) + *------*------*------*------* + | | | | | + | 2 | 0 | 4 | 5 | + *------*------*------*------* + (5) (1)| |(0) (4) (5) + | 1 | + *------* + (5) (4) + + face_ind | node_ind + ---------|---------- + 0 | 1 0 3 2 + 1 | 0 1 5 4 + 2 | 1 2 6 5 + 3 | 2 3 7 6 + 4 | 3 0 4 7 + 5 | 4 5 6 7 + + Parameters + ----------- + volumes: (n, 8) np.ndarray + + Returns + -------- + faces: (n * 8, 4) np.ndarray + """ + volumes = np.asanyarray(volumes, settings.INT_DTYPE) + + if volumes.ndim != 2 or volumes.shape[1] != 8: + raise ValueError("Given volumes are not `hexa` volumes") + + fpe = 6 # faces per element + faces = np.empty(((volumes.shape[0] * fpe), 4), dtype=settings.INT_DTYPE) + + faces[::fpe] = volumes[:, [1, 0, 3, 2]] + faces[1::fpe] = volumes[:, [0, 1, 5, 4]] + faces[2::fpe] = volumes[:, [1, 2, 6, 5]] + faces[3::fpe] = volumes[:, [2, 3, 7, 6]] + faces[4::fpe] = volumes[:, [3, 0, 4, 7]] + faces[5::fpe] = volumes[:, [4, 5, 6, 7]] + + return faces
+ + + +
+[docs] +def volumes_to_faces(volumes): + """Guidance function for `tet_to_tri` and `hexa_to_quad`. + + Parameters + ----------- + volumes: (n, 4) or (m, 8) np.ndarray + + Returns + -------- + faces: (n*4, 3) or (m*6, 4) np.ndarray + """ + volumes = np.asanyarray(volumes, settings.INT_DTYPE) + if volumes.shape[1] == 4: + return tet_to_tri(volumes) + + elif volumes.shape[1] == 8: + return hexa_to_quad(volumes)
+ + + +
+[docs] +def faces_to_edges(faces): + """Compute edges based on following edge scheme. + + .. code-block:: text + + Ref: (node_ind), edge_ind + + (0) + /\\ + 0 / \\2 + /____\\ + (1) 1 (2) + + 2 + (3)*-----*(2) + | | + 3 | | 1 + (0)*-----*(1) + 0 + + Note: if `edges` index matter for tets, reorder it! + + Parameters + ----------- + faces: (n, 3) or (n, 4) np.ndarray + + Returns + -------- + edges: (n * 3, 2) or (n * 4, 2) np.ndarray + """ + if faces.ndim != 2: + raise ValueError( + "Given input has wrong dimension. " + "The input array for a faces has to be dim of 2" + ) + + num_faces = faces.shape[0] + vertices_per_face = faces.shape[1] + + num_edges = int(num_faces * vertices_per_face) + edges = np.empty((num_edges, 2), dtype=settings.INT_DTYPE) + + edges[:, 0] = faces.ravel() + + for i in range(vertices_per_face): + # v_ind : corresponding vertex index for i value + v_ind = 0 if i == int(vertices_per_face - 1) else i + 1 + + edges[i::vertices_per_face, 1] = faces[:, v_ind] + + return edges
+ + + +
+[docs] +def range_to_edges(range_, closed=False, continuous=True): + """Given range, for example (a, b), returns an edge sequence that + sequentially connects indices. If int is given as range, it is considered + as (0, value). Used to be called "closed/open_loop_index_train". + + Parameters + ----------- + range_: list, tuple, or int + closed: bool + continuous: bool + + Returns + -------- + edges: (n, 2) np.ndarray + """ + if isinstance(range_, int): + indices = np.arange(range_, dtype=settings.INT_DTYPE) + elif isinstance(range_, (list, tuple)): + # pass range_ as is and check for valid output + indices = np.arange(*range_, dtype=settings.INT_DTYPE) + if len(indices) < 2: + raise ValueError( + f"{range_} is invalid range input. " + "It must result in minimum of size=2 array." + ) + + # closed is ignored + if not continuous: + if indices.size % 2 == 1: + raise ValueError( + "Ranges should result in even number of indices for " + "continuous edges." + ) + return indices.reshape(-1, 2) + + return sequence_to_edges(indices, closed)
+ + + +
+[docs] +def sequence_to_edges(seq, closed=False): + """Given a sequence of int, "connect" to turn them into edges. + + Parameters + ----------- + seq: (n,) array-like + closed: bool + + Returns + -------- + edges: (m, 2) np.ndarray + """ + edges = np.repeat(seq, 2) + + if closed: + first = int(edges[0]) # this is redundant copy to ensure detaching + # equivalent to np.roll(edges, -1) without copy + # safe since numpy is single thread + edges[:-1] = edges[1:] + edges[-1] = first + else: + # reselect only part of the array instead of copy + # this should only update array interface protocol + edges = edges[1:-1] + + return edges.reshape(-1, 2)
+ + + +
+[docs] +def make_quad_faces(resolutions): + """Given number of nodes per each dimension, returns connectivity + information of a structured mesh. Counter clock wise connectivity. + + .. code-block:: text + + (3)*------*(2) + | | + | | + (0)*------*(1) + + Parameters + ---------- + resolutions: list + + Returns + ------- + faces: (n, 4) np.ndarray + """ + nnpd = np.asarray(resolutions) # number of nodes per dimension + if any(nnpd < 1): + raise ValueError(f"The number of nodes per dimension is wrong: {nnpd}") + + total_nodes = np.prod(nnpd) + total_faces = (nnpd[0] - 1) * (nnpd[1] - 1) + try: + node_indices = np.arange( + total_nodes, dtype=settings.INT_DTYPE + ).reshape(nnpd[1], nnpd[0]) + except ValueError as e: + raise ValueError(f"Problem with generating node indices. {e}") + + faces = np.empty((total_faces, 4), dtype=settings.INT_DTYPE) + + faces[:, 0] = node_indices[: (nnpd[1] - 1), : (nnpd[0] - 1)].ravel() + faces[:, 1] = node_indices[: (nnpd[1] - 1), 1 : nnpd[0]].ravel() + faces[:, 2] = node_indices[1 : nnpd[1], 1 : nnpd[0]].ravel() + faces[:, 3] = node_indices[1 : nnpd[1], : (nnpd[0] - 1)].ravel() + + return faces
+ + + +
+[docs] +def make_hexa_volumes(resolutions): + """Given number of nodes per each dimension, returns connectivity + information of structured hexahedron elements. Counter clock wise + connectivity. + + .. code-block:: text + + (7)*-------*(6) + /| /| + / | (5) / | + (4)*-------* | + | *----|--*(2) + | /(3) | / + |/ |/ + (0)*-------*(1) + + Parameters + ----------- + resolutions: list + + Returns + -------- + elements: (n, 8) np.ndarray + """ + nnpd = np.asarray(resolutions) # number of nodes per dimension + if any(nnpd < 1): + raise ValueError(f"The number of nodes per dimension is wrong: {nnpd}") + + total_nodes = np.prod(nnpd) + total_volumes = np.prod(nnpd - 1) + node_indices = np.arange(total_nodes, dtype=settings.INT_DTYPE).reshape( + nnpd[::-1] + ) + + volumes = np.empty((total_volumes, 8), dtype=settings.INT_DTYPE) + + volumes[:, 0] = node_indices[ + : (nnpd[2] - 1), : (nnpd[1] - 1), : (nnpd[0] - 1) + ].ravel() + volumes[:, 1] = node_indices[ + : (nnpd[2] - 1), : (nnpd[1] - 1), 1 : nnpd[0] + ].ravel() + volumes[:, 2] = node_indices[ + : (nnpd[2] - 1), 1 : nnpd[1], 1 : nnpd[0] + ].ravel() + volumes[:, 3] = node_indices[ + : (nnpd[2] - 1), 1 : nnpd[1], : (nnpd[0] - 1) + ].ravel() + volumes[:, 4] = node_indices[ + 1 : nnpd[2], : (nnpd[1] - 1), : (nnpd[0] - 1) + ].ravel() + volumes[:, 5] = node_indices[ + 1 : nnpd[2], : (nnpd[1] - 1), 1 : nnpd[0] + ].ravel() + volumes[:, 6] = node_indices[1 : nnpd[2], 1 : nnpd[1], 1 : nnpd[0]].ravel() + volumes[:, 7] = node_indices[ + 1 : nnpd[2], 1 : nnpd[1], : (nnpd[0] - 1) + ].ravel() + + return volumes
+ + + +
+[docs] +def subdivide_edges(edges): + """Subdivide edges. We assume that mid point is newly added points. + + ``Subdivided Edges`` + + .. code-block:: text + + Edges (Lines) + + Ref: (node_ids), edge_ids + + (0) (2) (1) + *--------*--------* + + edge_ids | node_ids + ---------|---------- + 0 | 0 2 + 1 | 2 1 + + Parameters + ----------- + edges: (n, 2) np.ndarray + + Returns + -------- + subdivided_edges: (n * 2, 2) np.ndarray + """ + if edges.ndim != 2 or edges.shape[1] != 2: + raise ValueError("Invalid edges shape!") + + raise NotImplementedError
+ + + +
+[docs] +def subdivide_tri(mesh, return_dict=False): + """Subdivide triangles. Each triangle is divided into 4 meshes. + + ``Subdivided Faces`` + + .. code-block:: text + + Triangles + + Ref: (node_ind), face_ind + + (0) + _/| + _/ 0| + (3) _/____|(5) + _/| /| + _/ 1| 3/ 2| + /____|/____| + (1) (4) (2) + + face_ind | node_ind + ---------|---------- + 0 | 0 3 5 + 1 | 1 4 3 + 2 | 2 5 4 + 3 | 3 4 5 + + Parameters + ----------- + mesh: Mesh + return_dict: bool + + Returns + -------- + new_vertices: (n, d) np.ndarray + subdivided_faces: (m, 3) np.ndarray + mesh_dict: dict + iff `return_dict=True`, + returns dict(vertices=new_vertices, faces=subdivided_faces). + """ + # This will only pass if the mesh is triangle mesh. + if mesh.faces.shape[1] != 3: + raise ValueError("Invalid faces shape!") + + # Form new vertices + edge_mid_v = mesh.vertices[mesh.unique_edges().values].mean(axis=1) + new_vertices = np.vstack((mesh.vertices, edge_mid_v)) + + subdivided_faces = np.empty( + (mesh.faces.shape[0] * 4, mesh.faces.shape[1]), + dtype=settings.INT_DTYPE, + ) + + mask = np.ones(subdivided_faces.shape[0], dtype=bool) + mask[3::4] = False + + # 0th column minus (every 4th row, starting from 3rd row) + subdivided_faces[mask, 0] = mesh.faces.ravel() + + # Form ids for new vertices + new_vertices_ids = mesh.unique_edges().inverse + int(mesh.faces.max() + 1) + # 1st & 2nd columns + subdivided_faces[mask, 1] = new_vertices_ids + subdivided_faces[mask, 2] = new_vertices_ids.reshape(-1, 3)[ + :, [2, 0, 1] + ].ravel() + + # Every 4th row, starting from 3rd row + subdivided_faces[~mask, :] = new_vertices_ids.reshape(-1, 3) + + if return_dict: + return { + "vertices": new_vertices, + "faces": subdivided_faces, + } + + else: + return new_vertices, subdivided_faces
+ + + +
+[docs] +def subdivide_quad( + mesh, + return_dict=False, +): + """Subdivide quads. + + Parameters + ----------- + mesh: Mesh + return_dict: bool + + Returns + -------- + new_vertices: (n, d) np.ndarray + subdivided_faces: (m, 4) np.ndarray + mesh_dict: dict + iff `return_dict=True`, + returns dict(vertices=new_vertices, faces=subdivided_faces). + """ + # This will only pass if the mesh is quad mesh. + if mesh.faces.shape[1] != 4: + raise ValueError("Invalid faces shape!") + + # Form new vertices + edge_mid_v = mesh.vertices[mesh.unique_edges().values].mean(axis=1) + face_centers = mesh.centers() + new_vertices = np.vstack( + ( + mesh.vertices, + edge_mid_v, + face_centers, + ) + ) + + subdivided_faces = np.empty( + (mesh.faces.shape[0] * 4, mesh.faces.shape[1]), + dtype=settings.INT_DTYPE, + ) + + subdivided_faces[:, 0] = mesh.faces.ravel() + subdivided_faces[:, 1] = mesh.unique_edges().inverse + len(mesh.vertices) + subdivided_faces[:, 2] = np.repeat( + np.arange(len(face_centers)) + (len(mesh.vertices) + len(edge_mid_v)), + 4, + dtype=settings.INT_DTYPE, + ) + subdivided_faces[:, 3] = ( + subdivided_faces[:, 1].reshape(-1, 4)[:, [3, 0, 1, 2]].ravel() + ) + + if return_dict: + return { + "vertices": new_vertices, + "faces": subdivided_faces, + } + + else: + return new_vertices, subdivided_faces
+ + + +
+[docs] +def sorted_unique(connectivity, sorted_=False): + """Given connectivity array, finds unique entries, based on its axis=1 + sorted values. Returned value will be sorted. + + Parameters + ----------- + connectivity: (n, d) np.ndarray + sorted_: bool + + Returns + -------- + unique_info: Unique2DIntegers + """ + s_connec = connectivity if sorted_ else np.sort(connectivity, axis=1) + + unique_stuff = arr.unique_rows( + s_connec, + return_index=True, + return_inverse=True, + return_counts=True, + dtype_name=settings.INT_DTYPE, + ) + + return helpers.data.Unique2DIntegers( + unique_stuff[0], # values + unique_stuff[1], # ids + unique_stuff[2], # inverse + unique_stuff[3], # counts + )
+ + + +def _sequentialize_directed_edges(edges, start=None, return_edges=False): + """ + Sequentialize directed edges. + """ + # we want to have an np array + edges = np.asanyarray(edges) + + # Build a lookup_array + lookup_array = np.full(edges.max() + 1, -1, dtype=settings.INT_DTYPE) + lookup_array[edges[:, 0]] = edges[:, 1] + + # select starting point - lowest index + starting_point = int(edges.min()) if start is None else int(start) + + # initialize a set to keep track of processes vertices + next_candidates = set(edges[:, 0]) + # we want to keep track of single occurrences, as they are line start + line_starts = set(np.where(np.bincount(edges.ravel()) == 1)[0]) + # for this to work, we can't have a line that starts at column 1. + # so, we remove those. + ls_col1 = set(np.where(np.bincount(edges[:, 1].ravel()) == 1)[0]) + line_starts.difference_update(ls_col1) + + polygons = [] + is_polygon = [] + for _ in range(len(edges)): + # Get polygon - start with first two points + polygon = [starting_point] + polygon.append(lookup_array[polygon[-1]]) + + # then keep looking until we come to the start. + # if there's only one edges, this will exit right away + for _ in range(len(next_candidates)): + # sequence closes -> polygon + if polygon[0] == polygon[-1]: + polygon.pop() + is_polygon.append(True) + break + + # sequence leads to unspecified connection -> not polygon + if lookup_array[polygon[-1]] < 0: + is_polygon.append(False) + break + polygon.append(lookup_array[polygon[-1]]) + + polygons.append(polygon) + + # check if we counted all the edges + # if so, exit + next_candidates.difference_update(polygons[-1]) + line_starts.difference_update(polygons[-1]) + + if len(next_candidates) == len(line_starts) == 0: + break + + # let's try to find the next starting point + starting_point = None + if len(line_starts) != 0: + starting_point = min(line_starts) + else: + starting_point = min(next_candidates) + + if not return_edges: + return polygons, is_polygon + + else: + polygon_edges = [] + for p, is_p in zip(polygons, is_polygon): + polygon_edges.append(sequence_to_edges(p, closed=is_p)) + + return polygon_edges, is_polygon + + +def _sequentialize_edges(edges, start=None, return_edges=False): + """ + sequentialize undirected edges. No overlaps are allowed, for now. + """ + edges = np.asanyarray(edges) + + # only applicable to closed polygons and open lines + # not for arbitrarily connected edges + bc = np.bincount(edges.ravel()) + if not all(bc < 3): + raise ValueError( + "This function currently supports individual lines/polygons " + "search. Given edges include connections with more than 3 edges." + ) + + # we want to keep track of single occurrences, as they are line start + line_starts = set(np.where(bc == 1)[0]) + + # initialize a set to keep track of processes vertices + next_candidates = set(edges.ravel()) + + # create a look up to each edge column + edge_col = collections.namedtuple("a", "b") + edge_col.a = edges[:, 0] + edge_col.b = edges[:, 1] + + # create trees for each edge column + tree = collections.namedtuple("a", "b") + tree.a = napf.KDT(edge_col.a.reshape(-1, 1)) + tree.b = napf.KDT(edge_col.b.reshape(-1, 1)) + + # radius search size + r = 0.1 + + current_id = np.argmin(edge_col.a) if start is None else start + start_value = int(edge_col.a[current_id]) + other_col = edge_col.b + + polygons = [] + is_polygon = [] + for _ in range(len(edges)): + polygon = [start_value, other_col[current_id]] + + # while polygon[0] != polygon[-1]: + for _ in range(len(next_candidates)): + if polygon[0] == polygon[-1]: + break + # search for ids + a_ids = tree.a.radius_search([[polygon[-1]]], r, True)[0][0] + b_ids = tree.b.radius_search([[polygon[-1]]], r, True)[0][0] + + # in total, there should be 2 otherwise, we can end this search + # and this is not a polygon + hits = len(a_ids) + len(b_ids) + if hits != 2: + break + + # so, we have 2 hits. we need to get the partner of non-current_id + # index + found = False + for ai in a_ids: + if ai != current_id: + found = True + current_id = ai + polygon.append(edge_col.b[current_id]) + break + if found: + continue + + for bi in b_ids: + if bi != current_id: + found = True + current_id = bi + polygon.append(edge_col.a[current_id]) + break + if found: + continue + + raise RuntimeError( + "Something went wrong. Please report this issue to " + "github.com/tataratat/gustaf/issues]" + ) + + # if indices closes itself, it is a polygon. + # Otherwise it is an open line + if polygon[0] == polygon[-1]: + polygon.pop() + is_polygon.append(True) + else: + is_polygon.append(False) + polygons.append(polygon) + + # check if we counted all the edges + # if so, exit + # let's try to find the next starting point + next_candidates.difference_update(polygons[-1]) + line_starts.difference_update(polygons[-1]) + + if len(next_candidates) == len(line_starts) == 0: + break + + # Assign next starting point + # generally first value of (those are min() in a set) line start or + # leftover candidates + start_value = None + if len(line_starts) != 0: + start_value = min(line_starts) + else: + start_value = min(next_candidates) + + # adjust state values + a_ids = tree.a.radius_search([[start_value]], r, True)[0][0] + if len(a_ids) != 0: + current_id = a_ids[0] + other_col = edge_col.b + continue + b_ids = tree.b.radius_search([[start_value]], r, True)[0][0] + if len(b_ids) != 0: + current_id = b_ids[0] + other_col = edge_col.a + continue + + raise RuntimeError( + "Something went wrong. Please report this issue to " + "github.com/tataratat/gustaf/issues" + ) + + if not return_edges: + return polygons, is_polygon + + else: + polygon_edges = [] + for p, is_p in zip(polygons, is_polygon): + polygon_edges.append(sequence_to_edges(p, closed=is_p)) + + return polygon_edges + + +
+[docs] +def sequentialize_edges(edges, start=None, return_edges=False, directed=False): + """ + Organize edge connectivities to describe polygon or a line. + This supports edges that describes separated/individual polygons and lines. + In other words, it doesn't support edges of overlapping vertices. + + Parameters + ----------- + edges: (n, 2) list-like + start: int + (Optional) Specify starting point. It will take minimum index otherwise. + return_edges: bool + (Optional) Default is False. If set True, returns sequences as edges. + directed: bool + (Optional) Default is False. Set True, if given edges are directed. + It should return the result faster. + + Returns + -------- + sequences: list + list of vertex ids. Or edges iff return_edges is True. + is_polygon: list + Tells if the sequence is a polygon or a line. + + Examples + --------- + >>> e = gus.Edges(vertices, edges) + >>> ordered_sequence, is_polygon = sequentialize_edges(e.edges) + + >>> f = gus.Faces(vertices, faces) + >>> ordered_sequence, is_polygon = sequentialize_edges( + ... f.edges()[f.single_edges()] + ... ) + """ + if directed: + return _sequentialize_directed_edges(edges, start, return_edges) + else: + return _sequentialize_edges(edges, start, return_edges)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/utils/log.html b/_modules/gustaf/utils/log.html new file mode 100644 index 000000000..531f2eb14 --- /dev/null +++ b/_modules/gustaf/utils/log.html @@ -0,0 +1,612 @@ + + + + + + + + + + gustaf.utils.log — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.utils.log

+"""gustaf/gustaf/utils/log.py.
+
+Thin logging wrapper.
+"""
+
+import logging
+from functools import partial
+
+
+
+[docs] +def configure(debug=False, logfile=None): + """Logging configurator. + + Parameters + ----------- + debug: bool + logfile: str + + Returns + -------- + None + """ + # logger + logger = logging.getLogger("gustaf") + + # level + level = logging.DEBUG if debug else logging.INFO + logger.setLevel(level) + + # format + formatter = logging.Formatter(fmt="%(name)s [%(levelname)s] %(message)s") + + # apply format using stream handler + # let's use only one stream handler so that calling configure multiple + # times won't duplicate printing. + new_handlers = [] + for _i, h in enumerate(logger.handlers): + # we skip all the stream handler. + if isinstance(h, logging.StreamHandler): + continue + + # blindly keep other ones + else: + new_handlers.append(h) + + # add new stream handler + stream_handler = logging.StreamHandler() + stream_handler.setLevel(level) + stream_handler.setFormatter(formatter) + new_handlers.append(stream_handler) + + logger.handlers = new_handlers + + # output logs + if logfile is not None: + file_logger_handler = logging.FileHandler(logfile) + logger.addHandler(file_logger_handler)
+ + + +
+[docs] +def debug(*log): + """Debug logger. + + Parameters + ----------- + *log: Tuple[str] + + Returns + -------- + None + """ + logger = logging.getLogger("gustaf") + logger.debug(" ".join(map(str, log)))
+ + + +
+[docs] +def info(*log): + """Info logger. + + Parameters + ----------- + *log: Tuple[str] + + Returns + -------- + None + """ + logger = logging.getLogger("gustaf") + logger.info(" ".join(map(str, log)))
+ + + +
+[docs] +def warning(*log): + """warning logger. + + Parameters + ----------- + *log: Tuple[str] + + Returns + -------- + None + """ + logger = logging.getLogger("gustaf") + logger.warning(" ".join(map(str, log)))
+ + + +
+[docs] +def prepended_log(message, log_func): + """ + Prepend message before a logging function. + + Parameters + ---------- + message: str + log_func: function + one of the following - {info, debug, warning} + + Returns + ------- + prepended: function + """ + return partial(log_func, message)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/utils/tictoc.html b/_modules/gustaf/utils/tictoc.html new file mode 100644 index 000000000..37299ab3f --- /dev/null +++ b/_modules/gustaf/utils/tictoc.html @@ -0,0 +1,613 @@ + + + + + + + + + + gustaf.utils.tictoc — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.utils.tictoc

+"""gustaf/gustaf/utils/tictoc.py.
+
+Timer that tics, tocs and logs.
+"""
+
+from time import perf_counter as now
+
+from gustaf._base import GustafBase
+
+
+
+[docs] +class Tic(GustafBase): + """ + Timer class for easier time measurement. + """ + + __slots__ = ("_title", "_names", "_laps", "_logger") + + # add short cut to perf_counter in case you just want pure "now" + now = now + + def __init__(self, title="untitled", log_level="debug"): + """ + Configures the timer and logger. Marks the starting point. + + Parameters + ---------- + title: str + Title for this measurement. Defaults to "untitled". + log_level: str + Valid options are {"info", "debug", "warning"}. Defaults to "debug". + """ + # select logger based on logger level + self._logger = eval(f"self._log{str(log_level).lower()[0]}") + + # initialize names + self._names = [] + + # give name + self._title = str(title) + + # start + self._laps = [now()] + +
+[docs] + def toc(self, name=None, log=False): + """ + Adds now to the measurements. + + Parameters + ---------- + name: str + Name of this specific measurement lap. + By default, it assigns a number to this lap. + log: bool + If True, will log lapsed time. Defaults to None. + + Returns + ------- + None + """ + # measure now + self._laps.append(now()) + + self._names.append( + f"lap-{len(self._laps) - 2}" if name is None else str(name) + ) + + if log: + self._logger( + f"{self._title} - {name}: {self._laps[-2] - self._laps[-1]}" + )
+ + +
+[docs] + def summary(self, log=True, print_=False): + """ + Prints measurement summary to the log. + + Parameters + ---------- + log: bool + Logs the summary. Default is True. + print_: bool + Prints the summary. Default is False. + + + Returns + ------- + records: tuple + Lap timings in a tuple consisting of a list of the lap names and + times for each lap from the timer start (cumulative time). + """ + start = self._laps[0] + cumulative = [f"{lap-start:.10f}" for lap in self._laps[1:]] + + if log or print_: + message = [f"\n+++ {self._title} - time logs +++\n"] + + name_width = int(max([len(n) for n in self._names])) + + # extract info + diff = [ + f"{l1 - l0:.10f}" + for l0, l1 in zip(self._laps[:-1], self._laps[1:]) + ] + diff_width = int(max([len(d) for d in diff])) + cumulative_width = int(max([len(c) for c in cumulative])) + + message.append( + f"{'names'.ljust(name_width)} | " + f"{'diff'.rjust(diff_width)} | " + f"{'cumulative'.rjust(cumulative_width)}\n" + ) + + for n, d, c in zip(self._names, diff, cumulative): + this_line = ( + f"{n.ljust(name_width)} | " + f"{d.rjust(diff_width)} | " + f"{c.rjust(cumulative_width)}\n" + ) + message.append(this_line) + + if log: + self._logger(*message) + if print_: + print(*message) # noqa: T201 + + return self._names.copy(), cumulative
+
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/vertices.html b/_modules/gustaf/vertices.html new file mode 100644 index 000000000..9dbf636d7 --- /dev/null +++ b/_modules/gustaf/vertices.html @@ -0,0 +1,1097 @@ + + + + + + + + + + gustaf.vertices — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.vertices

+"""gustaf/gustaf/vertices.py.
+
+Vertices. Base of all "Mesh" geometries.
+"""
+
+import copy
+
+import numpy as np
+
+from gustaf import helpers, settings, show, utils
+from gustaf._base import GustafBase
+from gustaf.helpers.options import Option
+
+
+
+[docs] +class VerticesShowOption(helpers.options.ShowOption): + """ + Show options for vertices. + """ + + _valid_options = helpers.options.make_valid_options( + *helpers.options.vedo_common_options, + Option( + "vedo", + "r", + "Radius of vertices in units of pixels.", + (float, int), + ), + Option( + "vedo", + "labels", + "Places a label/description str at the place of vertices.", + (np.ndarray, tuple, list), + ), + Option( + "vedo", + "label_options", + "Label kwargs to be passed during initialization." + "Valid keywords are: {scale: float, xrot: float, yrot: float, " + "zrot: float, ratio: float, precision: int, italic: bool, " + "font: str, justify: str, c: (str, tuple, list, int), " + "alpha: float}. " + "As further hint, justify takes '-' joined combination of " + "{center, mid, right, left, top, bottom}.", + (dict,), + ), + ) + + _helps = "Vertices" + + def _initialize_showable(self): + """ + Initialize Vertices showable for vedo. + + Parameters + ---------- + None + + Returns + ------- + vertices: vedo.Points + """ + init_options = ("r",) + + vertices = show.vedo.Points( + self._helpee.const_vertices, **self[init_options] + ) + + labels = self.get("labels", None) + if labels is not None: + # check length + if len(labels) != len(self._helpee.const_vertices): + raise ValueError( + f"number of label contents ({len(labels)}) and " + "number of vertices" + f"({len(self._helpee.const_vertices)}) does not match." + ) + + # apply options and return labels + return vertices.labels( + content=labels, + on="points", + **self.get("label_options", {}), + ) + + else: + # no labels, return Points + return vertices
+ + + +
+[docs] +class Vertices(GustafBase): + kind = "vertex" + + __slots__ = ( + "_vertices", + "_const_vertices", + "_computed", + "_show_options", + "_vertex_data", + ) + + # define frequently used types as dunder variable + __show_option__ = VerticesShowOption + + def __init__( + self, + vertices=None, + ): + """Vertices. It has vertices. + + Parameters + ----------- + vertices: (n, d) np.ndarray + + Returns + -------- + None + """ + # call setters + self.vertices = vertices + + # init helpers + self._vertex_data = helpers.data.VertexData(self) + self._computed = helpers.data.ComputedMeshData(self) + self._show_options = self.__show_option__(self) + + @property + def vertices(self): + """Returns vertices. + + Parameters + ----------- + None + + Returns + -------- + vertices: (n, d) np.ndarray + """ + self._logd("returning vertices") + return self._vertices + + @vertices.setter + def vertices(self, vs): + """Vertices setter. This will saved as a tracked array. This tracked + array is very sensitive and if we do anything with it that may hint an + inplace operation, it will be marked as modified. This includes copying + and slicing. If you know you aren't going to modify the array, please + consider using `const_vertices`. Somewhat c-style hint in naming. + + Parameters + ----------- + vs: (n, d) np.ndarray + + Returns + -------- + None + """ + self._logd("setting vertices") + + # we try not to make copy. + self._vertices = helpers.data.make_tracked_array( + vs, settings.FLOAT_DTYPE, copy=False + ) + + # shape check + if self._vertices.size > 0: + utils.arr.is_shape(self._vertices, (-1, -1), strict=True) + + # exact same, but not tracked. + self._const_vertices = self._vertices.view() + self._const_vertices.flags.writeable = False + + # at each setting, validate vertex_data + # --> by len mismatch, will clear data + if hasattr(self, "vertex_data"): + self.vertex_data._validate_len(raise_=False) + + @property + def const_vertices(self): + """Returns non-mutable view of `vertices`. Naming inspired by c/cpp + sessions. + + Parameters + ----------- + None + + Returns + -------- + None + """ + self._logd("returning const_vertices") + return self._const_vertices + + @property + def vertex_data(self): + """ + Returns vertex_data manager. Behaves similar to dict() and can be used + to store values/data associated with each vertex. + + Parameters + ---------- + None + + Returns + ------- + vertex_data: VertexData + """ + self._logd("returning vertex_data") + return self._vertex_data + + @property + def show_options(self): + """ + Returns a show option manager for this object. Behaves similar to + dict. + + Parameters + ---------- + None + + Returns + ------- + show_options: ShowOption + A derived class that's suitable for current class. + """ + self._logd("returning show_options") + return self._show_options + + @property + def whatami(self): + """Answers deep philosophical question: "what am i"? + + Parameters + ---------- + None + + Returns + -------- + whatami: str + vertices + """ + return "vertices" + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices"]) + def unique_vertices(self, tolerance=None, **kwargs): + """Returns a namedtuple that holds unique vertices info. Unique here + means "close-enough-within-tolerance". + + Parameters + ----------- + tolerance: float + (Optional) Default is settings.TOLERANCE + recompute: bool + Only applicable as keyword argument. Force re-computes. + + Returns + -------- + unique_vertices_info: Unique2DFloats + namedtuple with `values`, `ids`, `inverse`, `intersection`. + """ + self._logd("computing unique vertices") + if tolerance is None: + tolerance = settings.TOLERANCE + + values, ids, inverse, intersection = utils.arr.close_rows( + self.const_vertices, tolerance=tolerance, **kwargs + ) + + return helpers.data.Unique2DFloats( + values, + ids, + inverse, + intersection, + )
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices"]) + def bounds(self): + """Returns bounds of the vertices. Bounds means AABB of the geometry. + + Parameters + ----------- + None + + Returns + -------- + bounds: (d,) np.ndarray + """ + self._logd("computing bounds") + return utils.arr.bounds(self.vertices)
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices"]) + def bounds_diagonal(self): + """Returns diagonal vector of the bounding box. + + Parameters + ----------- + None + + Returns + -------- + bounds_diagonal: (d,) np.ndarray + same as `bounds[1] - bounds[0]` + """ + self._logd("computing bounds_diagonal") + bounds = self.bounds() + return bounds[1] - bounds[0]
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["vertices"]) + def bounds_diagonal_norm(self): + """Returns norm of bounds diagonal. + + Parameters + ----------- + None + + Returns + -------- + bounds_diagonal_norm: float + """ + self._logd("computing bounds_diagonal_norm") + return float(sum(self.bounds_diagonal() ** 2) ** 0.5)
+ + +
+[docs] + def update_vertices(self, mask, inverse=None): + """Update vertices with a mask. In other words, keeps only masked + vertices. Adapted from `github.com/mikedh/trimesh`. Updates + connectivity accordingly too. + + Parameters + ----------- + mask: (n,) bool or int + inverse: (len(self.vertices),) int + + Returns + -------- + updated_self: type(self) + """ + vertices = self.const_vertices.copy() + + # make mask numpy array + mask = np.asarray(mask) + + if (mask.dtype.name == "bool" and mask.all()) or len(mask) == 0: + return self + + # create inverse mask if not passed + check_neg = False + if inverse is None and self.kind != "vertex": + inverse = np.full(len(vertices), -11, dtype=settings.INT_DTYPE) + check_neg = True + if mask.dtype.kind == "b": + inverse[mask] = np.arange(mask.sum()) + elif mask.dtype.kind == "i": + inverse[mask] = np.arange(len(mask)) + else: + inverse = None + + # re-index elements from inverse + # TODO: Here could be a good place to preserve BCs. + elements = None + if inverse is not None and self.kind != "vertex": + elements = self.const_elements.copy() + elements = inverse[elements.reshape(-1)].reshape( + (-1, elements.shape[1]) + ) + # remove all the elements that's not part of inverse + if check_neg: + elem_mask = (elements > -1).all(axis=1) + elements = elements[elem_mask] + + # apply mask + vertices = vertices[mask] + + def update_vertex_data(obj, m, vertex_data): + """apply mask to vertex data if there's any.""" + new_data = helpers.data.VertexData(obj) + + for key, values in vertex_data.items(): + # should work, since this is called after updating vertices + new_data[key] = values[m] + + obj._vertex_data = new_data + + return obj + + # make shallow copy of saved vertex data + v_data = self.vertex_data._saved.copy() + + # update - if number of vertices changes, this will remove all the + # length mis-matching data. + self.vertices = vertices + if elements is not None: + self.elements = elements + + update_vertex_data(self, mask, v_data) + + return self
+ + +
+[docs] + def select_vertices(self, ranges): + """Returns vertices inside the given range. + + Parameters + ----------- + ranges: (d, 2) array-like + Takes None. + + Returns + -------- + ids: (n,) np.ndarray + """ + return utils.arr.select_with_ranges(self.vertices, ranges)
+ + +
+[docs] + def remove_vertices(self, ids): + """Removes vertices with given vertex ids. + + Parameters + ----------- + ids: (n,) np.ndarray + + Returns + -------- + new_self: type(self) + """ + mask = np.ones(len(self.vertices), dtype=bool) + mask[ids] = False + + return self.update_vertices(mask)
+ + +
+[docs] + def merge_vertices(self, tolerance=None, **kwargs): + """Based on unique vertices, merge vertices if it is mergeable. + + Parameters + ----------- + tolerance: float + Default is settings.TOLERANCE + + Returns + -------- + merged_self: type(self) + """ + unique_vs = self.unique_vertices(tolerance, **kwargs) + + self._logd("number of vertices") + self._logd(f" before merge: {len(self.vertices)}") + self._logd(f" after merge: {len(unique_vs.ids)}") + + return self.update_vertices( + mask=unique_vs.ids, + inverse=unique_vs.inverse, + )
+ + +
+[docs] + def showable(self, **kwargs): + """Returns showable object, meaning object of visualization backend. + + Parameters + ----------- + **kwargs: + + Returns + -------- + showable: obj + Obj of `gustaf.settings.VISUALIZATION_BACKEND` + """ + return show.make_showable(self, **kwargs)
+ + +
+[docs] + def show(self, **kwargs): + """Show current object using visualization backend. + + Parameters + ----------- + **kwargs: + + + Returns + -------- + None + """ + return show.show(self, **kwargs)
+ + +
+[docs] + def copy(self): + """Returns deepcopy of self. + + Parameters + ----------- + None + + Returns + -------- + self_copy: type(self) + """ + # all attributes are deepcopy-able + copied = copy.deepcopy(self) + + # update helpee. otherwise keeps reference to self + copied._show_options._helpee = copied + copied._vertex_data._helpee = copied + copied._computed._helpee = copied + + return copied
+ + +
+[docs] + @classmethod + def concat(cls, *instances): + """Sequentially put them together to make one object. + + Parameters + ----------- + *instances: List[type(cls)] + Allows one iterable object also. + + Returns + -------- + one_instance: type(cls) + """ + + def is_concatable(inst): + """Return true, if it is same as type(cls)""" + return bool(isinstance(inst, cls)) + + # If only one instance is given and it is iterable, adjust + # so that we will just iterate that. + if ( + len(instances) == 1 + and not isinstance(instances[0], str) + and hasattr(instances[0], "__iter__") + ): + instances = instances[0] + + vertices = [] + has_elem = cls.kind != "vertex" + if has_elem: + elements = [] + + # check if everything is "concatable". + for ins in instances: + if not is_concatable(ins): + raise TypeError( + "Can't concat. One of the instances is not " + f"`{cls.__name__}`." + ) + + tmp_ins = ins.copy() + + # make sure each element index starts from 0 & end at len(vertices) + if has_elem: + tmp_ins.remove_unreferenced_vertices() + + vertices.append(tmp_ins.vertices) + + if has_elem: + if len(elements) == 0: + elements.append(tmp_ins.elements) + e_offset = elements[-1].max() + 1 + + else: + elements.append(tmp_ins.elements + e_offset) + e_offset = elements[-1].max() + 1 + + if has_elem: + return cls( + vertices=np.vstack(vertices), + elements=np.vstack(elements), + ) + + else: + return Vertices(vertices=np.vstack(vertices))
+ + + def __add__(self, to_add): + """Concat in form of +. + + Parameters + ----------- + to_add: type(self) + + Returns + -------- + added: type(self) + """ + return type(self).concat(self, to_add)
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/gustaf/volumes.html b/_modules/gustaf/volumes.html new file mode 100644 index 000000000..3c14a1a35 --- /dev/null +++ b/_modules/gustaf/volumes.html @@ -0,0 +1,784 @@ + + + + + + + + + + gustaf.volumes — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for gustaf.volumes

+"""gustaf/gustaf/volumes.py."""
+
+import numpy as np
+
+from gustaf import helpers, settings, show, utils
+from gustaf.faces import Faces
+from gustaf.helpers.options import Option
+
+
+
+[docs] +class VolumesShowOption(helpers.options.ShowOption): + """ + Show options for vertices. + """ + + _valid_options = helpers.options.make_valid_options( + *helpers.options.vedo_common_options, + Option("vedo", "lw", "Width of edges (lines) in pixel units.", (int,)), + Option( + "vedo", "lc", "Color of edges (lines).", (int, str, tuple, list) + ), + ) + + _helps = "Volumes" + + def _initialize_showable(self): + """ + Initialize volumes as vedo.UGrid or visually equivalent vedo.Mesh + + Parameters + ---------- + None + + Returns + ------- + volumes: vedo.UGrid or vedo.Mesh + """ + # without a data to plot on the surface, return vedo.UGrid + # if vertex_ids is on, we will go with mesh + if ( + self.get("data", None) is None + and not self.get("vertex_ids", False) + and not self.get("arrow_data", False) + and not show.is_ipython + ): + from vtk import VTK_HEXAHEDRON as herr_hexa + from vtk import VTK_TETRA as frau_tetra + + to_vtktype = {"tet": frau_tetra, "hexa": herr_hexa} + grid_type = to_vtktype[self._helpee.whatami] + u_grid = show.vedoUGrid( + [ + self._helpee.const_vertices, + self._helpee.const_volumes, + [grid_type] * len(self._helpee.const_volumes), + ] + ) + + for option in ["lw", "lc"]: + val = self.get(option, False) + if val: + getattr(u_grid, option)(val) + + return u_grid.c("hotpink") + + # to show data, let's use Faces. This will plot all the elements + # as well as invisible ones. This will at least try to avoid + # duplicating faces. If you wanna see inside faces, try + # as_shrunk_faces = volumes.to_faces(unique=False).shrink(.8) + faces = self._helpee.to_faces(unique=True) + self.copy_valid_options(faces.show_options) + + return faces.show_options._initialize_showable()
+ + + +
+[docs] +class Volumes(Faces): + kind = "volume" + + const_faces = helpers.raise_if.invalid_inherited_attr( + "Faces.const_faces", + __qualname__, + property_=True, + ) + update_faces = helpers.raise_if.invalid_inherited_attr( + "Faces.update_edges", + __qualname__, + property_=False, + ) + + __slots__ = ( + "_volumes", + "_const_volumes", + ) + + __show_option__ = VolumesShowOption + __boundary_class__ = Faces + + def __init__( + self, + vertices=None, + volumes=None, + elements=None, + ): + """Volumes. It has vertices and volumes. Volumes could be tetrahedrons + or hexahedrons. + + Parameters + ----------- + vertices: (n, d) np.ndarray + volumes: (n, 4) or (n, 8) np.ndarray + """ + super().__init__(vertices=vertices) + if volumes is not None: + self.volumes = volumes + elif elements is not None: + self.volumes = elements + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def faces(self): + """Faces here aren't main property. So this needs to be computed. + + Parameters + ----------- + None + + Returns + -------- + faces: (n, 3) or (n, 4) np.ndarray + """ + whatami = self.whatami + faces = None + if whatami.startswith("tet"): + faces = utils.connec.tet_to_tri(self.volumes) + elif whatami.startswith("hexa"): + faces = utils.connec.hexa_to_quad(self.volumes) + + return faces
+ + +
+[docs] + @classmethod + def whatareyou(cls, volume_obj): + """overwrites Faces.whatareyou to tell you is this volume is tet or + hexa. + + Parameters + ----------- + volume_obj: Volumes + + Returns + -------- + whatareyou: str + """ + if not cls.kind.startswith(volume_obj.kind): + raise TypeError("Given obj is not {cls.__qualname__}") + + if volume_obj.volumes.shape[1] == 4: + return "tet" + + elif volume_obj.volumes.shape[1] == 8: + return "hexa" + + else: + raise ValueError( + "Invalid volumes connectivity shape. It should be (n, 4) " + f"or (n, 8), but given: {volume_obj.volumes.shape}" + )
+ + + @property + def volumes(self): + """Returns volumes. + + Parameters + ----------- + None + + Returns + -------- + volumes: (n, 4) or (n, 8) np.ndarray + """ + return self._volumes + + @volumes.setter + def volumes(self, vols): + """volumes setter. Similar to vertices, this will be a tracked array. + + Parameters + ----------- + vols: (n, 4) or (n, 8) np.ndarray + + Returns + -------- + None + """ + self._volumes = helpers.data.make_tracked_array( + vols, + settings.INT_DTYPE, + copy=False, + ) + if vols is not None: + utils.arr.is_one_of_shapes( + vols, + ((-1, 4), (-1, 8)), + strict=True, + ) + # same, but non-writeable view of tracked array + self._const_volumes = self._volumes.view() + self._const_volumes.flags.writeable = False + + @property + def const_volumes(self): + """Returns non-writeable view of volumes. + + Parameters + ----------- + None + + Returns + -------- + const_volumes: (n, 4) or (n, 8) np.ndarray + """ + return self._const_volumes + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def sorted_volumes(self): + """Sort volumes along axis=1. + + Parameters + ----------- + None + + Returns + -------- + volumes_sorted: (volumes.shape) np.ndarray + """ + volumes = self._get_attr("volumes") + + return np.sort(volumes, axis=1)
+ + +
+[docs] + @helpers.data.ComputedMeshData.depends_on(["elements"]) + def unique_volumes(self): + """Returns a namedtuple of unique volumes info. Similar to + unique_edges. + + Parameters + ----------- + None + + Returns + -------- + unique_info: Unique2DIntegers + valid attributes are {values, ids, inverse, counts} + """ + unique_info = utils.connec.sorted_unique( + self.sorted_volumes(), + sorted_=True, + ) + + volumes = self._get_attr("volumes") + + unique_info.values[:] = volumes[unique_info.ids] + + return unique_info
+ + +
+[docs] + def update_volumes(self, *args, **kwargs): + """Alias to update_elements.""" + self.update_elements(*args, **kwargs)
+ + +
+[docs] + def to_faces(self, unique=True): + """Returns Faces obj. + + Parameters + ----------- + unique: bool + Default is True. If True, only takes unique faces. + + Returns + -------- + faces: Faces + """ + return Faces( + self.vertices, + faces=self.unique_faces().values if unique else self.faces(), + )
+
+ +
+ +
+ + + + + +
+ +
+
+
+ +
+ + + +
+ + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 000000000..cdb237fd9 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,500 @@ + + + + + + + + + + Overview: module code — gustaf 0.0.25 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+
+ + + + +
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ + + + + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/_sources/CONTRIBUTING.rst.txt b/_sources/CONTRIBUTING.rst.txt new file mode 100644 index 000000000..85bb7bcf8 --- /dev/null +++ b/_sources/CONTRIBUTING.rst.txt @@ -0,0 +1,4 @@ +------------ +Contributing +------------ +.. mdinclude:: ../md/CONTRIBUTING.md diff --git a/_sources/_generated/gustaf.create.edges.from_data.rst.txt b/_sources/_generated/gustaf.create.edges.from_data.rst.txt new file mode 100644 index 000000000..ad64eaec9 --- /dev/null +++ b/_sources/_generated/gustaf.create.edges.from_data.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.edges.from\_data +============================== + +.. currentmodule:: gustaf.create.edges + +.. autofunction:: from_data \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.edges.from_vertices.rst.txt b/_sources/_generated/gustaf.create.edges.from_vertices.rst.txt new file mode 100644 index 000000000..b77aa7edd --- /dev/null +++ b/_sources/_generated/gustaf.create.edges.from_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.edges.from\_vertices +================================== + +.. currentmodule:: gustaf.create.edges + +.. autofunction:: from_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.edges.rst.txt b/_sources/_generated/gustaf.create.edges.rst.txt new file mode 100644 index 000000000..0d29d4e32 --- /dev/null +++ b/_sources/_generated/gustaf.create.edges.rst.txt @@ -0,0 +1,33 @@ +.. _gustaf.create.edges: + +gustaf.create.edges +=================== + +.. automodule:: gustaf.create.edges + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + from_data + from_vertices + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.create.faces.box.rst.txt b/_sources/_generated/gustaf.create.faces.box.rst.txt new file mode 100644 index 000000000..d64d56827 --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.box.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.faces.box +======================= + +.. currentmodule:: gustaf.create.faces + +.. autofunction:: box \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.faces.edges_as_quad.rst.txt b/_sources/_generated/gustaf.create.faces.edges_as_quad.rst.txt new file mode 100644 index 000000000..4add25ebf --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.edges_as_quad.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.faces.edges\_as\_quad +=================================== + +.. currentmodule:: gustaf.create.faces + +.. autofunction:: edges_as_quad \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.faces.rst.txt b/_sources/_generated/gustaf.create.faces.rst.txt new file mode 100644 index 000000000..8e4a2305e --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.rst.txt @@ -0,0 +1,36 @@ +.. _gustaf.create.faces: + +gustaf.create.faces +=================== + +.. automodule:: gustaf.create.faces + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + box + edges_as_quad + to_quad + to_simplex + vertex_normals + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.create.faces.to_quad.rst.txt b/_sources/_generated/gustaf.create.faces.to_quad.rst.txt new file mode 100644 index 000000000..03435212d --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.to_quad.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.faces.to\_quad +============================ + +.. currentmodule:: gustaf.create.faces + +.. autofunction:: to_quad \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.faces.to_simplex.rst.txt b/_sources/_generated/gustaf.create.faces.to_simplex.rst.txt new file mode 100644 index 000000000..6ee03140c --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.to_simplex.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.faces.to\_simplex +=============================== + +.. currentmodule:: gustaf.create.faces + +.. autofunction:: to_simplex \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.faces.vertex_normals.rst.txt b/_sources/_generated/gustaf.create.faces.vertex_normals.rst.txt new file mode 100644 index 000000000..13f880878 --- /dev/null +++ b/_sources/_generated/gustaf.create.faces.vertex_normals.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.faces.vertex\_normals +=================================== + +.. currentmodule:: gustaf.create.faces + +.. autofunction:: vertex_normals \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.rst.txt b/_sources/_generated/gustaf.create.rst.txt new file mode 100644 index 000000000..974597223 --- /dev/null +++ b/_sources/_generated/gustaf.create.rst.txt @@ -0,0 +1,37 @@ +.. _gustaf.create: + +gustaf.create +============= + +.. automodule:: gustaf.create + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: + :recursive: + + gustaf.create.edges + gustaf.create.faces + gustaf.create.vertices + gustaf.create.volumes + diff --git a/_sources/_generated/gustaf.create.vertices.raster.rst.txt b/_sources/_generated/gustaf.create.vertices.raster.rst.txt new file mode 100644 index 000000000..741e33152 --- /dev/null +++ b/_sources/_generated/gustaf.create.vertices.raster.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.vertices.raster +============================= + +.. currentmodule:: gustaf.create.vertices + +.. autofunction:: raster \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.vertices.rst.txt b/_sources/_generated/gustaf.create.vertices.rst.txt new file mode 100644 index 000000000..afab2cc7e --- /dev/null +++ b/_sources/_generated/gustaf.create.vertices.rst.txt @@ -0,0 +1,32 @@ +.. _gustaf.create.vertices: + +gustaf.create.vertices +====================== + +.. automodule:: gustaf.create.vertices + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + raster + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.create.volumes.box.rst.txt b/_sources/_generated/gustaf.create.volumes.box.rst.txt new file mode 100644 index 000000000..d820cbdeb --- /dev/null +++ b/_sources/_generated/gustaf.create.volumes.box.rst.txt @@ -0,0 +1,6 @@ +gustaf.create.volumes.box +========================= + +.. currentmodule:: gustaf.create.volumes + +.. autofunction:: box \ No newline at end of file diff --git a/_sources/_generated/gustaf.create.volumes.rst.txt b/_sources/_generated/gustaf.create.volumes.rst.txt new file mode 100644 index 000000000..fd318cedc --- /dev/null +++ b/_sources/_generated/gustaf.create.volumes.rst.txt @@ -0,0 +1,32 @@ +.. _gustaf.create.volumes: + +gustaf.create.volumes +===================== + +.. automodule:: gustaf.create.volumes + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + box + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.edges.Edges.centers.rst.txt b/_sources/_generated/gustaf.edges.Edges.centers.rst.txt new file mode 100644 index 000000000..8a5aac4e8 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.centers.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.centers +========================== + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.centers \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.const_edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.const_edges.rst.txt new file mode 100644 index 000000000..6416c9cdc --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.const_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.const\_edges +=============================== + +.. currentmodule:: gustaf.edges + +.. autoproperty:: Edges.const_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.const_elements.rst.txt b/_sources/_generated/gustaf.edges.Edges.const_elements.rst.txt new file mode 100644 index 000000000..8c287550b --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.const_elements.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.const\_elements +================================== + +.. currentmodule:: gustaf.edges + +.. autoproperty:: Edges.const_elements \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.dashed.rst.txt b/_sources/_generated/gustaf.edges.Edges.dashed.rst.txt new file mode 100644 index 000000000..39daee67c --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.dashed.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.dashed +========================= + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.dashed \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.edges.rst.txt new file mode 100644 index 000000000..2ba3aebae --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.edges +======================== + +.. currentmodule:: gustaf.edges + +.. autoproperty:: Edges.edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.elements.rst.txt b/_sources/_generated/gustaf.edges.Edges.elements.rst.txt new file mode 100644 index 000000000..45f246425 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.elements.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.elements +=========================== + +.. currentmodule:: gustaf.edges + +.. autoproperty:: Edges.elements \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.kind.rst.txt b/_sources/_generated/gustaf.edges.Edges.kind.rst.txt new file mode 100644 index 000000000..dcbc8e441 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.kind.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.kind +======================= + +.. currentmodule:: gustaf.edges + +.. autoattribute:: Edges.kind \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.referenced_vertices.rst.txt b/_sources/_generated/gustaf.edges.Edges.referenced_vertices.rst.txt new file mode 100644 index 000000000..34383ade2 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.referenced_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.referenced\_vertices +======================================= + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.referenced_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.rst.txt b/_sources/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.rst.txt new file mode 100644 index 000000000..2e712fcba --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.remove_unreferenced_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.remove\_unreferenced\_vertices +================================================= + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.remove_unreferenced_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.rst.txt new file mode 100644 index 000000000..227190804 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.rst.txt @@ -0,0 +1,142 @@ +gustaf.edges.Edges +================== + +.. currentmodule:: gustaf.edges + +.. autoclass:: Edges + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + Edges.centers + + + + + + + + + + + Edges.dashed + + + + + + + + Edges.referenced_vertices + + + + + Edges.remove_unreferenced_vertices + + + + + + + + + + + + + + + + + Edges.shrink + + + + + Edges.single_edges + + + + + Edges.sorted_edges + + + + + Edges.to_vertices + + + + + Edges.unique_edges + + + + + + + + Edges.update_edges + + + + + Edges.update_elements + + + + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Edges.const_edges + + + Edges.const_elements + + + + Edges.edges + + + Edges.elements + + + Edges.kind + + + + + + Edges.whatami + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.shrink.rst.txt b/_sources/_generated/gustaf.edges.Edges.shrink.rst.txt new file mode 100644 index 000000000..b8138b143 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.shrink.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.shrink +========================= + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.shrink \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.single_edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.single_edges.rst.txt new file mode 100644 index 000000000..b04f10a49 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.single_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.single\_edges +================================ + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.single_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.sorted_edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.sorted_edges.rst.txt new file mode 100644 index 000000000..db24be1d4 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.sorted_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.sorted\_edges +================================ + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.sorted_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.to_vertices.rst.txt b/_sources/_generated/gustaf.edges.Edges.to_vertices.rst.txt new file mode 100644 index 000000000..5f3fca6c6 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.to_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.to\_vertices +=============================== + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.to_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.unique_edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.unique_edges.rst.txt new file mode 100644 index 000000000..d879deda5 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.unique_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.unique\_edges +================================ + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.unique_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.update_edges.rst.txt b/_sources/_generated/gustaf.edges.Edges.update_edges.rst.txt new file mode 100644 index 000000000..89d1f1377 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.update_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.update\_edges +================================ + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.update_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.update_elements.rst.txt b/_sources/_generated/gustaf.edges.Edges.update_elements.rst.txt new file mode 100644 index 000000000..1353f8b39 --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.update_elements.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.update\_elements +=================================== + +.. currentmodule:: gustaf.edges + +.. automethod:: Edges.update_elements \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.Edges.whatami.rst.txt b/_sources/_generated/gustaf.edges.Edges.whatami.rst.txt new file mode 100644 index 000000000..caaa1234d --- /dev/null +++ b/_sources/_generated/gustaf.edges.Edges.whatami.rst.txt @@ -0,0 +1,6 @@ +gustaf.edges.Edges.whatami +========================== + +.. currentmodule:: gustaf.edges + +.. autoproperty:: Edges.whatami \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.EdgesShowOption.rst.txt b/_sources/_generated/gustaf.edges.EdgesShowOption.rst.txt new file mode 100644 index 000000000..f90e6633a --- /dev/null +++ b/_sources/_generated/gustaf.edges.EdgesShowOption.rst.txt @@ -0,0 +1,50 @@ +gustaf.edges.EdgesShowOption +============================ + +.. currentmodule:: gustaf.edges + +.. autoclass:: EdgesShowOption + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.edges.rst.txt b/_sources/_generated/gustaf.edges.rst.txt new file mode 100644 index 000000000..0d2e10746 --- /dev/null +++ b/_sources/_generated/gustaf.edges.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.edges: + +gustaf.edges +============ + +.. automodule:: gustaf.edges + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Edges + EdgesShowOption + + + + + + + + + diff --git a/_sources/_generated/gustaf.faces.Faces.BC.rst.txt b/_sources/_generated/gustaf.faces.Faces.BC.rst.txt new file mode 100644 index 000000000..738f65661 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.BC.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.BC +===================== + +.. currentmodule:: gustaf.faces + +.. autoattribute:: Faces.BC \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.const_edges.rst.txt b/_sources/_generated/gustaf.faces.Faces.const_edges.rst.txt new file mode 100644 index 000000000..d4e68bc6c --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.const_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.const\_edges +=============================== + +.. currentmodule:: gustaf.faces + +.. autoproperty:: Faces.const_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.const_faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.const_faces.rst.txt new file mode 100644 index 000000000..abe82d360 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.const_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.const\_faces +=============================== + +.. currentmodule:: gustaf.faces + +.. autoproperty:: Faces.const_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.dashed.rst.txt b/_sources/_generated/gustaf.faces.Faces.dashed.rst.txt new file mode 100644 index 000000000..ada4cba31 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.dashed.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.dashed +========================= + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.dashed \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.edges.rst.txt b/_sources/_generated/gustaf.faces.Faces.edges.rst.txt new file mode 100644 index 000000000..7070ac935 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.edges +======================== + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.faces.rst.txt new file mode 100644 index 000000000..d7c1fc21d --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.faces +======================== + +.. currentmodule:: gustaf.faces + +.. autoproperty:: Faces.faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.kind.rst.txt b/_sources/_generated/gustaf.faces.Faces.kind.rst.txt new file mode 100644 index 000000000..89e9effd1 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.kind.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.kind +======================= + +.. currentmodule:: gustaf.faces + +.. autoattribute:: Faces.kind \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.rst.txt new file mode 100644 index 000000000..53f5190e4 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.rst.txt @@ -0,0 +1,166 @@ +gustaf.faces.Faces +================== + +.. currentmodule:: gustaf.faces + +.. autoclass:: Faces + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + Faces.dashed + + + + + Faces.edges + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Faces.single_faces + + + + + + + + Faces.sorted_faces + + + + + Faces.to_edges + + + + + Faces.to_subelements + + + + + + + + + + + Faces.unique_faces + + + + + + + + Faces.update_edges + + + + + + + + Faces.update_faces + + + + + + + + Faces.whatareyou + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Faces.BC + + + Faces.const_edges + + + + Faces.const_faces + + + + + Faces.faces + + + Faces.kind + + + + + + Faces.whatami + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.single_faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.single_faces.rst.txt new file mode 100644 index 000000000..50f13dcaa --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.single_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.single\_faces +================================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.single_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.sorted_faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.sorted_faces.rst.txt new file mode 100644 index 000000000..f14f25b41 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.sorted_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.sorted\_faces +================================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.sorted_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.to_edges.rst.txt b/_sources/_generated/gustaf.faces.Faces.to_edges.rst.txt new file mode 100644 index 000000000..387517bc5 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.to_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.to\_edges +============================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.to_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.to_subelements.rst.txt b/_sources/_generated/gustaf.faces.Faces.to_subelements.rst.txt new file mode 100644 index 000000000..cdc84ca44 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.to_subelements.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.to\_subelements +================================== + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.to_subelements \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.unique_faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.unique_faces.rst.txt new file mode 100644 index 000000000..2294a527e --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.unique_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.unique\_faces +================================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.unique_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.update_edges.rst.txt b/_sources/_generated/gustaf.faces.Faces.update_edges.rst.txt new file mode 100644 index 000000000..1b95c12d3 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.update_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.update\_edges +================================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.update_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.update_faces.rst.txt b/_sources/_generated/gustaf.faces.Faces.update_faces.rst.txt new file mode 100644 index 000000000..ea15e0c85 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.update_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.update\_faces +================================ + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.update_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.whatami.rst.txt b/_sources/_generated/gustaf.faces.Faces.whatami.rst.txt new file mode 100644 index 000000000..0e0318246 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.whatami.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.whatami +========================== + +.. currentmodule:: gustaf.faces + +.. autoproperty:: Faces.whatami \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.Faces.whatareyou.rst.txt b/_sources/_generated/gustaf.faces.Faces.whatareyou.rst.txt new file mode 100644 index 000000000..7f45c2414 --- /dev/null +++ b/_sources/_generated/gustaf.faces.Faces.whatareyou.rst.txt @@ -0,0 +1,6 @@ +gustaf.faces.Faces.whatareyou +============================= + +.. currentmodule:: gustaf.faces + +.. automethod:: Faces.whatareyou \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.FacesShowOption.rst.txt b/_sources/_generated/gustaf.faces.FacesShowOption.rst.txt new file mode 100644 index 000000000..f72b6f876 --- /dev/null +++ b/_sources/_generated/gustaf.faces.FacesShowOption.rst.txt @@ -0,0 +1,50 @@ +gustaf.faces.FacesShowOption +============================ + +.. currentmodule:: gustaf.faces + +.. autoclass:: FacesShowOption + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.faces.rst.txt b/_sources/_generated/gustaf.faces.rst.txt new file mode 100644 index 000000000..d67ab7062 --- /dev/null +++ b/_sources/_generated/gustaf.faces.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.faces: + +gustaf.faces +============ + +.. automodule:: gustaf.faces + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Faces + FacesShowOption + + + + + + + + + diff --git a/_sources/_generated/gustaf.helpers.data.ComputedData.depends_on.rst.txt b/_sources/_generated/gustaf.helpers.data.ComputedData.depends_on.rst.txt new file mode 100644 index 000000000..8d6041c24 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.ComputedData.depends_on.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.ComputedData.depends\_on +============================================ + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: ComputedData.depends_on \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.ComputedData.rst.txt b/_sources/_generated/gustaf.helpers.data.ComputedData.rst.txt new file mode 100644 index 000000000..c7900e96c --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.ComputedData.rst.txt @@ -0,0 +1,49 @@ +gustaf.helpers.data.ComputedData +================================ + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: ComputedData + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + ComputedData.depends_on + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.ComputedMeshData.rst.txt b/_sources/_generated/gustaf.helpers.data.ComputedMeshData.rst.txt new file mode 100644 index 000000000..0ab8a4dcb --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.ComputedMeshData.rst.txt @@ -0,0 +1,47 @@ +gustaf.helpers.data.ComputedMeshData +==================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: ComputedMeshData + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.clear.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.clear.rst.txt new file mode 100644 index 000000000..dfbf48744 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.clear.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.clear +==================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.clear \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.get.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.get.rst.txt new file mode 100644 index 000000000..e1f0ac7ad --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.get.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.get +================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.get \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.items.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.items.rst.txt new file mode 100644 index 000000000..1b1d70f1e --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.items.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.items +==================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.items \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.keys.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.keys.rst.txt new file mode 100644 index 000000000..3ecca06c3 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.keys.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.keys +=================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.keys \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.pop.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.pop.rst.txt new file mode 100644 index 000000000..1e5ce6adb --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.pop.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.pop +================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.pop \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.rst.txt new file mode 100644 index 000000000..11339df96 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.rst.txt @@ -0,0 +1,58 @@ +gustaf.helpers.data.DataHolder +============================== + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: DataHolder + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + DataHolder.clear + + + + + DataHolder.get + + + + + DataHolder.items + + + + + DataHolder.keys + + + + + DataHolder.pop + + + + + DataHolder.update + + + + + DataHolder.values + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.update.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.update.rst.txt new file mode 100644 index 000000000..d9845b487 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.update.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.update +===================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.update \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.DataHolder.values.rst.txt b/_sources/_generated/gustaf.helpers.data.DataHolder.values.rst.txt new file mode 100644 index 000000000..9243897a5 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.DataHolder.values.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.DataHolder.values +===================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: DataHolder.values \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.TrackedArray.copy.rst.txt b/_sources/_generated/gustaf.helpers.data.TrackedArray.copy.rst.txt new file mode 100644 index 000000000..6c137aafb --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.TrackedArray.copy.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.TrackedArray.copy +===================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: TrackedArray.copy \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.TrackedArray.modified.rst.txt b/_sources/_generated/gustaf.helpers.data.TrackedArray.modified.rst.txt new file mode 100644 index 000000000..6fddbbad9 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.TrackedArray.modified.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.TrackedArray.modified +========================================= + +.. currentmodule:: gustaf.helpers.data + +.. autoproperty:: TrackedArray.modified \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.TrackedArray.rst.txt b/_sources/_generated/gustaf.helpers.data.TrackedArray.rst.txt new file mode 100644 index 000000000..617584f0f --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.TrackedArray.rst.txt @@ -0,0 +1,219 @@ +gustaf.helpers.data.TrackedArray +================================ + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: TrackedArray + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TrackedArray.copy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TrackedArray.view + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + + + + + + + + + + TrackedArray.modified + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.TrackedArray.view.rst.txt b/_sources/_generated/gustaf.helpers.data.TrackedArray.view.rst.txt new file mode 100644 index 000000000..1ccbfd4f9 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.TrackedArray.view.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.TrackedArray.view +===================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: TrackedArray.view \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DFloats.ids.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.ids.rst.txt new file mode 100644 index 000000000..26082cdfc --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.ids.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DFloats.ids +====================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DFloats.ids \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DFloats.intersection.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.intersection.rst.txt new file mode 100644 index 000000000..d1523a7be --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.intersection.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DFloats.intersection +=============================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DFloats.intersection \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DFloats.inverse.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.inverse.rst.txt new file mode 100644 index 000000000..b5544021b --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.inverse.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DFloats.inverse +========================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DFloats.inverse \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DFloats.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.rst.txt new file mode 100644 index 000000000..5b94dd99d --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.rst.txt @@ -0,0 +1,47 @@ +gustaf.helpers.data.Unique2DFloats +================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: Unique2DFloats + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Unique2DFloats.ids + + + Unique2DFloats.intersection + + + Unique2DFloats.inverse + + + Unique2DFloats.values + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DFloats.values.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.values.rst.txt new file mode 100644 index 000000000..7f336aa78 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DFloats.values.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DFloats.values +========================================= + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DFloats.values \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.counts.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.counts.rst.txt new file mode 100644 index 000000000..e0818a04b --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.counts.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DIntegers.counts +=========================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DIntegers.counts \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.ids.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.ids.rst.txt new file mode 100644 index 000000000..3e1e73598 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.ids.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DIntegers.ids +======================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DIntegers.ids \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.rst.txt new file mode 100644 index 000000000..6a2be2170 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.inverse.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DIntegers.inverse +============================================ + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DIntegers.inverse \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.rst.txt new file mode 100644 index 000000000..0bac64c95 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.rst.txt @@ -0,0 +1,47 @@ +gustaf.helpers.data.Unique2DIntegers +==================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: Unique2DIntegers + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Unique2DIntegers.counts + + + Unique2DIntegers.ids + + + Unique2DIntegers.inverse + + + Unique2DIntegers.values + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.values.rst.txt b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.values.rst.txt new file mode 100644 index 000000000..254de9bc0 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.Unique2DIntegers.values.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.Unique2DIntegers.values +=========================================== + +.. currentmodule:: gustaf.helpers.data + +.. autoattribute:: Unique2DIntegers.values \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.VertexData.as_arrow.rst.txt b/_sources/_generated/gustaf.helpers.data.VertexData.as_arrow.rst.txt new file mode 100644 index 000000000..474cc0f5e --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.VertexData.as_arrow.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.VertexData.as\_arrow +======================================== + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: VertexData.as_arrow \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.VertexData.as_scalar.rst.txt b/_sources/_generated/gustaf.helpers.data.VertexData.as_scalar.rst.txt new file mode 100644 index 000000000..21a91e377 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.VertexData.as_scalar.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.VertexData.as\_scalar +========================================= + +.. currentmodule:: gustaf.helpers.data + +.. automethod:: VertexData.as_scalar \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.VertexData.rst.txt b/_sources/_generated/gustaf.helpers.data.VertexData.rst.txt new file mode 100644 index 000000000..5af6096e4 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.VertexData.rst.txt @@ -0,0 +1,54 @@ +gustaf.helpers.data.VertexData +============================== + +.. currentmodule:: gustaf.helpers.data + +.. autoclass:: VertexData + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + VertexData.as_arrow + + + + + VertexData.as_scalar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.make_tracked_array.rst.txt b/_sources/_generated/gustaf.helpers.data.make_tracked_array.rst.txt new file mode 100644 index 000000000..abbaf7396 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.make_tracked_array.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.data.make\_tracked\_array +======================================== + +.. currentmodule:: gustaf.helpers.data + +.. autofunction:: make_tracked_array \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.data.rst.txt b/_sources/_generated/gustaf.helpers.data.rst.txt new file mode 100644 index 000000000..e2328b91f --- /dev/null +++ b/_sources/_generated/gustaf.helpers.data.rst.txt @@ -0,0 +1,46 @@ +.. _gustaf.helpers.data: + +gustaf.helpers.data +=================== + +.. automodule:: gustaf.helpers.data + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + make_tracked_array + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + ComputedData + ComputedMeshData + DataHolder + TrackedArray + Unique2DFloats + Unique2DIntegers + VertexData + + + + + + + + + diff --git a/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.rst.txt b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.rst.txt new file mode 100644 index 000000000..cd02cd7cd --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.clear.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.notebook.K3DPlotterN.clear +========================================= + +.. currentmodule:: gustaf.helpers.notebook + +.. automethod:: K3DPlotterN.clear \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.close.rst.txt b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.close.rst.txt new file mode 100644 index 000000000..f0ce4212a --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.close.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.notebook.K3DPlotterN.close +========================================= + +.. currentmodule:: gustaf.helpers.notebook + +.. automethod:: K3DPlotterN.close \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.display.rst.txt b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.display.rst.txt new file mode 100644 index 000000000..dd3dceb0f --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.display.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.notebook.K3DPlotterN.display +=========================================== + +.. currentmodule:: gustaf.helpers.notebook + +.. automethod:: K3DPlotterN.display \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.rst.txt b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.rst.txt new file mode 100644 index 000000000..7db908401 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.rst.txt @@ -0,0 +1,182 @@ +gustaf.helpers.notebook.K3DPlotterN +=================================== + +.. currentmodule:: gustaf.helpers.notebook + +.. autoclass:: K3DPlotterN + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + K3DPlotterN.clear + + + + + K3DPlotterN.close + + + + + + + + K3DPlotterN.display + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K3DPlotterN.show + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.show.rst.txt b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.show.rst.txt new file mode 100644 index 000000000..18d1f0d2d --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.K3DPlotterN.show.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.notebook.K3DPlotterN.show +======================================== + +.. currentmodule:: gustaf.helpers.notebook + +.. automethod:: K3DPlotterN.show \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.get_shape.rst.txt b/_sources/_generated/gustaf.helpers.notebook.get_shape.rst.txt new file mode 100644 index 000000000..31fc65885 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.get_shape.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.notebook.get\_shape +================================== + +.. currentmodule:: gustaf.helpers.notebook + +.. autofunction:: get_shape \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.notebook.rst.txt b/_sources/_generated/gustaf.helpers.notebook.rst.txt new file mode 100644 index 000000000..46b4c6add --- /dev/null +++ b/_sources/_generated/gustaf.helpers.notebook.rst.txt @@ -0,0 +1,40 @@ +.. _gustaf.helpers.notebook: + +gustaf.helpers.notebook +======================= + +.. automodule:: gustaf.helpers.notebook + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + get_shape + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + K3DPlotterN + + + + + + + + + diff --git a/_sources/_generated/gustaf.helpers.options.Option.allowed_types.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.allowed_types.rst.txt new file mode 100644 index 000000000..748926574 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.allowed_types.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.Option.allowed\_types +============================================ + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: Option.allowed_types \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.Option.backends.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.backends.rst.txt new file mode 100644 index 000000000..d19fc8036 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.backends.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.Option.backends +====================================== + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: Option.backends \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.Option.default.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.default.rst.txt new file mode 100644 index 000000000..477b35d85 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.default.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.Option.default +===================================== + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: Option.default \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.Option.description.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.description.rst.txt new file mode 100644 index 000000000..e2d87fdef --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.description.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.Option.description +========================================= + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: Option.description \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.Option.key.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.key.rst.txt new file mode 100644 index 000000000..5bdf3c6d8 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.key.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.Option.key +================================= + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: Option.key \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.Option.rst.txt b/_sources/_generated/gustaf.helpers.options.Option.rst.txt new file mode 100644 index 000000000..f53fd8aea --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.Option.rst.txt @@ -0,0 +1,44 @@ +gustaf.helpers.options.Option +============================= + +.. currentmodule:: gustaf.helpers.options + +.. autoclass:: Option + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Option.backends + + + Option.key + + + Option.description + + + Option.allowed_types + + + Option.default + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.SetDefault.default.rst.txt b/_sources/_generated/gustaf.helpers.options.SetDefault.default.rst.txt new file mode 100644 index 000000000..a2c13101c --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.SetDefault.default.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.SetDefault.default +========================================= + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: SetDefault.default \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.SetDefault.key.rst.txt b/_sources/_generated/gustaf.helpers.options.SetDefault.key.rst.txt new file mode 100644 index 000000000..091d8d7d5 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.SetDefault.key.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.SetDefault.key +===================================== + +.. currentmodule:: gustaf.helpers.options + +.. autoattribute:: SetDefault.key \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.SetDefault.rst.txt b/_sources/_generated/gustaf.helpers.options.SetDefault.rst.txt new file mode 100644 index 000000000..a25baad18 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.SetDefault.rst.txt @@ -0,0 +1,35 @@ +gustaf.helpers.options.SetDefault +================================= + +.. currentmodule:: gustaf.helpers.options + +.. autoclass:: SetDefault + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + SetDefault.key + + + SetDefault.default + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.clear.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.clear.rst.txt new file mode 100644 index 000000000..3456efc10 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.clear.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.clear +======================================= + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.clear \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.rst.txt new file mode 100644 index 000000000..acf0628a4 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.copy_valid_options.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.copy\_valid\_options +====================================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.copy_valid_options \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.get.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.get.rst.txt new file mode 100644 index 000000000..68a4f4439 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.get.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.get +===================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.get \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.items.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.items.rst.txt new file mode 100644 index 000000000..84da86bcb --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.items.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.items +======================================= + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.items \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.keys.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.keys.rst.txt new file mode 100644 index 000000000..dd44db70a --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.keys.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.keys +====================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.keys \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.pop.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.pop.rst.txt new file mode 100644 index 000000000..01e02e5ca --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.pop.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.pop +===================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.pop \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.rst.txt new file mode 100644 index 000000000..7bd67c1a6 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.rst.txt @@ -0,0 +1,68 @@ +gustaf.helpers.options.ShowOption +================================= + +.. currentmodule:: gustaf.helpers.options + +.. autoclass:: ShowOption + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + ShowOption.clear + + + + + ShowOption.copy_valid_options + + + + + ShowOption.get + + + + + ShowOption.items + + + + + ShowOption.keys + + + + + ShowOption.pop + + + + + ShowOption.update + + + + + ShowOption.valid_keys + + + + + ShowOption.values + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.update.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.update.rst.txt new file mode 100644 index 000000000..22c2ccf70 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.update.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.update +======================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.update \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.valid_keys.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.valid_keys.rst.txt new file mode 100644 index 000000000..931b568dd --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.valid_keys.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.valid\_keys +============================================= + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.valid_keys \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.ShowOption.values.rst.txt b/_sources/_generated/gustaf.helpers.options.ShowOption.values.rst.txt new file mode 100644 index 000000000..b5e4a72fc --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.ShowOption.values.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.ShowOption.values +======================================== + +.. currentmodule:: gustaf.helpers.options + +.. automethod:: ShowOption.values \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.make_valid_options.rst.txt b/_sources/_generated/gustaf.helpers.options.make_valid_options.rst.txt new file mode 100644 index 000000000..55203e723 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.make_valid_options.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.options.make\_valid\_options +=========================================== + +.. currentmodule:: gustaf.helpers.options + +.. autofunction:: make_valid_options \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.options.rst.txt b/_sources/_generated/gustaf.helpers.options.rst.txt new file mode 100644 index 000000000..52a356b45 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.options.rst.txt @@ -0,0 +1,42 @@ +.. _gustaf.helpers.options: + +gustaf.helpers.options +====================== + +.. automodule:: gustaf.helpers.options + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + make_valid_options + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Option + SetDefault + ShowOption + + + + + + + + + diff --git a/_sources/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.rst.txt b/_sources/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.rst.txt new file mode 100644 index 000000000..cbf734f78 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.raise_if.ModuleImportRaiser.rst.txt @@ -0,0 +1,23 @@ +gustaf.helpers.raise\_if.ModuleImportRaiser +=========================================== + +.. currentmodule:: gustaf.helpers.raise_if + +.. autoclass:: ModuleImportRaiser + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.rst.txt b/_sources/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.rst.txt new file mode 100644 index 000000000..3f624ebd3 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.raise_if.invalid_inherited_attr.rst.txt @@ -0,0 +1,6 @@ +gustaf.helpers.raise\_if.invalid\_inherited\_attr +================================================= + +.. currentmodule:: gustaf.helpers.raise_if + +.. autofunction:: invalid_inherited_attr \ No newline at end of file diff --git a/_sources/_generated/gustaf.helpers.raise_if.rst.txt b/_sources/_generated/gustaf.helpers.raise_if.rst.txt new file mode 100644 index 000000000..b8829b308 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.raise_if.rst.txt @@ -0,0 +1,40 @@ +.. _gustaf.helpers.raise_if: + +gustaf.helpers.raise\_if +======================== + +.. automodule:: gustaf.helpers.raise_if + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + invalid_inherited_attr + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + ModuleImportRaiser + + + + + + + + + diff --git a/_sources/_generated/gustaf.helpers.rst.txt b/_sources/_generated/gustaf.helpers.rst.txt new file mode 100644 index 000000000..0a4a00514 --- /dev/null +++ b/_sources/_generated/gustaf.helpers.rst.txt @@ -0,0 +1,37 @@ +.. _gustaf.helpers: + +gustaf.helpers +============== + +.. automodule:: gustaf.helpers + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: + :recursive: + + gustaf.helpers.data + gustaf.helpers.notebook + gustaf.helpers.options + gustaf.helpers.raise_if + diff --git a/_sources/_generated/gustaf.io.default.load.rst.txt b/_sources/_generated/gustaf.io.default.load.rst.txt new file mode 100644 index 000000000..68dbbbb11 --- /dev/null +++ b/_sources/_generated/gustaf.io.default.load.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.default.load +====================== + +.. currentmodule:: gustaf.io.default + +.. autofunction:: load \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.default.rst.txt b/_sources/_generated/gustaf.io.default.rst.txt new file mode 100644 index 000000000..7f1e40e1b --- /dev/null +++ b/_sources/_generated/gustaf.io.default.rst.txt @@ -0,0 +1,32 @@ +.. _gustaf.io.default: + +gustaf.io.default +================= + +.. automodule:: gustaf.io.default + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + load + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.ioutils.abs_fname.rst.txt b/_sources/_generated/gustaf.io.ioutils.abs_fname.rst.txt new file mode 100644 index 000000000..be06c045a --- /dev/null +++ b/_sources/_generated/gustaf.io.ioutils.abs_fname.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.ioutils.abs\_fname +============================ + +.. currentmodule:: gustaf.io.ioutils + +.. autofunction:: abs_fname \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.ioutils.check_and_makedirs.rst.txt b/_sources/_generated/gustaf.io.ioutils.check_and_makedirs.rst.txt new file mode 100644 index 000000000..ae79d1ed5 --- /dev/null +++ b/_sources/_generated/gustaf.io.ioutils.check_and_makedirs.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.ioutils.check\_and\_makedirs +====================================== + +.. currentmodule:: gustaf.io.ioutils + +.. autofunction:: check_and_makedirs \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.ioutils.rst.txt b/_sources/_generated/gustaf.io.ioutils.rst.txt new file mode 100644 index 000000000..8db331560 --- /dev/null +++ b/_sources/_generated/gustaf.io.ioutils.rst.txt @@ -0,0 +1,33 @@ +.. _gustaf.io.ioutils: + +gustaf.io.ioutils +================= + +.. automodule:: gustaf.io.ioutils + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + abs_fname + check_and_makedirs + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.meshio.export.rst.txt b/_sources/_generated/gustaf.io.meshio.export.rst.txt new file mode 100644 index 000000000..f06e20b69 --- /dev/null +++ b/_sources/_generated/gustaf.io.meshio.export.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.meshio.export +======================= + +.. currentmodule:: gustaf.io.meshio + +.. autofunction:: export \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.meshio.load.rst.txt b/_sources/_generated/gustaf.io.meshio.load.rst.txt new file mode 100644 index 000000000..2962ce746 --- /dev/null +++ b/_sources/_generated/gustaf.io.meshio.load.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.meshio.load +===================== + +.. currentmodule:: gustaf.io.meshio + +.. autofunction:: load \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.meshio.rst.txt b/_sources/_generated/gustaf.io.meshio.rst.txt new file mode 100644 index 000000000..baf44782c --- /dev/null +++ b/_sources/_generated/gustaf.io.meshio.rst.txt @@ -0,0 +1,33 @@ +.. _gustaf.io.meshio: + +gustaf.io.meshio +================ + +.. automodule:: gustaf.io.meshio + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + export + load + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.mfem.export.rst.txt b/_sources/_generated/gustaf.io.mfem.export.rst.txt new file mode 100644 index 000000000..8e549491e --- /dev/null +++ b/_sources/_generated/gustaf.io.mfem.export.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.mfem.export +===================== + +.. currentmodule:: gustaf.io.mfem + +.. autofunction:: export \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.mfem.load.rst.txt b/_sources/_generated/gustaf.io.mfem.load.rst.txt new file mode 100644 index 000000000..62a878150 --- /dev/null +++ b/_sources/_generated/gustaf.io.mfem.load.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.mfem.load +=================== + +.. currentmodule:: gustaf.io.mfem + +.. autofunction:: load \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.mfem.rst.txt b/_sources/_generated/gustaf.io.mfem.rst.txt new file mode 100644 index 000000000..fc92d271d --- /dev/null +++ b/_sources/_generated/gustaf.io.mfem.rst.txt @@ -0,0 +1,33 @@ +.. _gustaf.io.mfem: + +gustaf.io.mfem +============== + +.. automodule:: gustaf.io.mfem + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + export + load + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.mixd.export.rst.txt b/_sources/_generated/gustaf.io.mixd.export.rst.txt new file mode 100644 index 000000000..58bcb7db3 --- /dev/null +++ b/_sources/_generated/gustaf.io.mixd.export.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.mixd.export +===================== + +.. currentmodule:: gustaf.io.mixd + +.. autofunction:: export \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.mixd.load.rst.txt b/_sources/_generated/gustaf.io.mixd.load.rst.txt new file mode 100644 index 000000000..c4a2e0320 --- /dev/null +++ b/_sources/_generated/gustaf.io.mixd.load.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.mixd.load +=================== + +.. currentmodule:: gustaf.io.mixd + +.. autofunction:: load \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.mixd.make_mrng.rst.txt b/_sources/_generated/gustaf.io.mixd.make_mrng.rst.txt new file mode 100644 index 000000000..8595a91e7 --- /dev/null +++ b/_sources/_generated/gustaf.io.mixd.make_mrng.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.mixd.make\_mrng +========================= + +.. currentmodule:: gustaf.io.mixd + +.. autofunction:: make_mrng \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.mixd.rst.txt b/_sources/_generated/gustaf.io.mixd.rst.txt new file mode 100644 index 000000000..7c89faad4 --- /dev/null +++ b/_sources/_generated/gustaf.io.mixd.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.io.mixd: + +gustaf.io.mixd +============== + +.. automodule:: gustaf.io.mixd + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + export + load + make_mrng + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.nutils.export.rst.txt b/_sources/_generated/gustaf.io.nutils.export.rst.txt new file mode 100644 index 000000000..475d4b01e --- /dev/null +++ b/_sources/_generated/gustaf.io.nutils.export.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.nutils.export +======================= + +.. currentmodule:: gustaf.io.nutils + +.. autofunction:: export \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.nutils.load.rst.txt b/_sources/_generated/gustaf.io.nutils.load.rst.txt new file mode 100644 index 000000000..2f64f87ed --- /dev/null +++ b/_sources/_generated/gustaf.io.nutils.load.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.nutils.load +===================== + +.. currentmodule:: gustaf.io.nutils + +.. autofunction:: load \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.nutils.rst.txt b/_sources/_generated/gustaf.io.nutils.rst.txt new file mode 100644 index 000000000..328e40f00 --- /dev/null +++ b/_sources/_generated/gustaf.io.nutils.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.io.nutils: + +gustaf.io.nutils +================ + +.. automodule:: gustaf.io.nutils + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + export + load + to_nutils_simplex + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.io.nutils.to_nutils_simplex.rst.txt b/_sources/_generated/gustaf.io.nutils.to_nutils_simplex.rst.txt new file mode 100644 index 000000000..4a92a5537 --- /dev/null +++ b/_sources/_generated/gustaf.io.nutils.to_nutils_simplex.rst.txt @@ -0,0 +1,6 @@ +gustaf.io.nutils.to\_nutils\_simplex +==================================== + +.. currentmodule:: gustaf.io.nutils + +.. autofunction:: to_nutils_simplex \ No newline at end of file diff --git a/_sources/_generated/gustaf.io.rst.txt b/_sources/_generated/gustaf.io.rst.txt new file mode 100644 index 000000000..df93be5d0 --- /dev/null +++ b/_sources/_generated/gustaf.io.rst.txt @@ -0,0 +1,39 @@ +.. _gustaf.io: + +gustaf.io +========= + +.. automodule:: gustaf.io + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: + :recursive: + + gustaf.io.default + gustaf.io.ioutils + gustaf.io.meshio + gustaf.io.mfem + gustaf.io.mixd + gustaf.io.nutils + diff --git a/_sources/_generated/gustaf.rst.txt b/_sources/_generated/gustaf.rst.txt new file mode 100644 index 000000000..a02f7d1b3 --- /dev/null +++ b/_sources/_generated/gustaf.rst.txt @@ -0,0 +1,43 @@ +.. _gustaf: + +gustaf +====== + +.. automodule:: gustaf + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: + :recursive: + + gustaf.create + gustaf.edges + gustaf.faces + gustaf.helpers + gustaf.io + gustaf.settings + gustaf.show + gustaf.utils + gustaf.vertices + gustaf.volumes + diff --git a/_sources/_generated/gustaf.settings.rst.txt b/_sources/_generated/gustaf.settings.rst.txt new file mode 100644 index 000000000..e2c41abab --- /dev/null +++ b/_sources/_generated/gustaf.settings.rst.txt @@ -0,0 +1,25 @@ +.. _gustaf.settings: + +gustaf.settings +=============== + +.. automodule:: gustaf.settings + + + + + + + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.show.interpolate_vedo_dictcam.rst.txt b/_sources/_generated/gustaf.show.interpolate_vedo_dictcam.rst.txt new file mode 100644 index 000000000..0fee90083 --- /dev/null +++ b/_sources/_generated/gustaf.show.interpolate_vedo_dictcam.rst.txt @@ -0,0 +1,6 @@ +gustaf.show.interpolate\_vedo\_dictcam +====================================== + +.. currentmodule:: gustaf.show + +.. autofunction:: interpolate_vedo_dictcam \ No newline at end of file diff --git a/_sources/_generated/gustaf.show.make_showable.rst.txt b/_sources/_generated/gustaf.show.make_showable.rst.txt new file mode 100644 index 000000000..0638ce791 --- /dev/null +++ b/_sources/_generated/gustaf.show.make_showable.rst.txt @@ -0,0 +1,6 @@ +gustaf.show.make\_showable +========================== + +.. currentmodule:: gustaf.show + +.. autofunction:: make_showable \ No newline at end of file diff --git a/_sources/_generated/gustaf.show.rst.txt b/_sources/_generated/gustaf.show.rst.txt new file mode 100644 index 000000000..decf1658c --- /dev/null +++ b/_sources/_generated/gustaf.show.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.show: + +gustaf.show +=========== + +.. automodule:: gustaf.show + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + interpolate_vedo_dictcam + make_showable + show + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.show.show.rst.txt b/_sources/_generated/gustaf.show.show.rst.txt new file mode 100644 index 000000000..d6af1788c --- /dev/null +++ b/_sources/_generated/gustaf.show.show.rst.txt @@ -0,0 +1,6 @@ +gustaf.show.show +================ + +.. currentmodule:: gustaf.show + +.. autofunction:: show \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.bounds.rst.txt b/_sources/_generated/gustaf.utils.arr.bounds.rst.txt new file mode 100644 index 000000000..6a51b4914 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.bounds.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.bounds +======================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: bounds \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.bounds_diagonal.rst.txt b/_sources/_generated/gustaf.utils.arr.bounds_diagonal.rst.txt new file mode 100644 index 000000000..f4c6f49a0 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.bounds_diagonal.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.bounds\_diagonal +================================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: bounds_diagonal \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.bounds_mean.rst.txt b/_sources/_generated/gustaf.utils.arr.bounds_mean.rst.txt new file mode 100644 index 000000000..58e0770b4 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.bounds_mean.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.bounds\_mean +============================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: bounds_mean \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.bounds_norm.rst.txt b/_sources/_generated/gustaf.utils.arr.bounds_norm.rst.txt new file mode 100644 index 000000000..f61e2d22d --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.bounds_norm.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.bounds\_norm +============================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: bounds_norm \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.close_rows.rst.txt b/_sources/_generated/gustaf.utils.arr.close_rows.rst.txt new file mode 100644 index 000000000..ddc56b71b --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.close_rows.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.close\_rows +============================ + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: close_rows \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.cross3d.rst.txt b/_sources/_generated/gustaf.utils.arr.cross3d.rst.txt new file mode 100644 index 000000000..24990939a --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.cross3d.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.cross3d +======================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: cross3d \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.derivatives_to_normals.rst.txt b/_sources/_generated/gustaf.utils.arr.derivatives_to_normals.rst.txt new file mode 100644 index 000000000..81e10dce2 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.derivatives_to_normals.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.derivatives\_to\_normals +========================================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: derivatives_to_normals \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.enforce_len.rst.txt b/_sources/_generated/gustaf.utils.arr.enforce_len.rst.txt new file mode 100644 index 000000000..ea6b1dfbc --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.enforce_len.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.enforce\_len +============================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: enforce_len \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.is_one_of_shapes.rst.txt b/_sources/_generated/gustaf.utils.arr.is_one_of_shapes.rst.txt new file mode 100644 index 000000000..1cfd10849 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.is_one_of_shapes.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.is\_one\_of\_shapes +==================================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: is_one_of_shapes \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.is_shape.rst.txt b/_sources/_generated/gustaf.utils.arr.is_shape.rst.txt new file mode 100644 index 000000000..be9f86729 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.is_shape.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.is\_shape +========================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: is_shape \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.make_c_contiguous.rst.txt b/_sources/_generated/gustaf.utils.arr.make_c_contiguous.rst.txt new file mode 100644 index 000000000..e1d79b522 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.make_c_contiguous.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.make\_c\_contiguous +==================================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: make_c_contiguous \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.rotate.rst.txt b/_sources/_generated/gustaf.utils.arr.rotate.rst.txt new file mode 100644 index 000000000..f84a5e144 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.rotate.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.rotate +======================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: rotate \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.rotation_matrix.rst.txt b/_sources/_generated/gustaf.utils.arr.rotation_matrix.rst.txt new file mode 100644 index 000000000..4aad1c879 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.rotation_matrix.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.rotation\_matrix +================================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: rotation_matrix \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.rotation_matrix_around_axis.rst.txt b/_sources/_generated/gustaf.utils.arr.rotation_matrix_around_axis.rst.txt new file mode 100644 index 000000000..a958fd1b1 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.rotation_matrix_around_axis.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.rotation\_matrix\_around\_axis +=============================================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: rotation_matrix_around_axis \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.rst.txt b/_sources/_generated/gustaf.utils.arr.rst.txt new file mode 100644 index 000000000..ad6ffdae4 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.rst.txt @@ -0,0 +1,47 @@ +.. _gustaf.utils.arr: + +gustaf.utils.arr +================ + +.. automodule:: gustaf.utils.arr + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + bounds + bounds_diagonal + bounds_mean + bounds_norm + close_rows + cross3d + derivatives_to_normals + enforce_len + is_one_of_shapes + is_shape + make_c_contiguous + rotate + rotation_matrix + rotation_matrix_around_axis + select_with_ranges + unique_rows + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.utils.arr.select_with_ranges.rst.txt b/_sources/_generated/gustaf.utils.arr.select_with_ranges.rst.txt new file mode 100644 index 000000000..63c67dcc0 --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.select_with_ranges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.select\_with\_ranges +===================================== + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: select_with_ranges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.arr.unique_rows.rst.txt b/_sources/_generated/gustaf.utils.arr.unique_rows.rst.txt new file mode 100644 index 000000000..78692b75f --- /dev/null +++ b/_sources/_generated/gustaf.utils.arr.unique_rows.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.arr.unique\_rows +============================= + +.. currentmodule:: gustaf.utils.arr + +.. autofunction:: unique_rows \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.faces_to_edges.rst.txt b/_sources/_generated/gustaf.utils.connec.faces_to_edges.rst.txt new file mode 100644 index 000000000..35153ccbc --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.faces_to_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.faces\_to\_edges +==================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: faces_to_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.hexa_to_quad.rst.txt b/_sources/_generated/gustaf.utils.connec.hexa_to_quad.rst.txt new file mode 100644 index 000000000..8608d88a0 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.hexa_to_quad.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.hexa\_to\_quad +================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: hexa_to_quad \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.make_hexa_volumes.rst.txt b/_sources/_generated/gustaf.utils.connec.make_hexa_volumes.rst.txt new file mode 100644 index 000000000..5e1f1e9fa --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.make_hexa_volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.make\_hexa\_volumes +======================================= + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: make_hexa_volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.make_quad_faces.rst.txt b/_sources/_generated/gustaf.utils.connec.make_quad_faces.rst.txt new file mode 100644 index 000000000..1ba9f9af9 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.make_quad_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.make\_quad\_faces +===================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: make_quad_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.range_to_edges.rst.txt b/_sources/_generated/gustaf.utils.connec.range_to_edges.rst.txt new file mode 100644 index 000000000..3f175f054 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.range_to_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.range\_to\_edges +==================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: range_to_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.rst.txt b/_sources/_generated/gustaf.utils.connec.rst.txt new file mode 100644 index 000000000..35a648d57 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.rst.txt @@ -0,0 +1,44 @@ +.. _gustaf.utils.connec: + +gustaf.utils.connec +=================== + +.. automodule:: gustaf.utils.connec + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + faces_to_edges + hexa_to_quad + make_hexa_volumes + make_quad_faces + range_to_edges + sequence_to_edges + sequentialize_edges + sorted_unique + subdivide_edges + subdivide_quad + subdivide_tri + tet_to_tri + volumes_to_faces + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.utils.connec.sequence_to_edges.rst.txt b/_sources/_generated/gustaf.utils.connec.sequence_to_edges.rst.txt new file mode 100644 index 000000000..540c912e9 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.sequence_to_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.sequence\_to\_edges +======================================= + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: sequence_to_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.sequentialize_edges.rst.txt b/_sources/_generated/gustaf.utils.connec.sequentialize_edges.rst.txt new file mode 100644 index 000000000..47ee57163 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.sequentialize_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.sequentialize\_edges +======================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: sequentialize_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.sorted_unique.rst.txt b/_sources/_generated/gustaf.utils.connec.sorted_unique.rst.txt new file mode 100644 index 000000000..bb749dc4f --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.sorted_unique.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.sorted\_unique +================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: sorted_unique \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.subdivide_edges.rst.txt b/_sources/_generated/gustaf.utils.connec.subdivide_edges.rst.txt new file mode 100644 index 000000000..74c5b6e38 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.subdivide_edges.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.subdivide\_edges +==================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: subdivide_edges \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.subdivide_quad.rst.txt b/_sources/_generated/gustaf.utils.connec.subdivide_quad.rst.txt new file mode 100644 index 000000000..c8c4b4fe3 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.subdivide_quad.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.subdivide\_quad +=================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: subdivide_quad \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.subdivide_tri.rst.txt b/_sources/_generated/gustaf.utils.connec.subdivide_tri.rst.txt new file mode 100644 index 000000000..624022541 --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.subdivide_tri.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.subdivide\_tri +================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: subdivide_tri \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.tet_to_tri.rst.txt b/_sources/_generated/gustaf.utils.connec.tet_to_tri.rst.txt new file mode 100644 index 000000000..ae7a5ec3d --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.tet_to_tri.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.tet\_to\_tri +================================ + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: tet_to_tri \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.connec.volumes_to_faces.rst.txt b/_sources/_generated/gustaf.utils.connec.volumes_to_faces.rst.txt new file mode 100644 index 000000000..042a523bf --- /dev/null +++ b/_sources/_generated/gustaf.utils.connec.volumes_to_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.connec.volumes\_to\_faces +====================================== + +.. currentmodule:: gustaf.utils.connec + +.. autofunction:: volumes_to_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.log.configure.rst.txt b/_sources/_generated/gustaf.utils.log.configure.rst.txt new file mode 100644 index 000000000..7c9fb33a4 --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.configure.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.log.configure +========================== + +.. currentmodule:: gustaf.utils.log + +.. autofunction:: configure \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.log.debug.rst.txt b/_sources/_generated/gustaf.utils.log.debug.rst.txt new file mode 100644 index 000000000..93a9d9bf5 --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.debug.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.log.debug +====================== + +.. currentmodule:: gustaf.utils.log + +.. autofunction:: debug \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.log.info.rst.txt b/_sources/_generated/gustaf.utils.log.info.rst.txt new file mode 100644 index 000000000..ea8e6fbba --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.info.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.log.info +===================== + +.. currentmodule:: gustaf.utils.log + +.. autofunction:: info \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.log.prepended_log.rst.txt b/_sources/_generated/gustaf.utils.log.prepended_log.rst.txt new file mode 100644 index 000000000..67548650a --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.prepended_log.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.log.prepended\_log +=============================== + +.. currentmodule:: gustaf.utils.log + +.. autofunction:: prepended_log \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.log.rst.txt b/_sources/_generated/gustaf.utils.log.rst.txt new file mode 100644 index 000000000..cd281cc99 --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.rst.txt @@ -0,0 +1,36 @@ +.. _gustaf.utils.log: + +gustaf.utils.log +================ + +.. automodule:: gustaf.utils.log + + + + + + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + configure + debug + info + prepended_log + warning + + + + + + + + + + + + + diff --git a/_sources/_generated/gustaf.utils.log.warning.rst.txt b/_sources/_generated/gustaf.utils.log.warning.rst.txt new file mode 100644 index 000000000..32de9555e --- /dev/null +++ b/_sources/_generated/gustaf.utils.log.warning.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.log.warning +======================== + +.. currentmodule:: gustaf.utils.log + +.. autofunction:: warning \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.rst.txt b/_sources/_generated/gustaf.utils.rst.txt new file mode 100644 index 000000000..6688aebcd --- /dev/null +++ b/_sources/_generated/gustaf.utils.rst.txt @@ -0,0 +1,37 @@ +.. _gustaf.utils: + +gustaf.utils +============ + +.. automodule:: gustaf.utils + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: + :recursive: + + gustaf.utils.arr + gustaf.utils.connec + gustaf.utils.log + gustaf.utils.tictoc + diff --git a/_sources/_generated/gustaf.utils.tictoc.Tic.now.rst.txt b/_sources/_generated/gustaf.utils.tictoc.Tic.now.rst.txt new file mode 100644 index 000000000..644792ab6 --- /dev/null +++ b/_sources/_generated/gustaf.utils.tictoc.Tic.now.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.tictoc.Tic.now +=========================== + +.. currentmodule:: gustaf.utils.tictoc + +.. automethod:: Tic.now \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.tictoc.Tic.rst.txt b/_sources/_generated/gustaf.utils.tictoc.Tic.rst.txt new file mode 100644 index 000000000..7c933ba95 --- /dev/null +++ b/_sources/_generated/gustaf.utils.tictoc.Tic.rst.txt @@ -0,0 +1,38 @@ +gustaf.utils.tictoc.Tic +======================= + +.. currentmodule:: gustaf.utils.tictoc + +.. autoclass:: Tic + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + Tic.now + + + + + Tic.summary + + + + + Tic.toc + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.tictoc.Tic.summary.rst.txt b/_sources/_generated/gustaf.utils.tictoc.Tic.summary.rst.txt new file mode 100644 index 000000000..df0ca877d --- /dev/null +++ b/_sources/_generated/gustaf.utils.tictoc.Tic.summary.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.tictoc.Tic.summary +=============================== + +.. currentmodule:: gustaf.utils.tictoc + +.. automethod:: Tic.summary \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.tictoc.Tic.toc.rst.txt b/_sources/_generated/gustaf.utils.tictoc.Tic.toc.rst.txt new file mode 100644 index 000000000..86861ccec --- /dev/null +++ b/_sources/_generated/gustaf.utils.tictoc.Tic.toc.rst.txt @@ -0,0 +1,6 @@ +gustaf.utils.tictoc.Tic.toc +=========================== + +.. currentmodule:: gustaf.utils.tictoc + +.. automethod:: Tic.toc \ No newline at end of file diff --git a/_sources/_generated/gustaf.utils.tictoc.rst.txt b/_sources/_generated/gustaf.utils.tictoc.rst.txt new file mode 100644 index 000000000..08fc2f81b --- /dev/null +++ b/_sources/_generated/gustaf.utils.tictoc.rst.txt @@ -0,0 +1,33 @@ +.. _gustaf.utils.tictoc: + +gustaf.utils.tictoc +=================== + +.. automodule:: gustaf.utils.tictoc + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Tic + + + + + + + + + diff --git a/_sources/_generated/gustaf.vertices.Vertices.bounds.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.bounds.rst.txt new file mode 100644 index 000000000..d119854b0 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.bounds.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.bounds +=============================== + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.bounds \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal.rst.txt new file mode 100644 index 000000000..49fbe0e37 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.bounds\_diagonal +========================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.bounds_diagonal \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.rst.txt new file mode 100644 index 000000000..ec4be954c --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.bounds_diagonal_norm.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.bounds\_diagonal\_norm +=============================================== + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.bounds_diagonal_norm \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.concat.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.concat.rst.txt new file mode 100644 index 000000000..f8f87fcdc --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.concat.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.concat +=============================== + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.concat \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.const_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.const_vertices.rst.txt new file mode 100644 index 000000000..87bfb063b --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.const_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.const\_vertices +======================================== + +.. currentmodule:: gustaf.vertices + +.. autoproperty:: Vertices.const_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.copy.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.copy.rst.txt new file mode 100644 index 000000000..0d41280dd --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.copy.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.copy +============================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.copy \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.kind.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.kind.rst.txt new file mode 100644 index 000000000..2b90e57eb --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.kind.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.kind +============================= + +.. currentmodule:: gustaf.vertices + +.. autoattribute:: Vertices.kind \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.merge_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.merge_vertices.rst.txt new file mode 100644 index 000000000..68a9f0471 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.merge_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.merge\_vertices +======================================== + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.merge_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.remove_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.remove_vertices.rst.txt new file mode 100644 index 000000000..88d00e99c --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.remove_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.remove\_vertices +========================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.remove_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.rst.txt new file mode 100644 index 000000000..c1186fc72 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.rst.txt @@ -0,0 +1,107 @@ +gustaf.vertices.Vertices +======================== + +.. currentmodule:: gustaf.vertices + +.. autoclass:: Vertices + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + Vertices.bounds + + + + + Vertices.bounds_diagonal + + + + + Vertices.bounds_diagonal_norm + + + + + Vertices.concat + + + + + Vertices.copy + + + + + Vertices.merge_vertices + + + + + Vertices.remove_vertices + + + + + Vertices.select_vertices + + + + + Vertices.show + + + + + Vertices.showable + + + + + Vertices.unique_vertices + + + + + Vertices.update_vertices + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + Vertices.const_vertices + + + Vertices.kind + + + Vertices.show_options + + + Vertices.vertex_data + + + Vertices.vertices + + + Vertices.whatami + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.select_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.select_vertices.rst.txt new file mode 100644 index 000000000..c6fed616e --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.select_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.select\_vertices +========================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.select_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.show.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.show.rst.txt new file mode 100644 index 000000000..5ec3d30d7 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.show.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.show +============================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.show \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.show_options.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.show_options.rst.txt new file mode 100644 index 000000000..7d17f42e0 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.show_options.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.show\_options +====================================== + +.. currentmodule:: gustaf.vertices + +.. autoproperty:: Vertices.show_options \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.showable.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.showable.rst.txt new file mode 100644 index 000000000..cf31c4796 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.showable.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.showable +================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.showable \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.unique_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.unique_vertices.rst.txt new file mode 100644 index 000000000..e596dc20d --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.unique_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.unique\_vertices +========================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.unique_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.update_vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.update_vertices.rst.txt new file mode 100644 index 000000000..1899e8146 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.update_vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.update\_vertices +========================================= + +.. currentmodule:: gustaf.vertices + +.. automethod:: Vertices.update_vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.vertex_data.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.vertex_data.rst.txt new file mode 100644 index 000000000..24bf3c61d --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.vertex_data.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.vertex\_data +===================================== + +.. currentmodule:: gustaf.vertices + +.. autoproperty:: Vertices.vertex_data \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.vertices.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.vertices.rst.txt new file mode 100644 index 000000000..ee19dbaaa --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.vertices.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.vertices +================================= + +.. currentmodule:: gustaf.vertices + +.. autoproperty:: Vertices.vertices \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.Vertices.whatami.rst.txt b/_sources/_generated/gustaf.vertices.Vertices.whatami.rst.txt new file mode 100644 index 000000000..fadbdcd26 --- /dev/null +++ b/_sources/_generated/gustaf.vertices.Vertices.whatami.rst.txt @@ -0,0 +1,6 @@ +gustaf.vertices.Vertices.whatami +================================ + +.. currentmodule:: gustaf.vertices + +.. autoproperty:: Vertices.whatami \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.VerticesShowOption.rst.txt b/_sources/_generated/gustaf.vertices.VerticesShowOption.rst.txt new file mode 100644 index 000000000..dfa2fe30b --- /dev/null +++ b/_sources/_generated/gustaf.vertices.VerticesShowOption.rst.txt @@ -0,0 +1,50 @@ +gustaf.vertices.VerticesShowOption +================================== + +.. currentmodule:: gustaf.vertices + +.. autoclass:: VerticesShowOption + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.vertices.rst.txt b/_sources/_generated/gustaf.vertices.rst.txt new file mode 100644 index 000000000..2f9562d4b --- /dev/null +++ b/_sources/_generated/gustaf.vertices.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.vertices: + +gustaf.vertices +=============== + +.. automodule:: gustaf.vertices + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Vertices + VerticesShowOption + + + + + + + + + diff --git a/_sources/_generated/gustaf.volumes.Volumes.const_faces.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.const_faces.rst.txt new file mode 100644 index 000000000..f7ddfcfe3 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.const_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.const\_faces +=================================== + +.. currentmodule:: gustaf.volumes + +.. autoproperty:: Volumes.const_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.const_volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.const_volumes.rst.txt new file mode 100644 index 000000000..6dd895caf --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.const_volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.const\_volumes +===================================== + +.. currentmodule:: gustaf.volumes + +.. autoproperty:: Volumes.const_volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.faces.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.faces.rst.txt new file mode 100644 index 000000000..ac9dfcb76 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.faces +============================ + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.kind.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.kind.rst.txt new file mode 100644 index 000000000..78c6406e1 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.kind.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.kind +=========================== + +.. currentmodule:: gustaf.volumes + +.. autoattribute:: Volumes.kind \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.rst.txt new file mode 100644 index 000000000..74ac36ce1 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.rst.txt @@ -0,0 +1,172 @@ +gustaf.volumes.Volumes +====================== + +.. currentmodule:: gustaf.volumes + +.. autoclass:: Volumes + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Volumes.faces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Volumes.sorted_volumes + + + + + + + + Volumes.to_faces + + + + + + + + + + + + + + + + + + + + Volumes.unique_volumes + + + + + + + + + + + Volumes.update_faces + + + + + + + + Volumes.update_volumes + + + + + Volumes.whatareyou + + + + + + + + .. rubric:: Attributes + + .. autosummary:: + :toctree: + + + + + + Volumes.const_faces + + + + Volumes.const_volumes + + + + Volumes.kind + + + + + + Volumes.volumes + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.sorted_volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.sorted_volumes.rst.txt new file mode 100644 index 000000000..e8ce47df7 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.sorted_volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.sorted\_volumes +====================================== + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.sorted_volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.to_faces.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.to_faces.rst.txt new file mode 100644 index 000000000..e8a40c9ee --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.to_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.to\_faces +================================ + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.to_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.unique_volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.unique_volumes.rst.txt new file mode 100644 index 000000000..0b623560c --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.unique_volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.unique\_volumes +====================================== + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.unique_volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.update_faces.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.update_faces.rst.txt new file mode 100644 index 000000000..4d819e167 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.update_faces.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.update\_faces +==================================== + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.update_faces \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.update_volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.update_volumes.rst.txt new file mode 100644 index 000000000..0147218d6 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.update_volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.update\_volumes +====================================== + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.update_volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.volumes.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.volumes.rst.txt new file mode 100644 index 000000000..f2785973b --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.volumes.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.volumes +============================== + +.. currentmodule:: gustaf.volumes + +.. autoproperty:: Volumes.volumes \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.Volumes.whatareyou.rst.txt b/_sources/_generated/gustaf.volumes.Volumes.whatareyou.rst.txt new file mode 100644 index 000000000..028be048a --- /dev/null +++ b/_sources/_generated/gustaf.volumes.Volumes.whatareyou.rst.txt @@ -0,0 +1,6 @@ +gustaf.volumes.Volumes.whatareyou +================================= + +.. currentmodule:: gustaf.volumes + +.. automethod:: Volumes.whatareyou \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.VolumesShowOption.rst.txt b/_sources/_generated/gustaf.volumes.VolumesShowOption.rst.txt new file mode 100644 index 000000000..b29ecc7a8 --- /dev/null +++ b/_sources/_generated/gustaf.volumes.VolumesShowOption.rst.txt @@ -0,0 +1,50 @@ +gustaf.volumes.VolumesShowOption +================================ + +.. currentmodule:: gustaf.volumes + +.. autoclass:: VolumesShowOption + :show-inheritance: + + + + + .. rubric:: Methods + + .. autosummary:: + :toctree: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/_generated/gustaf.volumes.rst.txt b/_sources/_generated/gustaf.volumes.rst.txt new file mode 100644 index 000000000..9c93686eb --- /dev/null +++ b/_sources/_generated/gustaf.volumes.rst.txt @@ -0,0 +1,34 @@ +.. _gustaf.volumes: + +gustaf.volumes +============== + +.. automodule:: gustaf.volumes + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + :template: + + Volumes + VolumesShowOption + + + + + + + + + diff --git a/_sources/details.rst.txt b/_sources/details.rst.txt new file mode 100644 index 000000000..9e8dcd267 --- /dev/null +++ b/_sources/details.rst.txt @@ -0,0 +1,8 @@ +Feature details & options +========================= +More detailed documentations for available features and options. + +.. toctree:: + :maxdepth: 1 + + Show Options diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..7160e80f3 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,32 @@ +.. toctree:: + :maxdepth: 2 + +.. mdinclude:: ../md/README.md + +Sources +============ +.. toctree:: + Github + +Contributing +=============== +.. toctree:: + :maxdepth: 1 + + Contiributing + +Library +============ +.. toctree:: + :maxdepth: 1 + + API references + + Feature details & options
+ +.. Indices and tables +.. ================== + +.. * :ref:`genindex` +.. * :ref:`modindex` +.. * :ref:`search` diff --git a/_sources/python_api.rst.txt b/_sources/python_api.rst.txt new file mode 100644 index 000000000..9c5ec79ac --- /dev/null +++ b/_sources/python_api.rst.txt @@ -0,0 +1,6 @@ +.. autosummary:: + :toctree: _generated + :template: + :recursive: + + gustaf diff --git a/_sources/references.rst.txt b/_sources/references.rst.txt new file mode 100644 index 000000000..35a67ea72 --- /dev/null +++ b/_sources/references.rst.txt @@ -0,0 +1,7 @@ +Library References +================== + +API References +-------------- +.. toctree:: + python_api diff --git a/_sources/show_options.rst.txt b/_sources/show_options.rst.txt new file mode 100644 index 000000000..1e87aae0c --- /dev/null +++ b/_sources/show_options.rst.txt @@ -0,0 +1,4 @@ +------------ +Show Options +------------ +.. mdinclude:: ../md/show_options.md diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..2af6139e6 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 270px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..c1f8f2304 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.0.25', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/favicon.ico b/_static/favicon.ico new file mode 100644 index 000000000..f875b5737 Binary files /dev/null and b/_static/favicon.ico differ diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/gus_dark_mode.png b/_static/gus_dark_mode.png new file mode 100644 index 000000000..d9726d464 Binary files /dev/null and b/_static/gus_dark_mode.png differ diff --git a/_static/gus_light_mode.png b/_static/gus_light_mode.png new file mode 100644 index 000000000..3c9dfccdb Binary files /dev/null and b/_static/gus_light_mode.png differ diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 000000000..367b8ed81 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 000000000..997797f27 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,152 @@ +html[data-theme="light"] .highlight pre { line-height: 125%; } +html[data-theme="light"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight .hll { background-color: #7971292e } +html[data-theme="light"] .highlight { background: #fefefe; color: #545454 } +html[data-theme="light"] .highlight .c { color: #797129 } /* Comment */ +html[data-theme="light"] .highlight .err { color: #d91e18 } /* Error */ +html[data-theme="light"] .highlight .k { color: #7928a1 } /* Keyword */ +html[data-theme="light"] .highlight .l { color: #797129 } /* Literal */ +html[data-theme="light"] .highlight .n { color: #545454 } /* Name */ +html[data-theme="light"] .highlight .o { color: #008000 } /* Operator */ +html[data-theme="light"] .highlight .p { color: #545454 } /* Punctuation */ +html[data-theme="light"] .highlight .ch { color: #797129 } /* Comment.Hashbang */ +html[data-theme="light"] .highlight .cm { color: #797129 } /* Comment.Multiline */ +html[data-theme="light"] .highlight .cp { color: #797129 } /* Comment.Preproc */ +html[data-theme="light"] .highlight .cpf { color: #797129 } /* Comment.PreprocFile */ +html[data-theme="light"] .highlight .c1 { color: #797129 } /* Comment.Single */ +html[data-theme="light"] .highlight .cs { color: #797129 } /* Comment.Special */ +html[data-theme="light"] .highlight .gd { color: #007faa } /* Generic.Deleted */ +html[data-theme="light"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="light"] .highlight .gh { color: #007faa } /* Generic.Heading */ +html[data-theme="light"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="light"] .highlight .gu { color: #007faa } /* Generic.Subheading */ +html[data-theme="light"] .highlight .kc { color: #7928a1 } /* Keyword.Constant */ +html[data-theme="light"] .highlight .kd { color: #7928a1 } /* Keyword.Declaration */ +html[data-theme="light"] .highlight .kn { color: #7928a1 } /* Keyword.Namespace */ +html[data-theme="light"] .highlight .kp { color: #7928a1 } /* Keyword.Pseudo */ +html[data-theme="light"] .highlight .kr { color: #7928a1 } /* Keyword.Reserved */ +html[data-theme="light"] .highlight .kt { color: #797129 } /* Keyword.Type */ +html[data-theme="light"] .highlight .ld { color: #797129 } /* Literal.Date */ +html[data-theme="light"] .highlight .m { color: #797129 } /* Literal.Number */ +html[data-theme="light"] .highlight .s { color: #008000 } /* Literal.String */ +html[data-theme="light"] .highlight .na { color: #797129 } /* Name.Attribute */ +html[data-theme="light"] .highlight .nb { color: #797129 } /* Name.Builtin */ +html[data-theme="light"] .highlight .nc { color: #007faa } /* Name.Class */ +html[data-theme="light"] .highlight .no { color: #007faa } /* Name.Constant */ +html[data-theme="light"] .highlight .nd { color: #797129 } /* Name.Decorator */ +html[data-theme="light"] .highlight .ni { color: #008000 } /* Name.Entity */ +html[data-theme="light"] .highlight .ne { color: #7928a1 } /* Name.Exception */ +html[data-theme="light"] .highlight .nf { color: #007faa } /* Name.Function */ +html[data-theme="light"] .highlight .nl { color: #797129 } /* Name.Label */ +html[data-theme="light"] .highlight .nn { color: #545454 } /* Name.Namespace */ +html[data-theme="light"] .highlight .nx { color: #545454 } /* Name.Other */ +html[data-theme="light"] .highlight .py { color: #007faa } /* Name.Property */ +html[data-theme="light"] .highlight .nt { color: #007faa } /* Name.Tag */ +html[data-theme="light"] .highlight .nv { color: #d91e18 } /* Name.Variable */ +html[data-theme="light"] .highlight .ow { color: #7928a1 } /* Operator.Word */ +html[data-theme="light"] .highlight .pm { color: #545454 } /* Punctuation.Marker */ +html[data-theme="light"] .highlight .w { color: #545454 } /* Text.Whitespace */ +html[data-theme="light"] .highlight .mb { color: #797129 } /* Literal.Number.Bin */ +html[data-theme="light"] .highlight .mf { color: #797129 } /* Literal.Number.Float */ +html[data-theme="light"] .highlight .mh { color: #797129 } /* Literal.Number.Hex */ +html[data-theme="light"] .highlight .mi { color: #797129 } /* Literal.Number.Integer */ +html[data-theme="light"] .highlight .mo { color: #797129 } /* Literal.Number.Oct */ +html[data-theme="light"] .highlight .sa { color: #008000 } /* Literal.String.Affix */ +html[data-theme="light"] .highlight .sb { color: #008000 } /* Literal.String.Backtick */ +html[data-theme="light"] .highlight .sc { color: #008000 } /* Literal.String.Char */ +html[data-theme="light"] .highlight .dl { color: #008000 } /* Literal.String.Delimiter */ +html[data-theme="light"] .highlight .sd { color: #008000 } /* Literal.String.Doc */ +html[data-theme="light"] .highlight .s2 { color: #008000 } /* Literal.String.Double */ +html[data-theme="light"] .highlight .se { color: #008000 } /* Literal.String.Escape */ +html[data-theme="light"] .highlight .sh { color: #008000 } /* Literal.String.Heredoc */ +html[data-theme="light"] .highlight .si { color: #008000 } /* Literal.String.Interpol */ +html[data-theme="light"] .highlight .sx { color: #008000 } /* Literal.String.Other */ +html[data-theme="light"] .highlight .sr { color: #d91e18 } /* Literal.String.Regex */ +html[data-theme="light"] .highlight .s1 { color: #008000 } /* Literal.String.Single */ +html[data-theme="light"] .highlight .ss { color: #007faa } /* Literal.String.Symbol */ +html[data-theme="light"] .highlight .bp { color: #797129 } /* Name.Builtin.Pseudo */ +html[data-theme="light"] .highlight .fm { color: #007faa } /* Name.Function.Magic */ +html[data-theme="light"] .highlight .vc { color: #d91e18 } /* Name.Variable.Class */ +html[data-theme="light"] .highlight .vg { color: #d91e18 } /* Name.Variable.Global */ +html[data-theme="light"] .highlight .vi { color: #d91e18 } /* Name.Variable.Instance */ +html[data-theme="light"] .highlight .vm { color: #797129 } /* Name.Variable.Magic */ +html[data-theme="light"] .highlight .il { color: #797129 } /* Literal.Number.Integer.Long */ +html[data-theme="dark"] .highlight pre { line-height: 125%; } +html[data-theme="dark"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight .hll { background-color: #ffd9002e } +html[data-theme="dark"] .highlight { background: #2b2b2b; color: #f8f8f2 } +html[data-theme="dark"] .highlight .c { color: #ffd900 } /* Comment */ +html[data-theme="dark"] .highlight .err { color: #ffa07a } /* Error */ +html[data-theme="dark"] .highlight .k { color: #dcc6e0 } /* Keyword */ +html[data-theme="dark"] .highlight .l { color: #ffd900 } /* Literal */ +html[data-theme="dark"] .highlight .n { color: #f8f8f2 } /* Name */ +html[data-theme="dark"] .highlight .o { color: #abe338 } /* Operator */ +html[data-theme="dark"] .highlight .p { color: #f8f8f2 } /* Punctuation */ +html[data-theme="dark"] .highlight .ch { color: #ffd900 } /* Comment.Hashbang */ +html[data-theme="dark"] .highlight .cm { color: #ffd900 } /* Comment.Multiline */ +html[data-theme="dark"] .highlight .cp { color: #ffd900 } /* Comment.Preproc */ +html[data-theme="dark"] .highlight .cpf { color: #ffd900 } /* Comment.PreprocFile */ +html[data-theme="dark"] .highlight .c1 { color: #ffd900 } /* Comment.Single */ +html[data-theme="dark"] .highlight .cs { color: #ffd900 } /* Comment.Special */ +html[data-theme="dark"] .highlight .gd { color: #00e0e0 } /* Generic.Deleted */ +html[data-theme="dark"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="dark"] .highlight .gh { color: #00e0e0 } /* Generic.Heading */ +html[data-theme="dark"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="dark"] .highlight .gu { color: #00e0e0 } /* Generic.Subheading */ +html[data-theme="dark"] .highlight .kc { color: #dcc6e0 } /* Keyword.Constant */ +html[data-theme="dark"] .highlight .kd { color: #dcc6e0 } /* Keyword.Declaration */ +html[data-theme="dark"] .highlight .kn { color: #dcc6e0 } /* Keyword.Namespace */ +html[data-theme="dark"] .highlight .kp { color: #dcc6e0 } /* Keyword.Pseudo */ +html[data-theme="dark"] .highlight .kr { color: #dcc6e0 } /* Keyword.Reserved */ +html[data-theme="dark"] .highlight .kt { color: #ffd900 } /* Keyword.Type */ +html[data-theme="dark"] .highlight .ld { color: #ffd900 } /* Literal.Date */ +html[data-theme="dark"] .highlight .m { color: #ffd900 } /* Literal.Number */ +html[data-theme="dark"] .highlight .s { color: #abe338 } /* Literal.String */ +html[data-theme="dark"] .highlight .na { color: #ffd900 } /* Name.Attribute */ +html[data-theme="dark"] .highlight .nb { color: #ffd900 } /* Name.Builtin */ +html[data-theme="dark"] .highlight .nc { color: #00e0e0 } /* Name.Class */ +html[data-theme="dark"] .highlight .no { color: #00e0e0 } /* Name.Constant */ +html[data-theme="dark"] .highlight .nd { color: #ffd900 } /* Name.Decorator */ +html[data-theme="dark"] .highlight .ni { color: #abe338 } /* Name.Entity */ +html[data-theme="dark"] .highlight .ne { color: #dcc6e0 } /* Name.Exception */ +html[data-theme="dark"] .highlight .nf { color: #00e0e0 } /* Name.Function */ +html[data-theme="dark"] .highlight .nl { color: #ffd900 } /* Name.Label */ +html[data-theme="dark"] .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +html[data-theme="dark"] .highlight .nx { color: #f8f8f2 } /* Name.Other */ +html[data-theme="dark"] .highlight .py { color: #00e0e0 } /* Name.Property */ +html[data-theme="dark"] .highlight .nt { color: #00e0e0 } /* Name.Tag */ +html[data-theme="dark"] .highlight .nv { color: #ffa07a } /* Name.Variable */ +html[data-theme="dark"] .highlight .ow { color: #dcc6e0 } /* Operator.Word */ +html[data-theme="dark"] .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +html[data-theme="dark"] .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +html[data-theme="dark"] .highlight .mb { color: #ffd900 } /* Literal.Number.Bin */ +html[data-theme="dark"] .highlight .mf { color: #ffd900 } /* Literal.Number.Float */ +html[data-theme="dark"] .highlight .mh { color: #ffd900 } /* Literal.Number.Hex */ +html[data-theme="dark"] .highlight .mi { color: #ffd900 } /* Literal.Number.Integer */ +html[data-theme="dark"] .highlight .mo { color: #ffd900 } /* Literal.Number.Oct */ +html[data-theme="dark"] .highlight .sa { color: #abe338 } /* Literal.String.Affix */ +html[data-theme="dark"] .highlight .sb { color: #abe338 } /* Literal.String.Backtick */ +html[data-theme="dark"] .highlight .sc { color: #abe338 } /* Literal.String.Char */ +html[data-theme="dark"] .highlight .dl { color: #abe338 } /* Literal.String.Delimiter */ +html[data-theme="dark"] .highlight .sd { color: #abe338 } /* Literal.String.Doc */ +html[data-theme="dark"] .highlight .s2 { color: #abe338 } /* Literal.String.Double */ +html[data-theme="dark"] .highlight .se { color: #abe338 } /* Literal.String.Escape */ +html[data-theme="dark"] .highlight .sh { color: #abe338 } /* Literal.String.Heredoc */ +html[data-theme="dark"] .highlight .si { color: #abe338 } /* Literal.String.Interpol */ +html[data-theme="dark"] .highlight .sx { color: #abe338 } /* Literal.String.Other */ +html[data-theme="dark"] .highlight .sr { color: #ffa07a } /* Literal.String.Regex */ +html[data-theme="dark"] .highlight .s1 { color: #abe338 } /* Literal.String.Single */ +html[data-theme="dark"] .highlight .ss { color: #00e0e0 } /* Literal.String.Symbol */ +html[data-theme="dark"] .highlight .bp { color: #ffd900 } /* Name.Builtin.Pseudo */ +html[data-theme="dark"] .highlight .fm { color: #00e0e0 } /* Name.Function.Magic */ +html[data-theme="dark"] .highlight .vc { color: #ffa07a } /* Name.Variable.Class */ +html[data-theme="dark"] .highlight .vg { color: #ffa07a } /* Name.Variable.Global */ +html[data-theme="dark"] .highlight .vi { color: #ffa07a } /* Name.Variable.Instance */ +html[data-theme="dark"] .highlight .vm { color: #ffd900 } /* Name.Variable.Magic */ +html[data-theme="dark"] .highlight .il { color: #ffd900 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/quad.png b/_static/quad.png new file mode 100644 index 000000000..c0e8e5c17 Binary files /dev/null and b/_static/quad.png differ diff --git a/_static/scripts/bootstrap.js b/_static/scripts/bootstrap.js new file mode 100644 index 000000000..4e209b0e1 --- /dev/null +++ b/_static/scripts/bootstrap.js @@ -0,0 +1,3 @@ +/*! For license information please see bootstrap.js.LICENSE.txt */ +(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{afterMain:()=>E,afterRead:()=>v,afterWrite:()=>C,applyStyles:()=>$,arrow:()=>J,auto:()=>a,basePlacements:()=>l,beforeMain:()=>y,beforeRead:()=>_,beforeWrite:()=>A,bottom:()=>s,clippingParents:()=>d,computeStyles:()=>it,createPopper:()=>Dt,createPopperBase:()=>St,createPopperLite:()=>$t,detectOverflow:()=>_t,end:()=>h,eventListeners:()=>st,flip:()=>bt,hide:()=>wt,left:()=>r,main:()=>w,modifierPhases:()=>O,offset:()=>Et,placements:()=>g,popper:()=>f,popperGenerator:()=>Lt,popperOffsets:()=>At,preventOverflow:()=>Tt,read:()=>b,reference:()=>p,right:()=>o,start:()=>c,top:()=>n,variationPlacements:()=>m,viewport:()=>u,write:()=>T});var i={};t.r(i),t.d(i,{Alert:()=>Oe,Button:()=>ke,Carousel:()=>ri,Collapse:()=>yi,Dropdown:()=>Vi,Modal:()=>xn,Offcanvas:()=>Vn,Popover:()=>fs,ScrollSpy:()=>Ts,Tab:()=>Ks,Toast:()=>lo,Tooltip:()=>hs});var n="top",s="bottom",o="right",r="left",a="auto",l=[n,s,o,r],c="start",h="end",d="clippingParents",u="viewport",f="popper",p="reference",m=l.reduce((function(t,e){return t.concat([e+"-"+c,e+"-"+h])}),[]),g=[].concat(l,[a]).reduce((function(t,e){return t.concat([e,e+"-"+c,e+"-"+h])}),[]),_="beforeRead",b="read",v="afterRead",y="beforeMain",w="main",E="afterMain",A="beforeWrite",T="write",C="afterWrite",O=[_,b,v,y,w,E,A,T,C];function x(t){return t?(t.nodeName||"").toLowerCase():null}function k(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function L(t){return t instanceof k(t).Element||t instanceof Element}function S(t){return t instanceof k(t).HTMLElement||t instanceof HTMLElement}function D(t){return"undefined"!=typeof ShadowRoot&&(t instanceof k(t).ShadowRoot||t instanceof ShadowRoot)}const $={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];S(s)&&x(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});S(n)&&x(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function I(t){return t.split("-")[0]}var N=Math.max,P=Math.min,M=Math.round;function j(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function F(){return!/^((?!chrome|android).)*safari/i.test(j())}function H(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&S(t)&&(s=t.offsetWidth>0&&M(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&M(n.height)/t.offsetHeight||1);var r=(L(t)?k(t):window).visualViewport,a=!F()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function B(t){var e=H(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function W(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&D(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function z(t){return k(t).getComputedStyle(t)}function R(t){return["table","td","th"].indexOf(x(t))>=0}function q(t){return((L(t)?t.ownerDocument:t.document)||window.document).documentElement}function V(t){return"html"===x(t)?t:t.assignedSlot||t.parentNode||(D(t)?t.host:null)||q(t)}function Y(t){return S(t)&&"fixed"!==z(t).position?t.offsetParent:null}function K(t){for(var e=k(t),i=Y(t);i&&R(i)&&"static"===z(i).position;)i=Y(i);return i&&("html"===x(i)||"body"===x(i)&&"static"===z(i).position)?e:i||function(t){var e=/firefox/i.test(j());if(/Trident/i.test(j())&&S(t)&&"fixed"===z(t).position)return null;var i=V(t);for(D(i)&&(i=i.host);S(i)&&["html","body"].indexOf(x(i))<0;){var n=z(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Q(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function X(t,e,i){return N(t,P(e,i))}function U(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function G(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const J={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,a=t.name,c=t.options,h=i.elements.arrow,d=i.modifiersData.popperOffsets,u=I(i.placement),f=Q(u),p=[r,o].indexOf(u)>=0?"height":"width";if(h&&d){var m=function(t,e){return U("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:G(t,l))}(c.padding,i),g=B(h),_="y"===f?n:r,b="y"===f?s:o,v=i.rects.reference[p]+i.rects.reference[f]-d[f]-i.rects.popper[p],y=d[f]-i.rects.reference[f],w=K(h),E=w?"y"===f?w.clientHeight||0:w.clientWidth||0:0,A=v/2-y/2,T=m[_],C=E-g[p]-m[b],O=E/2-g[p]/2+A,x=X(T,O,C),k=f;i.modifiersData[a]=((e={})[k]=x,e.centerOffset=x-O,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&W(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Z(t){return t.split("-")[1]}var tt={top:"auto",right:"auto",bottom:"auto",left:"auto"};function et(t){var e,i=t.popper,a=t.popperRect,l=t.placement,c=t.variation,d=t.offsets,u=t.position,f=t.gpuAcceleration,p=t.adaptive,m=t.roundOffsets,g=t.isFixed,_=d.x,b=void 0===_?0:_,v=d.y,y=void 0===v?0:v,w="function"==typeof m?m({x:b,y}):{x:b,y};b=w.x,y=w.y;var E=d.hasOwnProperty("x"),A=d.hasOwnProperty("y"),T=r,C=n,O=window;if(p){var x=K(i),L="clientHeight",S="clientWidth";x===k(i)&&"static"!==z(x=q(i)).position&&"absolute"===u&&(L="scrollHeight",S="scrollWidth"),(l===n||(l===r||l===o)&&c===h)&&(C=s,y-=(g&&x===O&&O.visualViewport?O.visualViewport.height:x[L])-a.height,y*=f?1:-1),l!==r&&(l!==n&&l!==s||c!==h)||(T=o,b-=(g&&x===O&&O.visualViewport?O.visualViewport.width:x[S])-a.width,b*=f?1:-1)}var D,$=Object.assign({position:u},p&&tt),I=!0===m?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:M(i*s)/s||0,y:M(n*s)/s||0}}({x:b,y},k(i)):{x:b,y};return b=I.x,y=I.y,f?Object.assign({},$,((D={})[C]=A?"0":"",D[T]=E?"0":"",D.transform=(O.devicePixelRatio||1)<=1?"translate("+b+"px, "+y+"px)":"translate3d("+b+"px, "+y+"px, 0)",D)):Object.assign({},$,((e={})[C]=A?y+"px":"",e[T]=E?b+"px":"",e.transform="",e))}const it={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:I(e.placement),variation:Z(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,et(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,et(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var nt={passive:!0};const st={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=k(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,nt)})),a&&l.addEventListener("resize",i.update,nt),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,nt)})),a&&l.removeEventListener("resize",i.update,nt)}},data:{}};var ot={left:"right",right:"left",bottom:"top",top:"bottom"};function rt(t){return t.replace(/left|right|bottom|top/g,(function(t){return ot[t]}))}var at={start:"end",end:"start"};function lt(t){return t.replace(/start|end/g,(function(t){return at[t]}))}function ct(t){var e=k(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ht(t){return H(q(t)).left+ct(t).scrollLeft}function dt(t){var e=z(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function ut(t){return["html","body","#document"].indexOf(x(t))>=0?t.ownerDocument.body:S(t)&&dt(t)?t:ut(V(t))}function ft(t,e){var i;void 0===e&&(e=[]);var n=ut(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=k(n),r=s?[o].concat(o.visualViewport||[],dt(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ft(V(r)))}function pt(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function mt(t,e,i){return e===u?pt(function(t,e){var i=k(t),n=q(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=F();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+ht(t),y:l}}(t,i)):L(e)?function(t,e){var i=H(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):pt(function(t){var e,i=q(t),n=ct(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=N(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=N(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ht(t),l=-n.scrollTop;return"rtl"===z(s||i).direction&&(a+=N(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(q(t)))}function gt(t){var e,i=t.reference,a=t.element,l=t.placement,d=l?I(l):null,u=l?Z(l):null,f=i.x+i.width/2-a.width/2,p=i.y+i.height/2-a.height/2;switch(d){case n:e={x:f,y:i.y-a.height};break;case s:e={x:f,y:i.y+i.height};break;case o:e={x:i.x+i.width,y:p};break;case r:e={x:i.x-a.width,y:p};break;default:e={x:i.x,y:i.y}}var m=d?Q(d):null;if(null!=m){var g="y"===m?"height":"width";switch(u){case c:e[m]=e[m]-(i[g]/2-a[g]/2);break;case h:e[m]=e[m]+(i[g]/2-a[g]/2)}}return e}function _t(t,e){void 0===e&&(e={});var i=e,r=i.placement,a=void 0===r?t.placement:r,c=i.strategy,h=void 0===c?t.strategy:c,m=i.boundary,g=void 0===m?d:m,_=i.rootBoundary,b=void 0===_?u:_,v=i.elementContext,y=void 0===v?f:v,w=i.altBoundary,E=void 0!==w&&w,A=i.padding,T=void 0===A?0:A,C=U("number"!=typeof T?T:G(T,l)),O=y===f?p:f,k=t.rects.popper,D=t.elements[E?O:y],$=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ft(V(t)),i=["absolute","fixed"].indexOf(z(t).position)>=0&&S(t)?K(t):t;return L(i)?e.filter((function(t){return L(t)&&W(t,i)&&"body"!==x(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=mt(t,i,n);return e.top=N(s.top,e.top),e.right=P(s.right,e.right),e.bottom=P(s.bottom,e.bottom),e.left=N(s.left,e.left),e}),mt(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(L(D)?D:D.contextElement||q(t.elements.popper),g,b,h),I=H(t.elements.reference),M=gt({reference:I,element:k,strategy:"absolute",placement:a}),j=pt(Object.assign({},k,M)),F=y===f?j:I,B={top:$.top-F.top+C.top,bottom:F.bottom-$.bottom+C.bottom,left:$.left-F.left+C.left,right:F.right-$.right+C.right},R=t.modifiersData.offset;if(y===f&&R){var Y=R[a];Object.keys(B).forEach((function(t){var e=[o,s].indexOf(t)>=0?1:-1,i=[n,s].indexOf(t)>=0?"y":"x";B[t]+=Y[i]*e}))}return B}const bt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,h=t.name;if(!e.modifiersData[h]._skip){for(var d=i.mainAxis,u=void 0===d||d,f=i.altAxis,p=void 0===f||f,_=i.fallbackPlacements,b=i.padding,v=i.boundary,y=i.rootBoundary,w=i.altBoundary,E=i.flipVariations,A=void 0===E||E,T=i.allowedAutoPlacements,C=e.options.placement,O=I(C),x=_||(O!==C&&A?function(t){if(I(t)===a)return[];var e=rt(t);return[lt(t),e,lt(e)]}(C):[rt(C)]),k=[C].concat(x).reduce((function(t,i){return t.concat(I(i)===a?function(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,c=i.allowedAutoPlacements,h=void 0===c?g:c,d=Z(n),u=d?a?m:m.filter((function(t){return Z(t)===d})):l,f=u.filter((function(t){return h.indexOf(t)>=0}));0===f.length&&(f=u);var p=f.reduce((function(e,i){return e[i]=_t(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[I(i)],e}),{});return Object.keys(p).sort((function(t,e){return p[t]-p[e]}))}(e,{placement:i,boundary:v,rootBoundary:y,padding:b,flipVariations:A,allowedAutoPlacements:T}):i)}),[]),L=e.rects.reference,S=e.rects.popper,D=new Map,$=!0,N=k[0],P=0;P=0,B=H?"width":"height",W=_t(e,{placement:M,boundary:v,rootBoundary:y,altBoundary:w,padding:b}),z=H?F?o:r:F?s:n;L[B]>S[B]&&(z=rt(z));var R=rt(z),q=[];if(u&&q.push(W[j]<=0),p&&q.push(W[z]<=0,W[R]<=0),q.every((function(t){return t}))){N=M,$=!1;break}D.set(M,q)}if($)for(var V=function(t){var e=k.find((function(e){var i=D.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return N=e,"break"},Y=A?3:1;Y>0&&"break"!==V(Y);Y--);e.placement!==N&&(e.modifiersData[h]._skip=!0,e.placement=N,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function vt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function yt(t){return[n,o,s,r].some((function(e){return t[e]>=0}))}const wt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=_t(e,{elementContext:"reference"}),a=_t(e,{altBoundary:!0}),l=vt(r,n),c=vt(a,s,o),h=yt(l),d=yt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Et={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,s=t.name,a=i.offset,l=void 0===a?[0,0]:a,c=g.reduce((function(t,i){return t[i]=function(t,e,i){var s=I(t),a=[r,n].indexOf(s)>=0?-1:1,l="function"==typeof i?i(Object.assign({},e,{placement:t})):i,c=l[0],h=l[1];return c=c||0,h=(h||0)*a,[r,o].indexOf(s)>=0?{x:h,y:c}:{x:c,y:h}}(i,e.rects,l),t}),{}),h=c[e.placement],d=h.x,u=h.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=d,e.modifiersData.popperOffsets.y+=u),e.modifiersData[s]=c}},At={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=gt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Tt={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,a=t.name,l=i.mainAxis,h=void 0===l||l,d=i.altAxis,u=void 0!==d&&d,f=i.boundary,p=i.rootBoundary,m=i.altBoundary,g=i.padding,_=i.tether,b=void 0===_||_,v=i.tetherOffset,y=void 0===v?0:v,w=_t(e,{boundary:f,rootBoundary:p,padding:g,altBoundary:m}),E=I(e.placement),A=Z(e.placement),T=!A,C=Q(E),O="x"===C?"y":"x",x=e.modifiersData.popperOffsets,k=e.rects.reference,L=e.rects.popper,S="function"==typeof y?y(Object.assign({},e.rects,{placement:e.placement})):y,D="number"==typeof S?{mainAxis:S,altAxis:S}:Object.assign({mainAxis:0,altAxis:0},S),$=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,M={x:0,y:0};if(x){if(h){var j,F="y"===C?n:r,H="y"===C?s:o,W="y"===C?"height":"width",z=x[C],R=z+w[F],q=z-w[H],V=b?-L[W]/2:0,Y=A===c?k[W]:L[W],U=A===c?-L[W]:-k[W],G=e.elements.arrow,J=b&&G?B(G):{width:0,height:0},tt=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},et=tt[F],it=tt[H],nt=X(0,k[W],J[W]),st=T?k[W]/2-V-nt-et-D.mainAxis:Y-nt-et-D.mainAxis,ot=T?-k[W]/2+V+nt+it+D.mainAxis:U+nt+it+D.mainAxis,rt=e.elements.arrow&&K(e.elements.arrow),at=rt?"y"===C?rt.clientTop||0:rt.clientLeft||0:0,lt=null!=(j=null==$?void 0:$[C])?j:0,ct=z+ot-lt,ht=X(b?P(R,z+st-lt-at):R,z,b?N(q,ct):q);x[C]=ht,M[C]=ht-z}if(u){var dt,ut="x"===C?n:r,ft="x"===C?s:o,pt=x[O],mt="y"===O?"height":"width",gt=pt+w[ut],bt=pt-w[ft],vt=-1!==[n,r].indexOf(E),yt=null!=(dt=null==$?void 0:$[O])?dt:0,wt=vt?gt:pt-k[mt]-L[mt]-yt+D.altAxis,Et=vt?pt+k[mt]+L[mt]-yt-D.altAxis:bt,At=b&&vt?function(t,e,i){var n=X(t,e,i);return n>i?i:n}(wt,pt,Et):X(b?wt:gt,pt,b?Et:bt);x[O]=At,M[O]=At-pt}e.modifiersData[a]=M}},requiresIfExists:["offset"]};function Ct(t,e,i){void 0===i&&(i=!1);var n,s,o=S(e),r=S(e)&&function(t){var e=t.getBoundingClientRect(),i=M(e.width)/t.offsetWidth||1,n=M(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=q(e),l=H(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==x(e)||dt(a))&&(c=(n=e)!==k(n)&&S(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ct(n)),S(e)?((h=H(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=ht(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function Ot(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var xt={placement:"bottom",modifiers:[],strategy:"absolute"};function kt(){for(var t=arguments.length,e=new Array(t),i=0;iIt.has(t)&&It.get(t).get(e)||null,remove(t,e){if(!It.has(t))return;const i=It.get(t);i.delete(e),0===i.size&&It.delete(t)}},Pt="transitionend",Mt=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),jt=t=>{t.dispatchEvent(new Event(Pt))},Ft=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),Ht=t=>Ft(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(Mt(t)):null,Bt=t=>{if(!Ft(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},Wt=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),zt=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?zt(t.parentNode):null},Rt=()=>{},qt=t=>{t.offsetHeight},Vt=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Yt=[],Kt=()=>"rtl"===document.documentElement.dir,Qt=t=>{var e;e=()=>{const e=Vt();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(Yt.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of Yt)t()})),Yt.push(e)):e()},Xt=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,Ut=(t,e,i=!0)=>{if(!i)return void Xt(t);const n=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let s=!1;const o=({target:i})=>{i===e&&(s=!0,e.removeEventListener(Pt,o),Xt(t))};e.addEventListener(Pt,o),setTimeout((()=>{s||jt(e)}),n)},Gt=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},Jt=/[^.]*(?=\..*)\.|.*/,Zt=/\..*/,te=/::\d+$/,ee={};let ie=1;const ne={mouseenter:"mouseover",mouseleave:"mouseout"},se=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function oe(t,e){return e&&`${e}::${ie++}`||t.uidEvent||ie++}function re(t){const e=oe(t);return t.uidEvent=e,ee[e]=ee[e]||{},ee[e]}function ae(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function le(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=ue(t);return se.has(o)||(o=t),[n,s,o]}function ce(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=le(e,i,n);if(e in ne){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=re(t),c=l[a]||(l[a]={}),h=ae(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=oe(r,e.replace(Jt,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return pe(s,{delegateTarget:r}),n.oneOff&&fe.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return pe(n,{delegateTarget:t}),i.oneOff&&fe.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function he(t,e,i,n,s){const o=ae(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function de(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&he(t,e,i,r.callable,r.delegationSelector)}function ue(t){return t=t.replace(Zt,""),ne[t]||t}const fe={on(t,e,i,n){ce(t,e,i,n,!1)},one(t,e,i,n){ce(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=le(e,i,n),a=r!==e,l=re(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))de(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(te,"");a&&!e.includes(s)||he(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;he(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=Vt();let s=null,o=!0,r=!0,a=!1;e!==ue(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=pe(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function pe(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function me(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function ge(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const _e={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${ge(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${ge(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=me(t.dataset[n])}return e},getDataAttribute:(t,e)=>me(t.getAttribute(`data-bs-${ge(e)}`))};class be{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=Ft(e)?_e.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...Ft(e)?_e.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],o=Ft(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${o}" but expected type "${s}".`)}var i}}class ve extends be{constructor(t,e){super(),(t=Ht(t))&&(this._element=t,this._config=this._getConfig(e),Nt.set(this._element,this.constructor.DATA_KEY,this))}dispose(){Nt.remove(this._element,this.constructor.DATA_KEY),fe.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){Ut(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return Nt.get(Ht(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const ye=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?Mt(i.trim()):null}return e},we={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!Wt(t)&&Bt(t)))},getSelectorFromElement(t){const e=ye(t);return e&&we.findOne(e)?e:null},getElementFromSelector(t){const e=ye(t);return e?we.findOne(e):null},getMultipleElementsFromSelector(t){const e=ye(t);return e?we.find(e):[]}},Ee=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;fe.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),Wt(this))return;const s=we.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},Ae=".bs.alert",Te=`close${Ae}`,Ce=`closed${Ae}`;class Oe extends ve{static get NAME(){return"alert"}close(){if(fe.trigger(this._element,Te).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),fe.trigger(this._element,Ce),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Oe.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}Ee(Oe,"close"),Qt(Oe);const xe='[data-bs-toggle="button"]';class ke extends ve{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=ke.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}fe.on(document,"click.bs.button.data-api",xe,(t=>{t.preventDefault();const e=t.target.closest(xe);ke.getOrCreateInstance(e).toggle()})),Qt(ke);const Le=".bs.swipe",Se=`touchstart${Le}`,De=`touchmove${Le}`,$e=`touchend${Le}`,Ie=`pointerdown${Le}`,Ne=`pointerup${Le}`,Pe={endCallback:null,leftCallback:null,rightCallback:null},Me={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class je extends be{constructor(t,e){super(),this._element=t,t&&je.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Pe}static get DefaultType(){return Me}static get NAME(){return"swipe"}dispose(){fe.off(this._element,Le)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),Xt(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&Xt(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(fe.on(this._element,Ie,(t=>this._start(t))),fe.on(this._element,Ne,(t=>this._end(t))),this._element.classList.add("pointer-event")):(fe.on(this._element,Se,(t=>this._start(t))),fe.on(this._element,De,(t=>this._move(t))),fe.on(this._element,$e,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Fe=".bs.carousel",He=".data-api",Be="next",We="prev",ze="left",Re="right",qe=`slide${Fe}`,Ve=`slid${Fe}`,Ye=`keydown${Fe}`,Ke=`mouseenter${Fe}`,Qe=`mouseleave${Fe}`,Xe=`dragstart${Fe}`,Ue=`load${Fe}${He}`,Ge=`click${Fe}${He}`,Je="carousel",Ze="active",ti=".active",ei=".carousel-item",ii=ti+ei,ni={ArrowLeft:Re,ArrowRight:ze},si={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},oi={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ri extends ve{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=we.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===Je&&this.cycle()}static get Default(){return si}static get DefaultType(){return oi}static get NAME(){return"carousel"}next(){this._slide(Be)}nextWhenVisible(){!document.hidden&&Bt(this._element)&&this.next()}prev(){this._slide(We)}pause(){this._isSliding&&jt(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?fe.one(this._element,Ve,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void fe.one(this._element,Ve,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?Be:We;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&fe.on(this._element,Ye,(t=>this._keydown(t))),"hover"===this._config.pause&&(fe.on(this._element,Ke,(()=>this.pause())),fe.on(this._element,Qe,(()=>this._maybeEnableCycle()))),this._config.touch&&je.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of we.find(".carousel-item img",this._element))fe.on(t,Xe,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ze)),rightCallback:()=>this._slide(this._directionToOrder(Re)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new je(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=ni[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=we.findOne(ti,this._indicatorsElement);e.classList.remove(Ze),e.removeAttribute("aria-current");const i=we.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(Ze),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===Be,s=e||Gt(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>fe.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(qe).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),qt(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(Ze),i.classList.remove(Ze,c,l),this._isSliding=!1,r(Ve)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return we.findOne(ii,this._element)}_getItems(){return we.find(ei,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return Kt()?t===ze?We:Be:t===ze?Be:We}_orderToDirection(t){return Kt()?t===We?ze:Re:t===We?Re:ze}static jQueryInterface(t){return this.each((function(){const e=ri.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}fe.on(document,Ge,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=we.getElementFromSelector(this);if(!e||!e.classList.contains(Je))return;t.preventDefault();const i=ri.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===_e.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),fe.on(window,Ue,(()=>{const t=we.find('[data-bs-ride="carousel"]');for(const e of t)ri.getOrCreateInstance(e)})),Qt(ri);const ai=".bs.collapse",li=`show${ai}`,ci=`shown${ai}`,hi=`hide${ai}`,di=`hidden${ai}`,ui=`click${ai}.data-api`,fi="show",pi="collapse",mi="collapsing",gi=`:scope .${pi} .${pi}`,_i='[data-bs-toggle="collapse"]',bi={parent:null,toggle:!0},vi={parent:"(null|element)",toggle:"boolean"};class yi extends ve{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=we.find(_i);for(const t of i){const e=we.getSelectorFromElement(t),i=we.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return bi}static get DefaultType(){return vi}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>yi.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(fe.trigger(this._element,li).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(pi),this._element.classList.add(mi),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(mi),this._element.classList.add(pi,fi),this._element.style[e]="",fe.trigger(this._element,ci)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(fe.trigger(this._element,hi).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,qt(this._element),this._element.classList.add(mi),this._element.classList.remove(pi,fi);for(const t of this._triggerArray){const e=we.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(mi),this._element.classList.add(pi),fe.trigger(this._element,di)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(fi)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=Ht(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(_i);for(const e of t){const t=we.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=we.find(gi,this._config.parent);return we.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=yi.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}fe.on(document,ui,_i,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of we.getMultipleElementsFromSelector(this))yi.getOrCreateInstance(t,{toggle:!1}).toggle()})),Qt(yi);const wi="dropdown",Ei=".bs.dropdown",Ai=".data-api",Ti="ArrowUp",Ci="ArrowDown",Oi=`hide${Ei}`,xi=`hidden${Ei}`,ki=`show${Ei}`,Li=`shown${Ei}`,Si=`click${Ei}${Ai}`,Di=`keydown${Ei}${Ai}`,$i=`keyup${Ei}${Ai}`,Ii="show",Ni='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Pi=`${Ni}.${Ii}`,Mi=".dropdown-menu",ji=Kt()?"top-end":"top-start",Fi=Kt()?"top-start":"top-end",Hi=Kt()?"bottom-end":"bottom-start",Bi=Kt()?"bottom-start":"bottom-end",Wi=Kt()?"left-start":"right-start",zi=Kt()?"right-start":"left-start",Ri={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},qi={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Vi extends ve{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=we.next(this._element,Mi)[0]||we.prev(this._element,Mi)[0]||we.findOne(Mi,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Ri}static get DefaultType(){return qi}static get NAME(){return wi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Wt(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!fe.trigger(this._element,ki,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))fe.on(t,"mouseover",Rt);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Ii),this._element.classList.add(Ii),fe.trigger(this._element,Li,t)}}hide(){if(Wt(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!fe.trigger(this._element,Oi,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.off(t,"mouseover",Rt);this._popper&&this._popper.destroy(),this._menu.classList.remove(Ii),this._element.classList.remove(Ii),this._element.setAttribute("aria-expanded","false"),_e.removeDataAttribute(this._menu,"popper"),fe.trigger(this._element,xi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!Ft(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${wi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===e)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:Ft(this._config.reference)?t=Ht(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const i=this._getPopperConfig();this._popper=Dt(t,this._menu,i)}_isShown(){return this._menu.classList.contains(Ii)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Wi;if(t.classList.contains("dropstart"))return zi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?Fi:ji:e?Bi:Hi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(_e.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...Xt(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=we.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>Bt(t)));i.length&&Gt(i,e,t===Ci,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Vi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=we.find(Pi);for(const i of e){const e=Vi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ti,Ci].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ni)?this:we.prev(this,Ni)[0]||we.next(this,Ni)[0]||we.findOne(Ni,t.delegateTarget.parentNode),o=Vi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}fe.on(document,Di,Ni,Vi.dataApiKeydownHandler),fe.on(document,Di,Mi,Vi.dataApiKeydownHandler),fe.on(document,Si,Vi.clearMenus),fe.on(document,$i,Vi.clearMenus),fe.on(document,Si,Ni,(function(t){t.preventDefault(),Vi.getOrCreateInstance(this).toggle()})),Qt(Vi);const Yi="backdrop",Ki="show",Qi=`mousedown.bs.${Yi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Ui={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Gi extends be{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Ui}static get NAME(){return Yi}show(t){if(!this._config.isVisible)return void Xt(t);this._append();const e=this._getElement();this._config.isAnimated&&qt(e),e.classList.add(Ki),this._emulateAnimation((()=>{Xt(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),Xt(t)}))):Xt(t)}dispose(){this._isAppended&&(fe.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=Ht(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),fe.on(t,Qi,(()=>{Xt(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){Ut(t,this._getElement(),this._config.isAnimated)}}const Ji=".bs.focustrap",Zi=`focusin${Ji}`,tn=`keydown.tab${Ji}`,en="backward",nn={autofocus:!0,trapElement:null},sn={autofocus:"boolean",trapElement:"element"};class on extends be{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return nn}static get DefaultType(){return sn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),fe.off(document,Ji),fe.on(document,Zi,(t=>this._handleFocusin(t))),fe.on(document,tn,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,fe.off(document,Ji))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=we.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===en?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?en:"forward")}}const rn=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",an=".sticky-top",ln="padding-right",cn="margin-right";class hn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,ln,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,ln),this._resetElementAttributes(rn,ln),this._resetElementAttributes(an,cn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&_e.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=_e.getDataAttribute(t,e);null!==i?(_e.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(Ft(t))e(t);else for(const i of we.find(t,this._element))e(i)}}const dn=".bs.modal",un=`hide${dn}`,fn=`hidePrevented${dn}`,pn=`hidden${dn}`,mn=`show${dn}`,gn=`shown${dn}`,_n=`resize${dn}`,bn=`click.dismiss${dn}`,vn=`mousedown.dismiss${dn}`,yn=`keydown.dismiss${dn}`,wn=`click${dn}.data-api`,En="modal-open",An="show",Tn="modal-static",Cn={backdrop:!0,focus:!0,keyboard:!0},On={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class xn extends ve{constructor(t,e){super(t,e),this._dialog=we.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new hn,this._addEventListeners()}static get Default(){return Cn}static get DefaultType(){return On}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||fe.trigger(this._element,mn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(fe.trigger(this._element,un).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){fe.off(window,dn),fe.off(this._dialog,dn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Gi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new on({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=we.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),qt(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,fe.trigger(this._element,gn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){fe.on(this._element,yn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),fe.on(window,_n,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),fe.on(this._element,vn,(t=>{fe.one(this._element,bn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),fe.trigger(this._element,pn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(fe.trigger(this._element,fn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Tn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Tn),this._queueCallback((()=>{this._element.classList.remove(Tn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=Kt()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=Kt()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=xn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}fe.on(document,wn,'[data-bs-toggle="modal"]',(function(t){const e=we.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),fe.one(e,mn,(t=>{t.defaultPrevented||fe.one(e,pn,(()=>{Bt(this)&&this.focus()}))}));const i=we.findOne(".modal.show");i&&xn.getInstance(i).hide(),xn.getOrCreateInstance(e).toggle(this)})),Ee(xn),Qt(xn);const kn=".bs.offcanvas",Ln=".data-api",Sn=`load${kn}${Ln}`,Dn="show",$n="showing",In="hiding",Nn=".offcanvas.show",Pn=`show${kn}`,Mn=`shown${kn}`,jn=`hide${kn}`,Fn=`hidePrevented${kn}`,Hn=`hidden${kn}`,Bn=`resize${kn}`,Wn=`click${kn}${Ln}`,zn=`keydown.dismiss${kn}`,Rn={backdrop:!0,keyboard:!0,scroll:!1},qn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Vn extends ve{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Rn}static get DefaultType(){return qn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||fe.trigger(this._element,Pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new hn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($n),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Dn),this._element.classList.remove($n),fe.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(fe.trigger(this._element,jn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(In),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Dn,In),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new hn).reset(),fe.trigger(this._element,Hn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Gi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():fe.trigger(this._element,Fn)}:null})}_initializeFocusTrap(){return new on({trapElement:this._element})}_addEventListeners(){fe.on(this._element,zn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():fe.trigger(this._element,Fn))}))}static jQueryInterface(t){return this.each((function(){const e=Vn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}fe.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=we.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),Wt(this))return;fe.one(e,Hn,(()=>{Bt(this)&&this.focus()}));const i=we.findOne(Nn);i&&i!==e&&Vn.getInstance(i).hide(),Vn.getOrCreateInstance(e).toggle(this)})),fe.on(window,Sn,(()=>{for(const t of we.find(Nn))Vn.getOrCreateInstance(t).show()})),fe.on(window,Bn,(()=>{for(const t of we.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Vn.getOrCreateInstance(t).hide()})),Ee(Vn),Qt(Vn);const Yn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Un={allowList:Yn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Gn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Jn={entry:"(string|element|function|null)",selector:"(string|element)"};class Zn extends be{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Un}static get DefaultType(){return Gn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Jn)}_setContent(t,e,i){const n=we.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?Ft(e)?this._putElementInTemplate(Ht(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return Xt(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const ts=new Set(["sanitize","allowList","sanitizeFn"]),es="fade",is="show",ns=".modal",ss="hide.bs.modal",os="hover",rs="focus",as={AUTO:"auto",TOP:"top",RIGHT:Kt()?"left":"right",BOTTOM:"bottom",LEFT:Kt()?"right":"left"},ls={allowList:Yn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},cs={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class hs extends ve{constructor(t,i){if(void 0===e)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,i),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return ls}static get DefaultType(){return cs}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),fe.off(this._element.closest(ns),ss,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=fe.trigger(this._element,this.constructor.eventName("show")),e=(zt(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),fe.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(is),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.on(t,"mouseover",Rt);this._queueCallback((()=>{fe.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!fe.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(is),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))fe.off(t,"mouseover",Rt);this._activeTrigger.click=!1,this._activeTrigger[rs]=!1,this._activeTrigger[os]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),fe.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(es,is),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(es),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Zn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(es)}_isShown(){return this.tip&&this.tip.classList.contains(is)}_createPopper(t){const e=Xt(this._config.placement,[this,t,this._element]),i=as[e.toUpperCase()];return Dt(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return Xt(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...Xt(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)fe.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===os?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===os?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");fe.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?rs:os]=!0,e._enter()})),fe.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?rs:os]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},fe.on(this._element.closest(ns),ss,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=_e.getDataAttributes(this._element);for(const t of Object.keys(e))ts.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:Ht(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=hs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(hs);const ds={...hs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},us={...hs.DefaultType,content:"(null|string|element|function)"};class fs extends hs{static get Default(){return ds}static get DefaultType(){return us}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=fs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(fs);const ps=".bs.scrollspy",ms=`activate${ps}`,gs=`click${ps}`,_s=`load${ps}.data-api`,bs="active",vs="[href]",ys=".nav-link",ws=`${ys}, .nav-item > ${ys}, .list-group-item`,Es={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Ts extends ve{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Es}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=Ht(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(fe.off(this._config.target,gs),fe.on(this._config.target,gs,vs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=we.find(vs,this._config.target);for(const e of t){if(!e.hash||Wt(e))continue;const t=we.findOne(decodeURI(e.hash),this._element);Bt(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(bs),this._activateParents(t),fe.trigger(this._element,ms,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))we.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(bs);else for(const e of we.parents(t,".nav, .list-group"))for(const t of we.prev(e,ws))t.classList.add(bs)}_clearActiveClass(t){t.classList.remove(bs);const e=we.find(`${vs}.${bs}`,t);for(const t of e)t.classList.remove(bs)}static jQueryInterface(t){return this.each((function(){const e=Ts.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}fe.on(window,_s,(()=>{for(const t of we.find('[data-bs-spy="scroll"]'))Ts.getOrCreateInstance(t)})),Qt(Ts);const Cs=".bs.tab",Os=`hide${Cs}`,xs=`hidden${Cs}`,ks=`show${Cs}`,Ls=`shown${Cs}`,Ss=`click${Cs}`,Ds=`keydown${Cs}`,$s=`load${Cs}`,Is="ArrowLeft",Ns="ArrowRight",Ps="ArrowUp",Ms="ArrowDown",js="Home",Fs="End",Hs="active",Bs="fade",Ws="show",zs=".dropdown-toggle",Rs=`:not(${zs})`,qs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Vs=`.nav-link${Rs}, .list-group-item${Rs}, [role="tab"]${Rs}, ${qs}`,Ys=`.${Hs}[data-bs-toggle="tab"], .${Hs}[data-bs-toggle="pill"], .${Hs}[data-bs-toggle="list"]`;class Ks extends ve{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),fe.on(this._element,Ds,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?fe.trigger(e,Os,{relatedTarget:t}):null;fe.trigger(t,ks,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Hs),this._activate(we.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),fe.trigger(t,Ls,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Bs)))}_deactivate(t,e){t&&(t.classList.remove(Hs),t.blur(),this._deactivate(we.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),fe.trigger(t,xs,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Bs)))}_keydown(t){if(![Is,Ns,Ps,Ms,js,Fs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!Wt(t)));let i;if([js,Fs].includes(t.key))i=e[t.key===js?0:e.length-1];else{const n=[Ns,Ms].includes(t.key);i=Gt(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Ks.getOrCreateInstance(i).show())}_getChildren(){return we.find(Vs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=we.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=we.findOne(t,i);s&&s.classList.toggle(n,e)};n(zs,Hs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Hs)}_getInnerElement(t){return t.matches(Vs)?t:we.findOne(Vs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Ks.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}fe.on(document,Ss,qs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),Wt(this)||Ks.getOrCreateInstance(this).show()})),fe.on(window,$s,(()=>{for(const t of we.find(Ys))Ks.getOrCreateInstance(t)})),Qt(Ks);const Qs=".bs.toast",Xs=`mouseover${Qs}`,Us=`mouseout${Qs}`,Gs=`focusin${Qs}`,Js=`focusout${Qs}`,Zs=`hide${Qs}`,to=`hidden${Qs}`,eo=`show${Qs}`,io=`shown${Qs}`,no="hide",so="show",oo="showing",ro={animation:"boolean",autohide:"boolean",delay:"number"},ao={animation:!0,autohide:!0,delay:5e3};class lo extends ve{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return ao}static get DefaultType(){return ro}static get NAME(){return"toast"}show(){fe.trigger(this._element,eo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(no),qt(this._element),this._element.classList.add(so,oo),this._queueCallback((()=>{this._element.classList.remove(oo),fe.trigger(this._element,io),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(fe.trigger(this._element,Zs).defaultPrevented||(this._element.classList.add(oo),this._queueCallback((()=>{this._element.classList.add(no),this._element.classList.remove(oo,so),fe.trigger(this._element,to)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(so),super.dispose()}isShown(){return this._element.classList.contains(so)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){fe.on(this._element,Xs,(t=>this._onInteraction(t,!0))),fe.on(this._element,Us,(t=>this._onInteraction(t,!1))),fe.on(this._element,Gs,(t=>this._onInteraction(t,!0))),fe.on(this._element,Js,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=lo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}function co(t){"loading"!=document.readyState?t():document.addEventListener("DOMContentLoaded",t)}Ee(lo),Qt(lo),co((function(){[].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')).map((function(t){return new hs(t,{delay:{show:500,hide:100}})}))})),co((function(){document.getElementById("pst-back-to-top").addEventListener("click",(function(){document.body.scrollTop=0,document.documentElement.scrollTop=0}))})),co((function(){var t=document.getElementById("pst-back-to-top"),e=document.getElementsByClassName("bd-header")[0].getBoundingClientRect();window.addEventListener("scroll",(function(){this.oldScroll>this.scrollY&&this.scrollY>e.bottom?t.style.display="block":t.style.display="none",this.oldScroll=this.scrollY}))})),window.bootstrap=i})(); +//# sourceMappingURL=bootstrap.js.map \ No newline at end of file diff --git a/_static/scripts/bootstrap.js.LICENSE.txt b/_static/scripts/bootstrap.js.LICENSE.txt new file mode 100644 index 000000000..10f979d07 --- /dev/null +++ b/_static/scripts/bootstrap.js.LICENSE.txt @@ -0,0 +1,5 @@ +/*! + * Bootstrap v5.3.2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ diff --git a/_static/scripts/bootstrap.js.map b/_static/scripts/bootstrap.js.map new file mode 100644 index 000000000..64e212b1e --- /dev/null +++ b/_static/scripts/bootstrap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/bootstrap.js","mappings":"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","sources":["webpack://pydata_sphinx_theme/webpack/bootstrap","webpack://pydata_sphinx_theme/webpack/runtime/define property getters","webpack://pydata_sphinx_theme/webpack/runtime/hasOwnProperty shorthand","webpack://pydata_sphinx_theme/webpack/runtime/make namespace object","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/enums.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/applyStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getBasePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/math.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/userAgent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/contains.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/within.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/expandToHashMap.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/arrow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getVariation.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/computeStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/eventListeners.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/rectToClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/detectOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/flip.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/hide.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/offset.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getAltAxis.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/orderModifiers.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/createPopper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/debounce.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergeByName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper-lite.js","webpack://pydata_sphinx_theme/./node_modules/bootstrap/dist/js/bootstrap.esm.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/mixin.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/bootstrap.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n var x = _ref.x,\n y = _ref.y;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }, getWindow(popper)) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n });\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref) {\n var name = _ref.name,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n effect = _ref.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","/*!\n * Bootstrap v5.3.2 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nimport * as Popper from '@popperjs/core';\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map();\nconst Data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n const instanceMap = elementMap.get(element);\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n instanceMap.set(key, instance);\n },\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n return null;\n },\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key);\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend';\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`);\n }\n return selector;\n};\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n return prefix;\n};\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n }\n\n // Get transition-duration of the element\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay);\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n};\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n return typeof object.nodeType !== 'undefined';\n};\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object));\n }\n return null;\n};\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])');\n if (!closedDetails) {\n return elementIsVisible;\n }\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n if (summary === null) {\n return false;\n }\n }\n return elementIsVisible;\n};\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n if (element.classList.contains('disabled')) {\n return true;\n }\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null;\n }\n return findShadowRoot(element.parentNode);\n};\nconst noop = () => {};\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n};\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n return null;\n};\nconst DOMContentLoadedCallbacks = [];\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n};\nconst isRTL = () => document.documentElement.dir === 'rtl';\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n};\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;\n};\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n};\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length;\n let index = list.indexOf(activeElement);\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n index += shouldGetNext ? 1 : -1;\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\nlet uidEvent = 1;\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n};\nconst nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\nfunction getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n}\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n return fn.apply(element, [event]);\n };\n}\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n hydrateObj(event, {\n delegateTarget: target\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n return fn.apply(target, [event]);\n }\n }\n };\n}\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n}\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string';\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n return [isDelegated, callable, typeEvent];\n}\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.call(this, event);\n }\n };\n };\n callable = wrapFunction(callable);\n }\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n}\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n if (!fn) {\n return;\n }\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n}\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n}\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n}\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n const $ = getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n const evt = hydrateObj(new Event(event, {\n bubbles,\n cancelable: true\n }), args);\n if (defaultPrevented) {\n evt.preventDefault();\n }\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n return evt;\n }\n};\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value;\n }\n });\n }\n }\n return obj;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n if (value === Number(value).toString()) {\n return Number(value);\n }\n if (value === '' || value === 'null') {\n return null;\n }\n if (typeof value !== 'string') {\n return value;\n }\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n}\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n return attributes;\n },\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {};\n }\n static get DefaultType() {\n return {};\n }\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n return config;\n }\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property];\n const valueType = isElement(value) ? 'element' : toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.2';\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = getElement(element);\n if (!element) {\n return;\n }\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated);\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY);\n }\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n static get VERSION() {\n return VERSION;\n }\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href');\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n selector = hrefAttribute && hrefAttribute !== '#' ? parseSelector(hrefAttribute.trim()) : null;\n }\n return selector;\n};\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n return parents;\n },\n prev(element, selector) {\n let previous = element.previousElementSibling;\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n previous = previous.previousElementSibling;\n }\n return [];\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n next = next.nextElementSibling;\n }\n return [];\n },\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n },\n getSelectorFromElement(element) {\n const selector = getSelector(element);\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null;\n }\n return null;\n },\n getElementFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.findOne(selector) : null;\n },\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.find(selector) : [];\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n const name = component.NAME;\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);\n const instance = component.getOrCreateInstance(target);\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]();\n });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$f = 'alert';\nconst DATA_KEY$a = 'bs.alert';\nconst EVENT_KEY$b = `.${DATA_KEY$a}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$b}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$b}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$f;\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n if (closeEvent.defaultPrevented) {\n return;\n }\n this._element.classList.remove(CLASS_NAME_SHOW$8);\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n }\n\n // Private\n _destroyElement() {\n this._element.remove();\n EventHandler.trigger(this._element, EVENT_CLOSED);\n this.dispose();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close');\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$e = 'button';\nconst DATA_KEY$9 = 'bs.button';\nconst EVENT_KEY$a = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$e;\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this);\n if (config === 'toggle') {\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n event.preventDefault();\n const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n const data = Button.getOrCreateInstance(button);\n data.toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$d = 'swipe';\nconst EVENT_KEY$9 = '.bs.swipe';\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SWIPE_THRESHOLD = 40;\nconst Default$c = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n};\nconst DefaultType$c = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n};\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super();\n this._element = element;\n if (!element || !Swipe.isSupported()) {\n return;\n }\n this._config = this._getConfig(config);\n this._deltaX = 0;\n this._supportPointerEvents = Boolean(window.PointerEvent);\n this._initEvents();\n }\n\n // Getters\n static get Default() {\n return Default$c;\n }\n static get DefaultType() {\n return DefaultType$c;\n }\n static get NAME() {\n return NAME$d;\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY$9);\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX;\n return;\n }\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX;\n }\n }\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX;\n }\n this._handleSwipe();\n execute(this._config.endCallback);\n }\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;\n }\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX);\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return;\n }\n const direction = absDeltaX / this._deltaX;\n this._deltaX = 0;\n if (!direction) {\n return;\n }\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);\n }\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));\n this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));\n }\n }\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$c = 'carousel';\nconst DATA_KEY$8 = 'bs.carousel';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst ARROW_LEFT_KEY$1 = 'ArrowLeft';\nconst ARROW_RIGHT_KEY$1 = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst EVENT_SLIDE = `slide${EVENT_KEY$8}`;\nconst EVENT_SLID = `slid${EVENT_KEY$8}`;\nconst EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;\nconst EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;\nconst EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;\nconst EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT\n};\nconst Default$b = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n};\nconst DefaultType$b = {\n interval: '(number|boolean)',\n // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._interval = null;\n this._activeElement = null;\n this._isSliding = false;\n this.touchTimeout = null;\n this._swipeHelper = null;\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n this._addEventListeners();\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$b;\n }\n static get DefaultType() {\n return DefaultType$b;\n }\n static get NAME() {\n return NAME$c;\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT);\n }\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next();\n }\n }\n prev() {\n this._slide(ORDER_PREV);\n }\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element);\n }\n this._clearInterval();\n }\n cycle() {\n this._clearInterval();\n this._updateInterval();\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);\n }\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle());\n return;\n }\n this.cycle();\n }\n to(index) {\n const items = this._getItems();\n if (index > items.length - 1 || index < 0) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n return;\n }\n const activeIndex = this._getItemIndex(this._getActive());\n if (activeIndex === index) {\n return;\n }\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n this._slide(order, items[index]);\n }\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose();\n }\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval;\n return config;\n }\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));\n }\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());\n EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());\n }\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners();\n }\n }\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());\n }\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return;\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause();\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout);\n }\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n };\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n };\n this._swipeHelper = new Swipe(this._element, swipeConfig);\n }\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n const direction = KEY_TO_DIRECTION[event.key];\n if (direction) {\n event.preventDefault();\n this._slide(this._directionToOrder(direction));\n }\n }\n _getItemIndex(element) {\n return this._getItems().indexOf(element);\n }\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return;\n }\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n activeIndicator.removeAttribute('aria-current');\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement);\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);\n newActiveIndicator.setAttribute('aria-current', 'true');\n }\n }\n _updateInterval() {\n const element = this._activeElement || this._getActive();\n if (!element) {\n return;\n }\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n this._config.interval = elementInterval || this._config.defaultInterval;\n }\n _slide(order, element = null) {\n if (this._isSliding) {\n return;\n }\n const activeElement = this._getActive();\n const isNext = order === ORDER_NEXT;\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);\n if (nextElement === activeElement) {\n return;\n }\n const nextElementIndex = this._getItemIndex(nextElement);\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n });\n };\n const slideEvent = triggerEvent(EVENT_SLIDE);\n if (slideEvent.defaultPrevented) {\n return;\n }\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // TODO: change tests that use empty divs to avoid this check\n return;\n }\n const isCycling = Boolean(this._interval);\n this.pause();\n this._isSliding = true;\n this._setActiveIndicatorElement(nextElementIndex);\n this._activeElement = nextElement;\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n nextElement.classList.add(orderClassName);\n reflow(nextElement);\n activeElement.classList.add(directionalClassName);\n nextElement.classList.add(directionalClassName);\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName);\n nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n this._isSliding = false;\n triggerEvent(EVENT_SLID);\n };\n this._queueCallback(completeCallBack, activeElement, this._isAnimated());\n if (isCycling) {\n this.cycle();\n }\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE);\n }\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n }\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element);\n }\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n }\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n }\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n }\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config);\n if (typeof config === 'number') {\n data.to(config);\n return;\n }\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return;\n }\n event.preventDefault();\n const carousel = Carousel.getOrCreateInstance(target);\n const slideIndex = this.getAttribute('data-bs-slide-to');\n if (slideIndex) {\n carousel.to(slideIndex);\n carousel._maybeEnableCycle();\n return;\n }\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next();\n carousel._maybeEnableCycle();\n return;\n }\n carousel.prev();\n carousel._maybeEnableCycle();\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel);\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$b = 'collapse';\nconst DATA_KEY$7 = 'bs.collapse';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst EVENT_SHOW$6 = `show${EVENT_KEY$7}`;\nconst EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;\nconst EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;\nconst EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\nconst Default$a = {\n parent: null,\n toggle: true\n};\nconst DefaultType$a = {\n parent: '(null|element)',\n toggle: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n this._initializeChildren();\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n if (this._config.toggle) {\n this.toggle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$a;\n }\n static get DefaultType() {\n return DefaultType$a;\n }\n static get NAME() {\n return NAME$b;\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n let activeChildren = [];\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n const dimension = this._getDimension();\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.style[dimension] = 0;\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN$6);\n };\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n this._queueCallback(complete, this._element, true);\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n const dimension = this._getDimension();\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger);\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n EventHandler.trigger(this._element, EVENT_HIDDEN$6);\n };\n this._element.style[dimension] = '';\n this._queueCallback(complete, this._element, true);\n }\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW$7);\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n config.parent = getElement(config.parent);\n return config;\n }\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element);\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {};\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$a = 'dropdown';\nconst DATA_KEY$6 = 'bs.dropdown';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY$1 = 'ArrowUp';\nconst ARROW_DOWN_KEY$1 = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$5 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center';\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)';\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR = '.navbar';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst PLACEMENT_TOPCENTER = 'top';\nconst PLACEMENT_BOTTOMCENTER = 'bottom';\nconst Default$9 = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n};\nconst DefaultType$9 = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n};\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._popper = null;\n this._parent = this._element.parentNode; // dropdown wrapper\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);\n this._inNavbar = this._detectNavbar();\n }\n\n // Getters\n static get Default() {\n return Default$9;\n }\n static get DefaultType() {\n return DefaultType$9;\n }\n static get NAME() {\n return NAME$a;\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show();\n }\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);\n if (showEvent.defaultPrevented) {\n return;\n }\n this._createPopper();\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n this._element.focus();\n this._element.setAttribute('aria-expanded', true);\n this._menu.classList.add(CLASS_NAME_SHOW$6);\n this._element.classList.add(CLASS_NAME_SHOW$6);\n EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);\n }\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n this._completeHide(relatedTarget);\n }\n dispose() {\n if (this._popper) {\n this._popper.destroy();\n }\n super.dispose();\n }\n update() {\n this._inNavbar = this._detectNavbar();\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n if (this._popper) {\n this._popper.destroy();\n }\n this._menu.classList.remove(CLASS_NAME_SHOW$6);\n this._element.classList.remove(CLASS_NAME_SHOW$6);\n this._element.setAttribute('aria-expanded', 'false');\n Manipulator.removeDataAttribute(this._menu, 'popper');\n EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);\n }\n _getConfig(config) {\n config = super._getConfig(config);\n if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME$a.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n }\n return config;\n }\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n }\n let referenceElement = this._element;\n if (this._config.reference === 'parent') {\n referenceElement = this._parent;\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference);\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference;\n }\n const popperConfig = this._getPopperConfig();\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);\n }\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW$6);\n }\n _getPlacement() {\n const parentDropdown = this._parent;\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER;\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n }\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n }\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null;\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n };\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }];\n }\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _selectMenuItem({\n key,\n target\n }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));\n if (!items.length) {\n return;\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {\n return;\n }\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle);\n if (!context || context._config.autoClose === false) {\n continue;\n }\n const composedPath = event.composedPath();\n const isMenuTarget = composedPath.includes(context._menu);\n if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n continue;\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue;\n }\n const relatedTarget = {\n relatedTarget: context._element\n };\n if (event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n context._completeHide(relatedTarget);\n }\n }\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName);\n const isEscapeEvent = event.key === ESCAPE_KEY$2;\n const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return;\n }\n if (isInput && !isEscapeEvent) {\n return;\n }\n event.preventDefault();\n\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);\n const instance = Dropdown.getOrCreateInstance(getToggleButton);\n if (isUpOrDownEvent) {\n event.stopPropagation();\n instance.show();\n instance._selectMenuItem(event);\n return;\n }\n if (instance._isShown()) {\n // else is escape and we check if it is shown\n event.stopPropagation();\n instance.hide();\n getToggleButton.focus();\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n event.preventDefault();\n Dropdown.getOrCreateInstance(this).toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$9 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;\nconst Default$8 = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true,\n // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n};\n\nconst DefaultType$8 = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n};\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isAppended = false;\n this._element = null;\n }\n\n // Getters\n static get Default() {\n return Default$8;\n }\n static get DefaultType() {\n return DefaultType$8;\n }\n static get NAME() {\n return NAME$9;\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._append();\n const element = this._getElement();\n if (this._config.isAnimated) {\n reflow(element);\n }\n element.classList.add(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n execute(callback);\n });\n }\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n this.dispose();\n execute(callback);\n });\n }\n dispose() {\n if (!this._isAppended) {\n return;\n }\n EventHandler.off(this._element, EVENT_MOUSEDOWN);\n this._element.remove();\n this._isAppended = false;\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div');\n backdrop.className = this._config.className;\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE$4);\n }\n this._element = backdrop;\n }\n return this._element;\n }\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement);\n return config;\n }\n _append() {\n if (this._isAppended) {\n return;\n }\n const element = this._getElement();\n this._config.rootElement.append(element);\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback);\n });\n this._isAppended = true;\n }\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$8 = 'focustrap';\nconst DATA_KEY$5 = 'bs.focustrap';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\nconst Default$7 = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n};\n\nconst DefaultType$7 = {\n autofocus: 'boolean',\n trapElement: 'element'\n};\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isActive = false;\n this._lastTabNavDirection = null;\n }\n\n // Getters\n static get Default() {\n return Default$7;\n }\n static get DefaultType() {\n return DefaultType$7;\n }\n static get NAME() {\n return NAME$8;\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return;\n }\n if (this._config.autofocus) {\n this._config.trapElement.focus();\n }\n EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n this._isActive = true;\n }\n deactivate() {\n if (!this._isActive) {\n return;\n }\n this._isActive = false;\n EventHandler.off(document, EVENT_KEY$5);\n }\n\n // Private\n _handleFocusin(event) {\n const {\n trapElement\n } = this._config;\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return;\n }\n const elements = SelectorEngine.focusableChildren(trapElement);\n if (elements.length === 0) {\n trapElement.focus();\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus();\n } else {\n elements[0].focus();\n }\n }\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return;\n }\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\nconst PROPERTY_PADDING = 'padding-right';\nconst PROPERTY_MARGIN = 'margin-right';\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body;\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth;\n return Math.abs(window.innerWidth - documentWidth);\n }\n hide() {\n const width = this.getWidth();\n this._disableOverFlow();\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);\n }\n reset() {\n this._resetElementAttributes(this._element, 'overflow');\n this._resetElementAttributes(this._element, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);\n }\n isOverflowing() {\n return this.getWidth() > 0;\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow');\n this._element.style.overflow = 'hidden';\n }\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth();\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return;\n }\n this._saveInitialAttribute(element, styleProperty);\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty);\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue);\n }\n }\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty);\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty);\n return;\n }\n Manipulator.removeDataAttribute(element, styleProperty);\n element.style.setProperty(styleProperty, value);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector);\n return;\n }\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel);\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$7 = 'modal';\nconst DATA_KEY$4 = 'bs.modal';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;\nconst EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$4}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;\nconst EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst OPEN_SELECTOR$1 = '.modal.show';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\nconst Default$6 = {\n backdrop: true,\n focus: true,\n keyboard: true\n};\nconst DefaultType$6 = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._isShown = false;\n this._isTransitioning = false;\n this._scrollBar = new ScrollBarHelper();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$6;\n }\n static get DefaultType() {\n return DefaultType$6;\n }\n static get NAME() {\n return NAME$7;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._isTransitioning = true;\n this._scrollBar.hide();\n document.body.classList.add(CLASS_NAME_OPEN);\n this._adjustDialog();\n this._backdrop.show(() => this._showElement(relatedTarget));\n }\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._isShown = false;\n this._isTransitioning = true;\n this._focustrap.deactivate();\n this._element.classList.remove(CLASS_NAME_SHOW$4);\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());\n }\n dispose() {\n EventHandler.off(window, EVENT_KEY$4);\n EventHandler.off(this._dialog, EVENT_KEY$4);\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n handleUpdate() {\n this._adjustDialog();\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop),\n // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element);\n }\n this._element.style.display = 'block';\n this._element.removeAttribute('aria-hidden');\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.scrollTop = 0;\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n if (modalBody) {\n modalBody.scrollTop = 0;\n }\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_SHOW$4);\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate();\n }\n this._isTransitioning = false;\n EventHandler.trigger(this._element, EVENT_SHOWN$4, {\n relatedTarget\n });\n };\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated());\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n if (event.key !== ESCAPE_KEY$1) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n this._triggerBackdropTransition();\n });\n EventHandler.on(window, EVENT_RESIZE$1, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog();\n }\n });\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return;\n }\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition();\n return;\n }\n if (this._config.backdrop) {\n this.hide();\n }\n });\n });\n }\n _hideModal() {\n this._element.style.display = 'none';\n this._element.setAttribute('aria-hidden', true);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n this._isTransitioning = false;\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN);\n this._resetAdjustments();\n this._scrollBar.reset();\n EventHandler.trigger(this._element, EVENT_HIDDEN$4);\n });\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE$3);\n }\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);\n if (hideEvent.defaultPrevented) {\n return;\n }\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const initialOverflowY = this._element.style.overflowY;\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return;\n }\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden';\n }\n this._element.classList.add(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY;\n }, this._dialog);\n }, this._dialog);\n this._element.focus();\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const scrollbarWidth = this._scrollBar.getWidth();\n const isBodyOverflowing = scrollbarWidth > 0;\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n }\n _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](relatedTarget);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n EventHandler.one(target, EVENT_SHOW$4, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$4, () => {\n if (isVisible(this)) {\n this.focus();\n }\n });\n });\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide();\n }\n const data = Modal.getOrCreateInstance(target);\n data.toggle(this);\n});\nenableDismissTrigger(Modal);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$6 = 'offcanvas';\nconst DATA_KEY$3 = 'bs.offcanvas';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst ESCAPE_KEY = 'Escape';\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_SHOWING$1 = 'showing';\nconst CLASS_NAME_HIDING = 'hiding';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$3 = `show${EVENT_KEY$3}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$3}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\nconst Default$5 = {\n backdrop: true,\n keyboard: true,\n scroll: false\n};\nconst DefaultType$5 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isShown = false;\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$5;\n }\n static get DefaultType() {\n return DefaultType$5;\n }\n static get NAME() {\n return NAME$6;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._backdrop.show();\n if (!this._config.scroll) {\n new ScrollBarHelper().hide();\n }\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.classList.add(CLASS_NAME_SHOWING$1);\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate();\n }\n this._element.classList.add(CLASS_NAME_SHOW$3);\n this._element.classList.remove(CLASS_NAME_SHOWING$1);\n EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n relatedTarget\n });\n };\n this._queueCallback(completeCallBack, this._element, true);\n }\n hide() {\n if (!this._isShown) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._focustrap.deactivate();\n this._element.blur();\n this._isShown = false;\n this._element.classList.add(CLASS_NAME_HIDING);\n this._backdrop.hide();\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n if (!this._config.scroll) {\n new ScrollBarHelper().reset();\n }\n EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n };\n this._queueCallback(completeCallback, this._element, true);\n }\n dispose() {\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n this.hide();\n };\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop);\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n });\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$3, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus();\n }\n });\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide();\n }\n const data = Offcanvas.getOrCreateInstance(target);\n data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show();\n }\n});\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide();\n }\n }\n});\nenableDismissTrigger(Offcanvas);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\nconst DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n};\n// js-docs-end allow-list\n\nconst uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\n// eslint-disable-next-line unicorn/better-regex\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase();\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));\n }\n return true;\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml;\n }\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml);\n }\n const domParser = new window.DOMParser();\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase();\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove();\n continue;\n }\n const attributeList = [].concat(...element.attributes);\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName);\n }\n }\n }\n return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$5 = 'TemplateFactory';\nconst Default$4 = {\n allowList: DefaultAllowlist,\n content: {},\n // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n};\nconst DefaultType$4 = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n};\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n};\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n }\n\n // Getters\n static get Default() {\n return Default$4;\n }\n static get DefaultType() {\n return DefaultType$4;\n }\n static get NAME() {\n return NAME$5;\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);\n }\n hasContent() {\n return this.getContent().length > 0;\n }\n changeContent(content) {\n this._checkContent(content);\n this._config.content = {\n ...this._config.content,\n ...content\n };\n return this;\n }\n toHtml() {\n const templateWrapper = document.createElement('div');\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template);\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector);\n }\n const template = templateWrapper.children[0];\n const extraClass = this._resolvePossibleFunction(this._config.extraClass);\n if (extraClass) {\n template.classList.add(...extraClass.split(' '));\n }\n return template;\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config);\n this._checkContent(config.content);\n }\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({\n selector,\n entry: content\n }, DefaultContentType);\n }\n }\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template);\n if (!templateElement) {\n return;\n }\n content = this._resolvePossibleFunction(content);\n if (!content) {\n templateElement.remove();\n return;\n }\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement);\n return;\n }\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content);\n return;\n }\n templateElement.textContent = content;\n }\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this]);\n }\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = '';\n templateElement.append(element);\n return;\n }\n templateElement.textContent = element.textContent;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$4 = 'tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\nconst EVENT_HIDE$2 = 'hide';\nconst EVENT_HIDDEN$2 = 'hidden';\nconst EVENT_SHOW$2 = 'show';\nconst EVENT_SHOWN$2 = 'shown';\nconst EVENT_INSERTED = 'inserted';\nconst EVENT_CLICK$1 = 'click';\nconst EVENT_FOCUSIN$1 = 'focusin';\nconst EVENT_FOCUSOUT$1 = 'focusout';\nconst EVENT_MOUSEENTER = 'mouseenter';\nconst EVENT_MOUSELEAVE = 'mouseleave';\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 6],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' + '
' + '
' + '
',\n title: '',\n trigger: 'hover focus'\n};\nconst DefaultType$3 = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n};\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n }\n super(element, config);\n\n // Private\n this._isEnabled = true;\n this._timeout = 0;\n this._isHovered = null;\n this._activeTrigger = {};\n this._popper = null;\n this._templateFactory = null;\n this._newContent = null;\n\n // Protected\n this.tip = null;\n this._setListeners();\n if (!this._config.selector) {\n this._fixTitle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$3;\n }\n static get DefaultType() {\n return DefaultType$3;\n }\n static get NAME() {\n return NAME$4;\n }\n\n // Public\n enable() {\n this._isEnabled = true;\n }\n disable() {\n this._isEnabled = false;\n }\n toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n }\n toggle() {\n if (!this._isEnabled) {\n return;\n }\n this._activeTrigger.click = !this._activeTrigger.click;\n if (this._isShown()) {\n this._leave();\n return;\n }\n this._enter();\n }\n dispose() {\n clearTimeout(this._timeout);\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));\n }\n this._disposePopper();\n super.dispose();\n }\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements');\n }\n if (!(this._isWithContent() && this._isEnabled)) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));\n const shadowRoot = findShadowRoot(this._element);\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);\n if (showEvent.defaultPrevented || !isInTheDom) {\n return;\n }\n\n // TODO: v6 remove this or make it optional\n this._disposePopper();\n const tip = this._getTipElement();\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'));\n const {\n container\n } = this._config;\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip);\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));\n }\n this._popper = this._createPopper(tip);\n tip.classList.add(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));\n if (this._isHovered === false) {\n this._leave();\n }\n this._isHovered = false;\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n hide() {\n if (!this._isShown()) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));\n if (hideEvent.defaultPrevented) {\n return;\n }\n const tip = this._getTipElement();\n tip.classList.remove(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n this._activeTrigger[TRIGGER_CLICK] = false;\n this._activeTrigger[TRIGGER_FOCUS] = false;\n this._activeTrigger[TRIGGER_HOVER] = false;\n this._isHovered = null; // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return;\n }\n if (!this._isHovered) {\n this._disposePopper();\n }\n this._element.removeAttribute('aria-describedby');\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n update() {\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle());\n }\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());\n }\n return this.tip;\n }\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml();\n\n // TODO: remove this check in v6\n if (!tip) {\n return null;\n }\n tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n // TODO: v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`);\n const tipId = getUID(this.constructor.NAME).toString();\n tip.setAttribute('id', tipId);\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE$2);\n }\n return tip;\n }\n setContent(content) {\n this._newContent = content;\n if (this._isShown()) {\n this._disposePopper();\n this.show();\n }\n }\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content);\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n });\n }\n return this._templateFactory;\n }\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n };\n }\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n }\n _isAnimated() {\n return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);\n }\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);\n }\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element]);\n const attachment = AttachmentMap[placement.toUpperCase()];\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment));\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element]);\n }\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [{\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }, {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n }, {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement);\n }\n }]\n };\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _setListeners() {\n const triggers = this._config.trigger.split(' ');\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context.toggle();\n });\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);\n const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n context._enter();\n });\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n context._leave();\n });\n }\n }\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide();\n }\n };\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n }\n _fixTitle() {\n const title = this._element.getAttribute('title');\n if (!title) {\n return;\n }\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title);\n }\n this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title');\n }\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true;\n return;\n }\n this._isHovered = true;\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show();\n }\n }, this._config.delay.show);\n }\n _leave() {\n if (this._isWithActiveTrigger()) {\n return;\n }\n this._isHovered = false;\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide();\n }\n }, this._config.delay.hide);\n }\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout);\n this._timeout = setTimeout(handler, timeout);\n }\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true);\n }\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element);\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute];\n }\n }\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n };\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container);\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n return config;\n }\n _getDelegateConfig() {\n const config = {};\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value;\n }\n }\n config.selector = false;\n config.trigger = 'manual';\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config;\n }\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy();\n this._popper = null;\n }\n if (this.tip) {\n this.tip.remove();\n this.tip = null;\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$3 = 'popover';\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\nconst Default$2 = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' + '
' + '

' + '
' + '
',\n trigger: 'click'\n};\nconst DefaultType$2 = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n};\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default$2;\n }\n static get DefaultType() {\n return DefaultType$2;\n }\n static get NAME() {\n return NAME$3;\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent();\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n };\n }\n _getContent() {\n return this._resolvePossibleFunction(this._config.content);\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_CLICK = `click${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_TARGET_LINKS = '[href]';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst Default$1 = {\n offset: null,\n // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n};\nconst DefaultType$1 = {\n offset: '(number|null)',\n // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n};\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map();\n this._observableSections = new Map();\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;\n this._activeTarget = null;\n this._observer = null;\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n };\n this.refresh(); // initialize\n }\n\n // Getters\n static get Default() {\n return Default$1;\n }\n static get DefaultType() {\n return DefaultType$1;\n }\n static get NAME() {\n return NAME$2;\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables();\n this._maybeEnableSmoothScroll();\n if (this._observer) {\n this._observer.disconnect();\n } else {\n this._observer = this._getNewObserver();\n }\n for (const section of this._observableSections.values()) {\n this._observer.observe(section);\n }\n }\n dispose() {\n this._observer.disconnect();\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body;\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));\n }\n return config;\n }\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return;\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK);\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash);\n if (observableSection) {\n event.preventDefault();\n const root = this._rootElement || window;\n const height = observableSection.offsetTop - this._element.offsetTop;\n if (root.scrollTo) {\n root.scrollTo({\n top: height,\n behavior: 'smooth'\n });\n return;\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height;\n }\n });\n }\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n };\n return new IntersectionObserver(entries => this._observerCallback(entries), options);\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop;\n this._process(targetElement(entry));\n };\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;\n this._previousScrollData.parentScrollTop = parentScrollTop;\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null;\n this._clearActiveClass(targetElement(entry));\n continue;\n }\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry);\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return;\n }\n continue;\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry);\n }\n }\n }\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map();\n this._observableSections = new Map();\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue;\n }\n const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(decodeURI(anchor.hash), anchor);\n this._observableSections.set(anchor.hash, observableSection);\n }\n }\n }\n _process(target) {\n if (this._activeTarget === target) {\n return;\n }\n this._clearActiveClass(this._config.target);\n this._activeTarget = target;\n target.classList.add(CLASS_NAME_ACTIVE$1);\n this._activateParents(target);\n EventHandler.trigger(this._element, EVENT_ACTIVATE, {\n relatedTarget: target\n });\n }\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);\n return;\n }\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both
+
alpha

Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
data

Name of vertex_data to show. Object must have vertex_data with the same name.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vertex_ids

Show ids of vertices

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
element_ids

Show ids of elements

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
lighting

Lighting options {‘default’, ‘metallic’, ‘plastic’, ‘shiny’, ‘glossy’, ‘ambient’, ‘off’}

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
cmap

Colormap for vertex_data plots.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vmin

Minimum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
vmax

Maximum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_alpha

Colormap Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_n_colors

Set the number of available colors

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
scalarbar

Scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, title_yoffset: int, font_size: int, nlabels: int, c: str, horizontal: bool, use_alpha: bool, label_format: str}. Setting bool will add a default scalarbar

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
scalarbar3d

3D scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, size: list, title_font: str, title_xoffset: float, title_yoffset: float, title_size: float, title_rotation: float, nlabels: int, label_font:str, label_size: float, label_offset: float, label_rotation: int, label_format: str, draw_box: bool, above_text: str, below_text: str, nan_text: str, categories: list}

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
arrow_data

Name of vertex_data to plot as arrow. Corresponding data should be at least 2D. If you want more control over arrows, consider creating edges using gus.create.edges.from_data().

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
arrow_data_scale

Scaling factor for arrow data.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
arrow_data_color

Color for arrow data. Can be either cmap name or color. For cmap, colors are based on the size of the arrows.

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
axes

Configure a specific axes with options. Expect dict(), but setting True will set a default axes. For full options, see https://vedo.embl.es/autodocs/content/vedo/addons.html#vedo.addons.Axes

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
r

Radius of vertices in units of pixels.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
labels

Places a label/description str at the place of vertices.

+
    +
  • allowed types: ( numpy.ndarray, tuple, list)

  • +
  • default: None

    +

+ +
label_options

Label kwargs to be passed during initialization.Valid keywords are: {scale: float, xrot: float, yrot: float, zrot: float, ratio: float, precision: int, italic: bool, font: str, justify: str, c: (str, tuple, list, int), alpha: float}. As further hint, justify takes ‘-’ joined combination of {center, mid, right, left, top, bottom}.

+
    +
  • allowed types: ( dict,)

  • +
  • default: None

    +

+ + +
+

EdgesShowOption#

+
c

Color in {rgb, RGB, str of (hex, name), int}

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
alpha

Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
data

Name of vertex_data to show. Object must have vertex_data with the same name.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vertex_ids

Show ids of vertices

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
element_ids

Show ids of elements

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
lighting

Lighting options {‘default’, ‘metallic’, ‘plastic’, ‘shiny’, ‘glossy’, ‘ambient’, ‘off’}

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
cmap

Colormap for vertex_data plots.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vmin

Minimum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
vmax

Maximum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_alpha

Colormap Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_n_colors

Set the number of available colors

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
scalarbar

Scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, title_yoffset: int, font_size: int, nlabels: int, c: str, horizontal: bool, use_alpha: bool, label_format: str}. Setting bool will add a default scalarbar

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
scalarbar3d

3D scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, size: list, title_font: str, title_xoffset: float, title_yoffset: float, title_size: float, title_rotation: float, nlabels: int, label_font:str, label_size: float, label_offset: float, label_rotation: int, label_format: str, draw_box: bool, above_text: str, below_text: str, nan_text: str, categories: list}

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
arrow_data

Name of vertex_data to plot as arrow. Corresponding data should be at least 2D. If you want more control over arrows, consider creating edges using gus.create.edges.from_data().

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
arrow_data_scale

Scaling factor for arrow data.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
arrow_data_color

Color for arrow data. Can be either cmap name or color. For cmap, colors are based on the size of the arrows.

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
axes

Configure a specific axes with options. Expect dict(), but setting True will set a default axes. For full options, see https://vedo.embl.es/autodocs/content/vedo/addons.html#vedo.addons.Axes

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
lw

Width of edges (lines) in pixel units.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
as_arrows

Show edges as arrows.

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
head_radius

Radius of arrow head. Applicable if as_arrows is True

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
head_length

Length of arrow head. Applicable if as_arrows is True

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
shaft_radius

Radius of arrow shaft. Applicable if as_arrows is True

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
+
+

FacesShowOption#

+
c

Color in {rgb, RGB, str of (hex, name), int}

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
alpha

Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
data

Name of vertex_data to show. Object must have vertex_data with the same name.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vertex_ids

Show ids of vertices

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
element_ids

Show ids of elements

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
lighting

Lighting options {‘default’, ‘metallic’, ‘plastic’, ‘shiny’, ‘glossy’, ‘ambient’, ‘off’}

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
cmap

Colormap for vertex_data plots.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vmin

Minimum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
vmax

Maximum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_alpha

Colormap Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_n_colors

Set the number of available colors

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
scalarbar

Scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, title_yoffset: int, font_size: int, nlabels: int, c: str, horizontal: bool, use_alpha: bool, label_format: str}. Setting bool will add a default scalarbar

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
scalarbar3d

3D scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, size: list, title_font: str, title_xoffset: float, title_yoffset: float, title_size: float, title_rotation: float, nlabels: int, label_font:str, label_size: float, label_offset: float, label_rotation: int, label_format: str, draw_box: bool, above_text: str, below_text: str, nan_text: str, categories: list}

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
arrow_data

Name of vertex_data to plot as arrow. Corresponding data should be at least 2D. If you want more control over arrows, consider creating edges using gus.create.edges.from_data().

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
arrow_data_scale

Scaling factor for arrow data.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
arrow_data_color

Color for arrow data. Can be either cmap name or color. For cmap, colors are based on the size of the arrows.

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
axes

Configure a specific axes with options. Expect dict(), but setting True will set a default axes. For full options, see https://vedo.embl.es/autodocs/content/vedo/addons.html#vedo.addons.Axes

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
lw

Width of edges (lines) in pixel units.

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
lc

Color of edges (lines).

+
    +
  • allowed types: ( int, str, tuple, list)

  • +
  • default: None

    +

+ +
texture

Texture of faces in array, vedo.Picture, vtk.vtkTexture, or path to an image.

+
    +
  • allowed types: ( numpy.ndarray, tuple, list, str, vedo.image.Picture, vtkmodules.vtkRenderingCore.vtkTexture)

  • +
  • default: None

    +

+ +
+
+

VolumesShowOption#

+
c

Color in {rgb, RGB, str of (hex, name), int}

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
alpha

Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
data

Name of vertex_data to show. Object must have vertex_data with the same name.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vertex_ids

Show ids of vertices

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
element_ids

Show ids of elements

+
    +
  • allowed types: ( bool,)

  • +
  • default: None

    +

+ +
lighting

Lighting options {‘default’, ‘metallic’, ‘plastic’, ‘shiny’, ‘glossy’, ‘ambient’, ‘off’}

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
cmap

Colormap for vertex_data plots.

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
vmin

Minimum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
vmax

Maximum value for cmap

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_alpha

Colormap Transparency in range [0, 1].

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
cmap_n_colors

Set the number of available colors

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
scalarbar

Scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, title_yoffset: int, font_size: int, nlabels: int, c: str, horizontal: bool, use_alpha: bool, label_format: str}. Setting bool will add a default scalarbar

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
scalarbar3d

3D scalarbar describing cmap. At least an empty dict or dict with following items are accepted: {title: str, pos: tuple, size: list, title_font: str, title_xoffset: float, title_yoffset: float, title_size: float, title_rotation: float, nlabels: int, label_font:str, label_size: float, label_offset: float, label_rotation: int, label_format: str, draw_box: bool, above_text: str, below_text: str, nan_text: str, categories: list}

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
arrow_data

Name of vertex_data to plot as arrow. Corresponding data should be at least 2D. If you want more control over arrows, consider creating edges using gus.create.edges.from_data().

+
    +
  • allowed types: ( str,)

  • +
  • default: None

    +

+ +
arrow_data_scale

Scaling factor for arrow data.

+
    +
  • allowed types: ( float, int)

  • +
  • default: None

    +

+ +
arrow_data_color

Color for arrow data. Can be either cmap name or color. For cmap, colors are based on the size of the arrows.

+
    +
  • allowed types: ( str, tuple, list, int)

  • +
  • default: None

    +

+ +
axes

Configure a specific axes with options. Expect dict(), but setting True will set a default axes. For full options, see https://vedo.embl.es/autodocs/content/vedo/addons.html#vedo.addons.Axes

+
    +
  • allowed types: ( bool, dict)

  • +
  • default: None

    +

+ +
lw

Width of edges (lines) in pixel units.

+
    +
  • allowed types: ( int,)

  • +
  • default: None

    +

+ +
lc

Color of edges (lines).

+
    +
  • allowed types: ( int, str, tuple, list)

  • +
  • default: None

    +

+ +
+ + + + + + + + + + + + + + + +
+ + + +
+ +
+ + + + + + + + + + + + \ No newline at end of file