diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..00cfae505 --- /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: de75278cad59f59d80b838b08d7ae0ff +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 000000000..ca733abed Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/geometry/gdstk.Curve.doctree b/.doctrees/geometry/gdstk.Curve.doctree new file mode 100644 index 000000000..feecbb538 Binary files /dev/null and b/.doctrees/geometry/gdstk.Curve.doctree differ diff --git a/.doctrees/geometry/gdstk.FlexPath.doctree b/.doctrees/geometry/gdstk.FlexPath.doctree new file mode 100644 index 000000000..fc4fec12c Binary files /dev/null and b/.doctrees/geometry/gdstk.FlexPath.doctree differ diff --git a/.doctrees/geometry/gdstk.Polygon.doctree b/.doctrees/geometry/gdstk.Polygon.doctree new file mode 100644 index 000000000..684b8952e Binary files /dev/null and b/.doctrees/geometry/gdstk.Polygon.doctree differ diff --git a/.doctrees/geometry/gdstk.Repetition.doctree b/.doctrees/geometry/gdstk.Repetition.doctree new file mode 100644 index 000000000..208017f44 Binary files /dev/null and b/.doctrees/geometry/gdstk.Repetition.doctree differ diff --git a/.doctrees/geometry/gdstk.RobustPath.doctree b/.doctrees/geometry/gdstk.RobustPath.doctree new file mode 100644 index 000000000..a979b53eb Binary files /dev/null and b/.doctrees/geometry/gdstk.RobustPath.doctree differ diff --git a/.doctrees/geometry/gdstk.all_inside.doctree b/.doctrees/geometry/gdstk.all_inside.doctree new file mode 100644 index 000000000..6f1fb6524 Binary files /dev/null and b/.doctrees/geometry/gdstk.all_inside.doctree differ diff --git a/.doctrees/geometry/gdstk.any_inside.doctree b/.doctrees/geometry/gdstk.any_inside.doctree new file mode 100644 index 000000000..cafd94b4e Binary files /dev/null and b/.doctrees/geometry/gdstk.any_inside.doctree differ diff --git a/.doctrees/geometry/gdstk.boolean.doctree b/.doctrees/geometry/gdstk.boolean.doctree new file mode 100644 index 000000000..e5e91b44e Binary files /dev/null and b/.doctrees/geometry/gdstk.boolean.doctree differ diff --git a/.doctrees/geometry/gdstk.contour.doctree b/.doctrees/geometry/gdstk.contour.doctree new file mode 100644 index 000000000..8766b1789 Binary files /dev/null and b/.doctrees/geometry/gdstk.contour.doctree differ diff --git a/.doctrees/geometry/gdstk.cross.doctree b/.doctrees/geometry/gdstk.cross.doctree new file mode 100644 index 000000000..3e79a3584 Binary files /dev/null and b/.doctrees/geometry/gdstk.cross.doctree differ diff --git a/.doctrees/geometry/gdstk.ellipse.doctree b/.doctrees/geometry/gdstk.ellipse.doctree new file mode 100644 index 000000000..517f8d537 Binary files /dev/null and b/.doctrees/geometry/gdstk.ellipse.doctree differ diff --git a/.doctrees/geometry/gdstk.inside.doctree b/.doctrees/geometry/gdstk.inside.doctree new file mode 100644 index 000000000..f5d396680 Binary files /dev/null and b/.doctrees/geometry/gdstk.inside.doctree differ diff --git a/.doctrees/geometry/gdstk.offset.doctree b/.doctrees/geometry/gdstk.offset.doctree new file mode 100644 index 000000000..4dacafd81 Binary files /dev/null and b/.doctrees/geometry/gdstk.offset.doctree differ diff --git a/.doctrees/geometry/gdstk.racetrack.doctree b/.doctrees/geometry/gdstk.racetrack.doctree new file mode 100644 index 000000000..680000227 Binary files /dev/null and b/.doctrees/geometry/gdstk.racetrack.doctree differ diff --git a/.doctrees/geometry/gdstk.rectangle.doctree b/.doctrees/geometry/gdstk.rectangle.doctree new file mode 100644 index 000000000..7cad0223e Binary files /dev/null and b/.doctrees/geometry/gdstk.rectangle.doctree differ diff --git a/.doctrees/geometry/gdstk.regular_polygon.doctree b/.doctrees/geometry/gdstk.regular_polygon.doctree new file mode 100644 index 000000000..58e7d4c59 Binary files /dev/null and b/.doctrees/geometry/gdstk.regular_polygon.doctree differ diff --git a/.doctrees/geometry/gdstk.slice.doctree b/.doctrees/geometry/gdstk.slice.doctree new file mode 100644 index 000000000..8353618ac Binary files /dev/null and b/.doctrees/geometry/gdstk.slice.doctree differ diff --git a/.doctrees/geometry/gdstk.text.doctree b/.doctrees/geometry/gdstk.text.doctree new file mode 100644 index 000000000..c6fb86994 Binary files /dev/null and b/.doctrees/geometry/gdstk.text.doctree differ diff --git a/.doctrees/gettingstarted.doctree b/.doctrees/gettingstarted.doctree new file mode 100644 index 000000000..a2b584d3a Binary files /dev/null and b/.doctrees/gettingstarted.doctree differ diff --git a/.doctrees/headers/allocator.doctree b/.doctrees/headers/allocator.doctree new file mode 100644 index 000000000..8b021eb77 Binary files /dev/null and b/.doctrees/headers/allocator.doctree differ diff --git a/.doctrees/headers/array.doctree b/.doctrees/headers/array.doctree new file mode 100644 index 000000000..dd846d5e0 Binary files /dev/null and b/.doctrees/headers/array.doctree differ diff --git a/.doctrees/headers/cell.doctree b/.doctrees/headers/cell.doctree new file mode 100644 index 000000000..f3bf29495 Binary files /dev/null and b/.doctrees/headers/cell.doctree differ diff --git a/.doctrees/headers/clipper_tools.doctree b/.doctrees/headers/clipper_tools.doctree new file mode 100644 index 000000000..4e8207ec1 Binary files /dev/null and b/.doctrees/headers/clipper_tools.doctree differ diff --git a/.doctrees/headers/curve.doctree b/.doctrees/headers/curve.doctree new file mode 100644 index 000000000..7c887c3a6 Binary files /dev/null and b/.doctrees/headers/curve.doctree differ diff --git a/.doctrees/headers/flexpath.doctree b/.doctrees/headers/flexpath.doctree new file mode 100644 index 000000000..ee35ac64d Binary files /dev/null and b/.doctrees/headers/flexpath.doctree differ diff --git a/.doctrees/headers/font.doctree b/.doctrees/headers/font.doctree new file mode 100644 index 000000000..5dfffad3e Binary files /dev/null and b/.doctrees/headers/font.doctree differ diff --git a/.doctrees/headers/gdsii.doctree b/.doctrees/headers/gdsii.doctree new file mode 100644 index 000000000..659e6e3d9 Binary files /dev/null and b/.doctrees/headers/gdsii.doctree differ diff --git a/.doctrees/headers/gdstk.doctree b/.doctrees/headers/gdstk.doctree new file mode 100644 index 000000000..028e646c9 Binary files /dev/null and b/.doctrees/headers/gdstk.doctree differ diff --git a/.doctrees/headers/gdswriter.doctree b/.doctrees/headers/gdswriter.doctree new file mode 100644 index 000000000..8d88fa2b2 Binary files /dev/null and b/.doctrees/headers/gdswriter.doctree differ diff --git a/.doctrees/headers/label.doctree b/.doctrees/headers/label.doctree new file mode 100644 index 000000000..d7cfbe736 Binary files /dev/null and b/.doctrees/headers/label.doctree differ diff --git a/.doctrees/headers/library.doctree b/.doctrees/headers/library.doctree new file mode 100644 index 000000000..b74937642 Binary files /dev/null and b/.doctrees/headers/library.doctree differ diff --git a/.doctrees/headers/map.doctree b/.doctrees/headers/map.doctree new file mode 100644 index 000000000..fc0f5e192 Binary files /dev/null and b/.doctrees/headers/map.doctree differ diff --git a/.doctrees/headers/oasis.doctree b/.doctrees/headers/oasis.doctree new file mode 100644 index 000000000..42b671536 Binary files /dev/null and b/.doctrees/headers/oasis.doctree differ diff --git a/.doctrees/headers/pathcommon.doctree b/.doctrees/headers/pathcommon.doctree new file mode 100644 index 000000000..52d0ef9b0 Binary files /dev/null and b/.doctrees/headers/pathcommon.doctree differ diff --git a/.doctrees/headers/polygon.doctree b/.doctrees/headers/polygon.doctree new file mode 100644 index 000000000..1aa34acbf Binary files /dev/null and b/.doctrees/headers/polygon.doctree differ diff --git a/.doctrees/headers/property.doctree b/.doctrees/headers/property.doctree new file mode 100644 index 000000000..4209a5939 Binary files /dev/null and b/.doctrees/headers/property.doctree differ diff --git a/.doctrees/headers/rawcell.doctree b/.doctrees/headers/rawcell.doctree new file mode 100644 index 000000000..50882d355 Binary files /dev/null and b/.doctrees/headers/rawcell.doctree differ diff --git a/.doctrees/headers/reference.doctree b/.doctrees/headers/reference.doctree new file mode 100644 index 000000000..02449bc90 Binary files /dev/null and b/.doctrees/headers/reference.doctree differ diff --git a/.doctrees/headers/repetition.doctree b/.doctrees/headers/repetition.doctree new file mode 100644 index 000000000..9cc2e9c2f Binary files /dev/null and b/.doctrees/headers/repetition.doctree differ diff --git a/.doctrees/headers/robustpath.doctree b/.doctrees/headers/robustpath.doctree new file mode 100644 index 000000000..d6c28550b Binary files /dev/null and b/.doctrees/headers/robustpath.doctree differ diff --git a/.doctrees/headers/style.doctree b/.doctrees/headers/style.doctree new file mode 100644 index 000000000..8d185e958 Binary files /dev/null and b/.doctrees/headers/style.doctree differ diff --git a/.doctrees/headers/utils.doctree b/.doctrees/headers/utils.doctree new file mode 100644 index 000000000..643ac2c19 Binary files /dev/null and b/.doctrees/headers/utils.doctree differ diff --git a/.doctrees/headers/vec.doctree b/.doctrees/headers/vec.doctree new file mode 100644 index 000000000..cffde44f1 Binary files /dev/null and b/.doctrees/headers/vec.doctree differ diff --git a/.doctrees/how-tos.doctree b/.doctrees/how-tos.doctree new file mode 100644 index 000000000..6261304b5 Binary files /dev/null and b/.doctrees/how-tos.doctree differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 000000000..a780cecbe Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/library/gdstk.Cell.doctree b/.doctrees/library/gdstk.Cell.doctree new file mode 100644 index 000000000..2f92693d3 Binary files /dev/null and b/.doctrees/library/gdstk.Cell.doctree differ diff --git a/.doctrees/library/gdstk.GdsWriter.doctree b/.doctrees/library/gdstk.GdsWriter.doctree new file mode 100644 index 000000000..acf4e3287 Binary files /dev/null and b/.doctrees/library/gdstk.GdsWriter.doctree differ diff --git a/.doctrees/library/gdstk.Label.doctree b/.doctrees/library/gdstk.Label.doctree new file mode 100644 index 000000000..12ceb4d43 Binary files /dev/null and b/.doctrees/library/gdstk.Label.doctree differ diff --git a/.doctrees/library/gdstk.Library.doctree b/.doctrees/library/gdstk.Library.doctree new file mode 100644 index 000000000..fcea96098 Binary files /dev/null and b/.doctrees/library/gdstk.Library.doctree differ diff --git a/.doctrees/library/gdstk.RawCell.doctree b/.doctrees/library/gdstk.RawCell.doctree new file mode 100644 index 000000000..f6f5740ad Binary files /dev/null and b/.doctrees/library/gdstk.RawCell.doctree differ diff --git a/.doctrees/library/gdstk.Reference.doctree b/.doctrees/library/gdstk.Reference.doctree new file mode 100644 index 000000000..6b238ba54 Binary files /dev/null and b/.doctrees/library/gdstk.Reference.doctree differ diff --git a/.doctrees/library/gdstk.gds_info.doctree b/.doctrees/library/gdstk.gds_info.doctree new file mode 100644 index 000000000..9d2f63ab5 Binary files /dev/null and b/.doctrees/library/gdstk.gds_info.doctree differ diff --git a/.doctrees/library/gdstk.gds_units.doctree b/.doctrees/library/gdstk.gds_units.doctree new file mode 100644 index 000000000..77a2ee838 Binary files /dev/null and b/.doctrees/library/gdstk.gds_units.doctree differ diff --git a/.doctrees/library/gdstk.oas_precision.doctree b/.doctrees/library/gdstk.oas_precision.doctree new file mode 100644 index 000000000..5aa6398a0 Binary files /dev/null and b/.doctrees/library/gdstk.oas_precision.doctree differ diff --git a/.doctrees/library/gdstk.oas_validate.doctree b/.doctrees/library/gdstk.oas_validate.doctree new file mode 100644 index 000000000..621107e6b Binary files /dev/null and b/.doctrees/library/gdstk.oas_validate.doctree differ diff --git a/.doctrees/library/gdstk.read_gds.doctree b/.doctrees/library/gdstk.read_gds.doctree new file mode 100644 index 000000000..fcb24c1f7 Binary files /dev/null and b/.doctrees/library/gdstk.read_gds.doctree differ diff --git a/.doctrees/library/gdstk.read_oas.doctree b/.doctrees/library/gdstk.read_oas.doctree new file mode 100644 index 000000000..614107e10 Binary files /dev/null and b/.doctrees/library/gdstk.read_oas.doctree differ diff --git a/.doctrees/library/gdstk.read_rawcells.doctree b/.doctrees/library/gdstk.read_rawcells.doctree new file mode 100644 index 000000000..09eaf15d0 Binary files /dev/null and b/.doctrees/library/gdstk.read_rawcells.doctree differ diff --git a/.doctrees/reference_cpp.doctree b/.doctrees/reference_cpp.doctree new file mode 100644 index 000000000..9eeb1ea74 Binary files /dev/null and b/.doctrees/reference_cpp.doctree differ diff --git a/.doctrees/reference_python.doctree b/.doctrees/reference_python.doctree new file mode 100644 index 000000000..e0db40cc4 Binary files /dev/null and b/.doctrees/reference_python.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_images/apply_repetition.svg b/_images/apply_repetition.svg new file mode 100644 index 000000000..673d6b1a3 --- /dev/null +++ b/_images/apply_repetition.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/arc.svg b/_images/arc.svg new file mode 100644 index 000000000..bf73fe95f --- /dev/null +++ b/_images/arc.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/arc1.svg b/_images/arc1.svg new file mode 100644 index 000000000..b83370d34 --- /dev/null +++ b/_images/arc1.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/arc2.svg b/_images/arc2.svg new file mode 100644 index 000000000..fd98717e1 --- /dev/null +++ b/_images/arc2.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/bezier.svg b/_images/bezier.svg new file mode 100644 index 000000000..757c02a40 --- /dev/null +++ b/_images/bezier.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/bezier1.svg b/_images/bezier1.svg new file mode 100644 index 000000000..dd8998ddc --- /dev/null +++ b/_images/bezier1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/bezier2.svg b/_images/bezier2.svg new file mode 100644 index 000000000..52ebf06d6 --- /dev/null +++ b/_images/bezier2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/boolean.svg b/_images/boolean.svg new file mode 100644 index 000000000..e62a2a4aa --- /dev/null +++ b/_images/boolean.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/boolean_operations.svg b/_images/boolean_operations.svg new file mode 100644 index 000000000..7e9977fcf --- /dev/null +++ b/_images/boolean_operations.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/bounding_box.svg b/_images/bounding_box.svg new file mode 100644 index 000000000..ef8bade86 --- /dev/null +++ b/_images/bounding_box.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/bounding_box1.svg b/_images/bounding_box1.svg new file mode 100644 index 000000000..1060f5389 --- /dev/null +++ b/_images/bounding_box1.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/bounding_box2.svg b/_images/bounding_box2.svg new file mode 100644 index 000000000..1ba71a715 --- /dev/null +++ b/_images/bounding_box2.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/circles.svg b/_images/circles.svg new file mode 100644 index 000000000..a946d8a5d --- /dev/null +++ b/_images/circles.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/commands.svg b/_images/commands.svg new file mode 100644 index 000000000..dbea449b5 --- /dev/null +++ b/_images/commands.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/commands1.svg b/_images/commands1.svg new file mode 100644 index 000000000..189e31904 --- /dev/null +++ b/_images/commands1.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/commands2.svg b/_images/commands2.svg new file mode 100644 index 000000000..2ccd48818 --- /dev/null +++ b/_images/commands2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/contour.svg b/_images/contour.svg new file mode 100644 index 000000000..bec461726 --- /dev/null +++ b/_images/contour.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/convex_hull.svg b/_images/convex_hull.svg new file mode 100644 index 000000000..f2a0a32f0 --- /dev/null +++ b/_images/convex_hull.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/convex_hull1.svg b/_images/convex_hull1.svg new file mode 100644 index 000000000..5e1fa72f9 --- /dev/null +++ b/_images/convex_hull1.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/cross.svg b/_images/cross.svg new file mode 100644 index 000000000..ca6b649e2 --- /dev/null +++ b/_images/cross.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic.svg b/_images/cubic.svg new file mode 100644 index 000000000..7126af9bd --- /dev/null +++ b/_images/cubic.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic1.svg b/_images/cubic1.svg new file mode 100644 index 000000000..f596090e0 --- /dev/null +++ b/_images/cubic1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic2.svg b/_images/cubic2.svg new file mode 100644 index 000000000..c30fb13a6 --- /dev/null +++ b/_images/cubic2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic_smooth.svg b/_images/cubic_smooth.svg new file mode 100644 index 000000000..ce7b61665 --- /dev/null +++ b/_images/cubic_smooth.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic_smooth1.svg b/_images/cubic_smooth1.svg new file mode 100644 index 000000000..f8f03ffaf --- /dev/null +++ b/_images/cubic_smooth1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/cubic_smooth2.svg b/_images/cubic_smooth2.svg new file mode 100644 index 000000000..b9611b52b --- /dev/null +++ b/_images/cubic_smooth2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/curves.svg b/_images/curves.svg new file mode 100644 index 000000000..5f973fa13 --- /dev/null +++ b/_images/curves.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/curves_1.svg b/_images/curves_1.svg new file mode 100644 index 000000000..26e70535c --- /dev/null +++ b/_images/curves_1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/curves_2.svg b/_images/curves_2.svg new file mode 100644 index 000000000..b6fc26b9f --- /dev/null +++ b/_images/curves_2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/ellipse.svg b/_images/ellipse.svg new file mode 100644 index 000000000..f5cdd174a --- /dev/null +++ b/_images/ellipse.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/fillet.svg b/_images/fillet.svg new file mode 100644 index 000000000..47ed193bf --- /dev/null +++ b/_images/fillet.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/fillet_operation.svg b/_images/fillet_operation.svg new file mode 100644 index 000000000..c4033370b --- /dev/null +++ b/_images/fillet_operation.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/filtering.svg b/_images/filtering.svg new file mode 100644 index 000000000..5758a372a --- /dev/null +++ b/_images/filtering.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/flatten.svg b/_images/flatten.svg new file mode 100644 index 000000000..c3042ddbf --- /dev/null +++ b/_images/flatten.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/flexible_paths.svg b/_images/flexible_paths.svg new file mode 100644 index 000000000..79b5dc809 --- /dev/null +++ b/_images/flexible_paths.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/flexible_paths_2.svg b/_images/flexible_paths_2.svg new file mode 100644 index 000000000..74bd19ce1 --- /dev/null +++ b/_images/flexible_paths_2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/flexible_paths_3.svg b/_images/flexible_paths_3.svg new file mode 100644 index 000000000..f2ef3de9f --- /dev/null +++ b/_images/flexible_paths_3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/fonts.svg b/_images/fonts.svg new file mode 100644 index 000000000..8933df084 --- /dev/null +++ b/_images/fonts.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/fracture.svg b/_images/fracture.svg new file mode 100644 index 000000000..0afac6a6c --- /dev/null +++ b/_images/fracture.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/holes.svg b/_images/holes.svg new file mode 100644 index 000000000..f6bca0745 --- /dev/null +++ b/_images/holes.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/horizontal.svg b/_images/horizontal.svg new file mode 100644 index 000000000..6e7785e23 --- /dev/null +++ b/_images/horizontal.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/init.svg b/_images/init.svg new file mode 100644 index 000000000..21e0fcc96 --- /dev/null +++ b/_images/init.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/init0.svg b/_images/init0.svg new file mode 100644 index 000000000..c0558ea1b --- /dev/null +++ b/_images/init0.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/init1.svg b/_images/init1.svg new file mode 100644 index 000000000..ccb04475c --- /dev/null +++ b/_images/init1.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/init11.svg b/_images/init11.svg new file mode 100644 index 000000000..a15678087 --- /dev/null +++ b/_images/init11.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/init12.svg b/_images/init12.svg new file mode 100644 index 000000000..b8bcc7952 --- /dev/null +++ b/_images/init12.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/init2.svg b/_images/init2.svg new file mode 100644 index 000000000..54d50dfb1 --- /dev/null +++ b/_images/init2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/init3.svg b/_images/init3.svg new file mode 100644 index 000000000..2a0bf85ed --- /dev/null +++ b/_images/init3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/init4.svg b/_images/init4.svg new file mode 100644 index 000000000..7a0f94db3 --- /dev/null +++ b/_images/init4.svg @@ -0,0 +1,22 @@ + + + + + + + + +Center +North +South +East +West +Northeast +Southeast +Northwest +Southwest + + \ No newline at end of file diff --git a/_images/init5.svg b/_images/init5.svg new file mode 100644 index 000000000..87945dff0 --- /dev/null +++ b/_images/init5.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/interpolation.svg b/_images/interpolation.svg new file mode 100644 index 000000000..e73e5c621 --- /dev/null +++ b/_images/interpolation.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/interpolation1.svg b/_images/interpolation1.svg new file mode 100644 index 000000000..e39c9a089 --- /dev/null +++ b/_images/interpolation1.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/interpolation2.svg b/_images/interpolation2.svg new file mode 100644 index 000000000..a3b603d31 --- /dev/null +++ b/_images/interpolation2.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/layer_and_datatype.svg b/_images/layer_and_datatype.svg new file mode 100644 index 000000000..97ae1be46 --- /dev/null +++ b/_images/layer_and_datatype.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/layout.svg b/_images/layout.svg new file mode 100644 index 000000000..c9816f0f8 --- /dev/null +++ b/_images/layout.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/offset.svg b/_images/offset.svg new file mode 100644 index 000000000..fbfef5914 --- /dev/null +++ b/_images/offset.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/offset_operation.svg b/_images/offset_operation.svg new file mode 100644 index 000000000..5f771b48c --- /dev/null +++ b/_images/offset_operation.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/pads.svg b/_images/pads.svg new file mode 100644 index 000000000..2dfbbfdc2 --- /dev/null +++ b/_images/pads.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/parametric.svg b/_images/parametric.svg new file mode 100644 index 000000000..a41716429 --- /dev/null +++ b/_images/parametric.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/parametric1.svg b/_images/parametric1.svg new file mode 100644 index 000000000..c89b87c4d --- /dev/null +++ b/_images/parametric1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/parametric2.svg b/_images/parametric2.svg new file mode 100644 index 000000000..7c67517dc --- /dev/null +++ b/_images/parametric2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/parametric_cell.svg b/_images/parametric_cell.svg new file mode 100644 index 000000000..0434736a1 --- /dev/null +++ b/_images/parametric_cell.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/path_markers.svg b/_images/path_markers.svg new file mode 100644 index 000000000..fc054d6f7 --- /dev/null +++ b/_images/path_markers.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/polygons.svg b/_images/polygons.svg new file mode 100644 index 000000000..e78f6403c --- /dev/null +++ b/_images/polygons.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/pos_filtering.svg b/_images/pos_filtering.svg new file mode 100644 index 000000000..62b5a172e --- /dev/null +++ b/_images/pos_filtering.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/racetrack.svg b/_images/racetrack.svg new file mode 100644 index 000000000..5a4b09be3 --- /dev/null +++ b/_images/racetrack.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/references.svg b/_images/references.svg new file mode 100644 index 000000000..0d5e205b5 --- /dev/null +++ b/_images/references.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/regular_polygon.svg b/_images/regular_polygon.svg new file mode 100644 index 000000000..91de39b5c --- /dev/null +++ b/_images/regular_polygon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/remove.svg b/_images/remove.svg new file mode 100644 index 000000000..a22af7a4f --- /dev/null +++ b/_images/remove.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/repetitions.svg b/_images/repetitions.svg new file mode 100644 index 000000000..3fddb1ae8 --- /dev/null +++ b/_images/repetitions.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/robust_paths.svg b/_images/robust_paths.svg new file mode 100644 index 000000000..2965ed521 --- /dev/null +++ b/_images/robust_paths.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/segment.svg b/_images/segment.svg new file mode 100644 index 000000000..33ffe2f20 --- /dev/null +++ b/_images/segment.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/segment1.svg b/_images/segment1.svg new file mode 100644 index 000000000..caee1f175 --- /dev/null +++ b/_images/segment1.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/segment11.svg b/_images/segment11.svg new file mode 100644 index 000000000..e68749369 --- /dev/null +++ b/_images/segment11.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/segment2.svg b/_images/segment2.svg new file mode 100644 index 000000000..cc7fa9fd4 --- /dev/null +++ b/_images/segment2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/slice.svg b/_images/slice.svg new file mode 100644 index 000000000..d9379cdf1 --- /dev/null +++ b/_images/slice.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/slice_operation.svg b/_images/slice_operation.svg new file mode 100644 index 000000000..cc7a16a45 --- /dev/null +++ b/_images/slice_operation.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/text.svg b/_images/text.svg new file mode 100644 index 000000000..5b76fd0b3 --- /dev/null +++ b/_images/text.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/text1.svg b/_images/text1.svg new file mode 100644 index 000000000..25043a837 --- /dev/null +++ b/_images/text1.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + +Sample label + + \ No newline at end of file diff --git a/_images/tolerance.svg b/_images/tolerance.svg new file mode 100644 index 000000000..0a41b139c --- /dev/null +++ b/_images/tolerance.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/_images/transformations.svg b/_images/transformations.svg new file mode 100644 index 000000000..9e5df6d5b --- /dev/null +++ b/_images/transformations.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/_images/transforms.svg b/_images/transforms.svg new file mode 100644 index 000000000..5ff4196f7 --- /dev/null +++ b/_images/transforms.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_images/write_svg.svg b/_images/write_svg.svg new file mode 100644 index 000000000..a305cf5c7 --- /dev/null +++ b/_images/write_svg.svg @@ -0,0 +1,16 @@ + + + + + + + + + +Example + + \ No newline at end of file diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 000000000..81415803e --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /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: 230px; + 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/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 000000000..c718cee44 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 000000000..6cb600001 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 000000000..7059e2314 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 000000000..f815f63f9 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 000000000..f2c76e5bd Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 000000000..88ad05b9f Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 000000000..c4e3d804b Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 000000000..c6dff51f0 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 000000000..bb195043c Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 000000000..76114bc03 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 000000000..3404f37e2 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 000000000..ae1307ff5 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 000000000..3bf984332 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 000000000..19a446a0e --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ 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..cdb2a62e4 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.9.53', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: false, + 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/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/jquery.js b/_static/jquery.js new file mode 100644 index 000000000..c4c6022f2 --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/html5shiv.min.js b/_static/js/html5shiv.min.js new file mode 100644 index 000000000..cd1c674f5 --- /dev/null +++ b/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/theme.js b/_static/js/theme.js new file mode 100644 index 000000000..1fddb6ee4 --- /dev/null +++ b/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + 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..9e207a048 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,73 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .ch { color: #999988; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .cpf { color: #999988; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #bb8844 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #999999 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #009999 } /* Literal.Number.Bin */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sa { color: #bb8844 } /* Literal.String.Affix */ +.highlight .sb { color: #bb8844 } /* Literal.String.Backtick */ +.highlight .sc { color: #bb8844 } /* Literal.String.Char */ +.highlight .dl { color: #bb8844 } /* Literal.String.Delimiter */ +.highlight .sd { color: #bb8844 } /* Literal.String.Doc */ +.highlight .s2 { color: #bb8844 } /* Literal.String.Double */ +.highlight .se { color: #bb8844 } /* Literal.String.Escape */ +.highlight .sh { color: #bb8844 } /* Literal.String.Heredoc */ +.highlight .si { color: #bb8844 } /* Literal.String.Interpol */ +.highlight .sx { color: #bb8844 } /* Literal.String.Other */ +.highlight .sr { color: #808000 } /* Literal.String.Regex */ +.highlight .s1 { color: #bb8844 } /* Literal.String.Single */ +.highlight .ss { color: #bb8844 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #990000; font-weight: bold } /* Name.Function.Magic */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .vm { color: #008080 } /* Name.Variable.Magic */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 000000000..b08d58c9b --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!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.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/tabs.css b/_static/tabs.css new file mode 100644 index 000000000..13042e567 --- /dev/null +++ b/_static/tabs.css @@ -0,0 +1,110 @@ +/* body[data-theme] { */ +:root { + --tabs--label-text: #4b5563; + --tabs--label-text--hover: #4b5563; + --tabs--label-text--active: #0ea5e9; + --tabs--label-text--active--hover: #0ea5e9; + --tabs--label-background: transparent; + --tabs--label-background--hover: transparent; + --tabs--label-background--active: transparent; + --tabs--label-background--active--hover: transparent; + --tabs--label-border: transparent; + --tabs--label-border--hover: #d1d5db; + --tabs--label-border--active: #0ea5e9; + --tabs--label-border--active--hover: #0ea5e9; + --tabs--padding-x: 1.25em; + --tabs--margin-x: 0; + --tabs--border: #e6e6e6; +} + +/* Hide radio buttons */ +.tab-set > input { + position: absolute; + opacity: 0; +} + +/* Tab set container */ +.tab-set { + border-radius: 2px; + display: flex; + flex-wrap: wrap; + margin: 0.75em 0; + position: relative; +} + +/* Tab label */ +.tab-set > label { + z-index: 1; + + width: auto; + border-bottom: 2px solid var(--tabs--label-border); + padding: 1em var(--tabs--padding-x) 0.5em; + margin-left: var(--tabs--margin-x); + + color: var(--tabs--label-text); + background: var(--tabs--label-background); + + transition: color 250ms; + + cursor: pointer; + + font-size: 0.875em; + font-weight: 700; +} +.tab-set > label:nth-child(2) { + margin-left: 0; +} + +/* Hovered label */ +.tab-set > label:hover { + color: var(--tabs--label-text--hover); + background: var(--tabs--label-background--hover); + border-color: var(--tabs--label-border--hover); +} + +/* Active tab label */ +.tab-set > input:checked + label { + color: var(--tabs--label-text--active); + background: var(--tabs--label-background--active); + border-color: var(--tabs--label-border--active); +} +.tab-set > input:checked + label:hover { + color: var(--tabs--label-text--active--hover); + background: var(--tabs--label-background--active--hover); + border-color: var(--tabs--label-border--active--hover); +} + +/* Tab content */ +.tab-content { + order: 99; + display: none; + width: 100%; + box-shadow: 0 -0.0625rem var(--tabs--border); +} + +/* Show content, when input is checked. */ +.tab-set > input:checked + label + .tab-content { + display: block; +} +.tab-content > p:first-child { + margin-top: 0.75rem; +} +/* Remove the top border on first code block */ +.tab-content > [class^="highlight-"]:first-child .highlight { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +/* Remove margins on children */ +.tab-content > *:first-child { + margin-top: 0; +} +.tab-content > *:last-child { + margin-bottom: 0; +} + +/* Remove margins on nested tabs */ +.tab-content > .tab-set { + margin: 0; +} diff --git a/_static/tabs.js b/_static/tabs.js new file mode 100644 index 000000000..58d2cdddd --- /dev/null +++ b/_static/tabs.js @@ -0,0 +1,30 @@ +var labels_by_text = {}; + +function ready() { + var li = document.getElementsByClassName("tab-label"); + const urlParams = new URLSearchParams(window.location.search); + const tabs = urlParams.getAll("tabs"); + + for (const label of li) { + label.onclick = onLabelClick; + const text = label.textContent; + if (!labels_by_text[text]) { + labels_by_text[text] = []; + } + labels_by_text[text].push(label); + } + + for (const tab of tabs) { + for (label of labels_by_text[tab]) { + label.previousSibling.checked = true; + } + } +} + +function onLabelClick() { + // Activate other labels with the same text. + for (label of labels_by_text[this.textContent]) { + label.previousSibling.checked = true; + } +} +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/genindex.html b/genindex.html new file mode 100644 index 000000000..22e80a75f --- /dev/null +++ b/genindex.html @@ -0,0 +1,966 @@ + + + + + + Index — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + | X + | Y + +
+

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + +
+ +

I

+ + +
+ +

J

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + +
+ +

V

+ + + +
+ +

W

+ + + +
+ +

X

+ + + +
+ +

Y

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.Curve.html b/geometry/gdstk.Curve.html new file mode 100644 index 000000000..ed2a99014 --- /dev/null +++ b/geometry/gdstk.Curve.html @@ -0,0 +1,664 @@ + + + + + + + gdstk.Curve — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Curve

+
+
+class gdstk.Curve(xy, tolerance=0.01)
+

Curve object for construction of complex polygons.

+

The methods are loosely based on the definition of SVG paths.

+
+
Parameters:
+
    +
  • xy – Curve starting point. It can be a sequence of 2 numbers or a +single complex value.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation of the curve.

  • +
+
+
+

Examples

+
>>> curve = gdstk.Curve((3, 4), tolerance=1e-3)
+>>> curve.segment((1, 1), True)
+>>> curve.turn(1, -numpy.pi / 2)
+>>> curve.segment((1, -1), True)
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/init.svg +

Methods

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

arc(radius, initial_angle, final_angle[, ...])

Append an elliptical arc to this curve.

bezier(xy[, relative])

Append a Bézier curve to this curve.

commands(*args)

Parse commands to append sections to this curve.

cubic(xy[, relative])

Append cubic Bézier curves to this curve.

cubic_smooth(xy[, relative])

Append smooth cubic Bézier curves to this curve.

horizontal(x[, relative])

Append horizontal segments to this curve.

interpolation(points[, angles, tension_in, ...])

Append a smooth interpolating curve through the given points.

parametric(curve_function[, relative])

Append a parametric curve to this curve.

points()

Return the polygonal approximation of this curve.

quadratic(xy[, relative])

Append quadratic Bézier curves to this curve.

quadratic_smooth(xy[, relative])

Append smooth quadratic Bézier curves to this curve.

segment(xy[, relative])

Append straight segments to this curve.

turn(radius, angle)

Append a circular turn to this curve.

vertical(y[, relative])

Append vertical segments to this curve.

+

Attributes

+ + + + + + +

tolerance

Tolerance used for calculating the polygonal approximation of the curve.

+
+
+arc(radius, initial_angle, final_angle, rotation=0) self
+

Append an elliptical arc to this curve.

+
+
Parameters:
+
    +
  • radius (number or sequence[2]) – Circular arc radius or elliptical +arc radii.

  • +
  • initial_angle – Starting angle (in radians).

  • +
  • final_angle – Ending angle (in radians).

  • +
  • rotation – Arc rotation.

  • +
+
+
+

Examples

+
>>> curve = gdstk.Curve((-0.6, 0), tolerance=1e-3)
+>>> curve.segment((1, 0), True)
+>>> curve.arc(1, 0, numpy.pi / 2)
+>>> polygon_1 = gdstk.Polygon(curve.points())
+
+
+
>>> curve = gdstk.Curve((0.6, 0), tolerance=1e-3)
+>>> curve.segment((1, 0), True)
+>>> curve.arc((2 ** -0.5, 0.4), -numpy.pi / 4, 3 * numpy.pi / 4,
+...           -numpy.pi / 4)
+>>> polygon_2 = gdstk.Polygon(curve.points())
+
+
+../_images/arc.svg +
+ +
+
+bezier(xy, relative=False) self
+

Append a Bézier curve to this curve.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Curve control points.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4),
+...           (0, 0)]
+>>> curve = gdstk.Curve((0, 0))
+>>> curve.segment(points)
+>>> control_poly = gdstk.Polygon(curve.points(), datatype=1)
+>>> curve = gdstk.Curve((0, 0), tolerance=1e-3)
+>>> curve.bezier(points)
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/bezier.svg +
+ +
+
+commands(*args) self
+

Parse commands to append sections to this curve.

+

Commands are single characters followed by a pre-defined number of +numerical arguments, according to the table below:

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

Command

Primitive

Arguments

L/l

Line segment

x, y

H/h

Horizontal segment

x

V/v

Vertical segment

y

C/c

Cubic Bézier

x0, y0, x1, y1, x2, y2

S/s

Smooth cubic Bézier

x0, y0, x1, y1

Q/q

Quadratic Bézier

x0, y0, x1, y1

T/t

Smooth quadratic Bézier

x, y

a

Circular turn

rad, ang

A

Circular arc

rad, ang0, ang1

E

Elliptical arc

rad0, rad1, ang0, ang1, rot

+

Uppercase commands assume that coordinates are absolute, whereas the +lowercase versions assume they are relative to the previous endpoint.

+
+

Notes

+

The meaning and order of the arguments of all commands are identical +to the corresponding method.

+
+

Examples

+
>>> curve = gdstk.Curve((0, 0), tolerance=1e-3)
+>>> curve.commands("l", 1, 1, "a", 1, -numpy.pi / 2, "l", 1, -1,
+...                "S", 1, -2, 0, -2)
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/commands.svg +
+ +
+
+cubic(xy, relative=False) self
+

Append cubic Bézier curves to this curve.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 3 consecutive points is +interpreted as 2 control points and an end point.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> curve = gdstk.Curve((0, 0), tolerance=1e-3)
+>>> curve.cubic([(1, -2), (2, -2), (3, 0)])
+>>> curve.cubic([(2.7, 1), (1.8, 1), (1.5, 0),
+...              (1.3, -0.2), (0.3, -0.2), (0, 0)])
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/cubic.svg +
+ +
+
+cubic_smooth(xy, relative=False) self
+

Append smooth cubic Bézier curves to this curve.

+

The first control point is assumed to be the reflection of the last +control point of this curve with respect to its end point.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 2 consecutive points is +interpreted as the second control point and an end point.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> curve = gdstk.Curve((0, 0), tolerance=1e-3)
+>>> curve.cubic([1 + 0j, 2.5 + 1.5j, 2 + 2j])
+>>> curve.cubic_smooth([1j, 0j])
+>>> polygon = gdstk.Polygon(curve.points())
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/cubic_smooth.svg +
+ +
+
+horizontal(x, relative=False) self
+

Append horizontal segments to this curve.

+
+
Parameters:
+
    +
  • x (number or sequence) – End point x coordinates.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+ +
+
+interpolation(points, angles=None, tension_in=1, tension_out=1, initial_curl=1, final_curl=1, cycle=False, relative=False) self
+

Append a smooth interpolating curve through the given points.

+

Use the Hobby algorithm [1] to calculate a smooth interpolating +curve made of cubic Bezier segments between each pair of points. Angle +and tension parameters can be specified at each point, and the curve can +be open or closed.

+
+
Parameters:
+
    +
  • points (sequence[N] of points) – Vertices in the interpolating curve.

  • +
  • angles (None or sequence[N + 1]) – Tangent angles at each point +(in radians). Angles defined as None are automatically +calculated.

  • +
  • tension_in (number or sequence[N + 1]) – Tension parameter when +arriving at each point. One value per point or a single value used +for all points.

  • +
  • tension_out (number or sequence[N + 1]) – Tension parameter when +leaving each point. One value per point or a single value used for +all points.

  • +
  • initial_curl – Ratio between the mock curvatures at the first point +and at its neighbor. A value of 1 renders the first segment a good +approximation for a circular arc. A value of 0 will better +approximate a straight segment. It has no effect for closed curves +or when an angle is defined for the first point.

  • +
  • final_curl – Ratio between the mock curvatures at the last point and +at its neighbor. It has no effect for closed curves or when an +angle is defined for the first point.

  • +
  • cycle – If True, calculates control points for a closed curve, +with an additional segment connecting the first and last points.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)]
+>>> curve = gdstk.Curve((0, 0))
+>>> curve.segment(points)
+>>> control_poly_1 = gdstk.Polygon(curve.points(), datatype=1)
+>>> curve = gdstk.Curve((0, 0), tolerance=1e-3)
+>>> curve.interpolation(points, cycle=True)
+>>> polygon_1 = gdstk.Polygon(curve.points())
+
+
+
>>> half_pi = numpy.pi / 2
+>>> angles = [half_pi, None, None, None, -half_pi, -half_pi, None]
+>>> curve = gdstk.Curve((4, -9))
+>>> curve.segment(points, relative=True)
+>>> control_poly_2 = gdstk.Polygon(curve.points(), datatype=1)
+>>> curve = gdstk.Curve((4, -9), tolerance=1e-3)
+>>> curve.interpolation(points, angles, cycle=True, relative=True)
+>>> polygon_2 = gdstk.Polygon(curve.points())
+
+
+../_images/interpolation.svg + +
+ +
+
+parametric(curve_function, relative=True) self
+

Append a parametric curve to this curve.

+
+
Parameters:
+
    +
  • curve_function (callable) – Function that defines the curve. Must be +a function of one argument (that varies from 0 to 1) that returns +a 2-element sequence or complex with the coordinates of the curve.

  • +
  • relative – If True, the return values of curve_function are +used as offsets from the current path position, i.e., to ensure a +continuous path, curve_function(0) must be (0, 0). Otherwise, +they are used as absolute coordinates.

  • +
+
+
+

Examples

+
>>> pi = numpy.pi
+>>> def top(u):
+...     x = 4 * u
+...     y = 1 - numpy.cos(4 * pi * u)
+...     return (x, y)
+...
+>>> curve = gdstk.Curve((-2, 0), tolerance=1e-3)
+>>> curve.parametric(top)
+>>> curve.parametric(
+...     lambda u: (4 - 2 * u ** 0.5) * numpy.exp(-1.5j * pi * u) - 4
+... )
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/parametric.svg +
+ +
+
+points() numpy.ndarray
+

Return the polygonal approximation of this curve.

+

Examples

+
>>> curve = gdstk.Curve((0, 0))
+>>> curve.segment([(1, 0), (0, 1)])
+>>> curve.points()
+array([[0., 0.],
+       [1., 0.],
+       [0., 1.]])
+
+
+
+ +
+
+quadratic(xy, relative=False) self
+

Append quadratic Bézier curves to this curve.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 2 consecutive points is +interpreted as control point and an end point.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

See also

+

gdstk.Curve.cubic()

+
+
+ +
+
+quadratic_smooth(xy, relative=False) self
+

Append smooth quadratic Bézier curves to this curve.

+

The control point is assumed to be the reflection of the last control +point of this curve with respect to its end point.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Curve end points.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+ +
+ +
+
+segment(xy, relative=False) self
+

Append straight segments to this curve.

+
+
Parameters:
+
    +
  • xy – Segment end point. It can be a sequence of 2 numbers or a single +complex. Multiple segments can be constructed by using a sequence +of points.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> curve = gdstk.Curve((1, 0))
+>>> curve.segment((0, 1))
+>>> curve.segment([0j, -1+0j])
+>>> curve.segment([(0, -1), (2, -1)], True)
+>>> polygon = gdstk.Polygon(curve.points())
+
+
+../_images/segment.svg +
+ +
+
+tolerance
+

Tolerance used for calculating the polygonal approximation of the curve.

+

Examples

+
>>> curve = gdstk.Curve((-2.5, 0), tolerance=1e-1)
+>>> curve.arc((2, 3), 0, numpy.pi)
+>>> polygon_1 = gdstk.Polygon(curve.points())
+>>> print(polygon_1.size)
+7
+>>> curve = gdstk.Curve((2.5, 0), tolerance=1e-3)
+>>> curve.arc((2, 3), 0, numpy.pi)
+>>> polygon_2 = gdstk.Polygon(curve.points())
+>>> print(polygon_2.size)
+62
+
+
+../_images/tolerance.svg +
+ +
+
+turn(radius, angle) self
+

Append a circular turn to this curve.

+
+
Parameters:
+
    +
  • radius – Circular arc radius.

  • +
  • angle – Turning angle. Positive values turn counter clockwise and +negative values, clockwise.

  • +
+
+
+
+ +
+
+vertical(y, relative=False) self
+

Append vertical segments to this curve.

+
+
Parameters:
+
    +
  • y (number or sequence) – End point y coordinates.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.FlexPath.html b/geometry/gdstk.FlexPath.html new file mode 100644 index 000000000..7f248ee0c --- /dev/null +++ b/geometry/gdstk.FlexPath.html @@ -0,0 +1,1446 @@ + + + + + + + gdstk.FlexPath — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.FlexPath

+
+
+class gdstk.FlexPath(points, width, offset=0, joins='natural', ends='flush', bend_radius=0, bend_function=None, tolerance=1e-2, simple_path=False, scale_width=True, layer=0, datatype=0)
+

Flexible path creation.

+

FlexPath can be used to create single and multiple parallel paths with +controlled widths and offsets. Joins and end caps can be customized +freely and, if desired, bends can be automatically created to join path +segments continuously.

+

Adjacent sections are expected to be joined smoothly when at least one +of them is curved. If that condition cannot be met, +gdstk.RobustPath should be used instead.

+
+
Parameters:
+
    +
  • points – Single point or sequence of points that make up the path. +Each point can be a pair of coordinates or a complex value.

  • +
  • width (number or sequence) – Width of the paths. If this is a +sequence, its length defines the number of paths created.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path.

  • +
  • joins – Definition for the joins. One of “natural”, “miter”, “bevel”, +“round”, “smooth”, or a callable. A callable must accept 6 +arguments (end point and direction vector for each edge adjacent +to the join, the center of the join, and the path width) and +return a sequence of points that define the join shape.

  • +
  • ends – Definition for the end caps. One of “flush”, “extended”, +“round”, “smooth”, a 2-tuple, or a callable. A 2-tuple defines the +extension length on both ends of the path. A callable must accept +4 arguments (cap end point and direction for both path sides) and +return a sequence of points that define the cap shape.

  • +
  • bend_radius (number or sequence) – If a positive number, path +segments are joined by a bend shape (defaults to a circular arc) +when possible.

  • +
  • bend_function (callable) – A callable that takes 4 arguments (radius, +initial and final angles, and the bend center) and returns a +sequence of points defining the bend shape.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation of the paths.

  • +
  • simple_path – If True, the paths will be stored as GDSII path +elements. They require less memory, but do not support “smooth” or +callable joins and end caps, or width changes along the path.

  • +
  • scale_width – If False, the path widths are not scaled when +transforming this path.

  • +
  • layer – layer number assigned to this path.

  • +
  • datatype – data type number assigned to this path.

  • +
+
+
+
+

Notes

+

If width is a number and offset a sequence, the number of +parallel paths is defined by the latter.

+

Arguments joins, ends, bend_radius, bend_function, +layer, and datatype can also be lists with one definition +for each path created.

+
+

Examples

+
>>> path = gdstk.FlexPath(
+...     [(0, 5), (0, 0), (5, 0), (15, 10), (15, -5)],
+...     [0.8, 0.8, 0.8, 0.8],
+...     1.0,
+...     joins=["natural", "bevel", "miter", "round"],
+...     ends=["flush", "extended", (0.4, 0.8), "round"],
+...     layer=[0, 1, 2, 3],
+... )
+
+
+../_images/init1.svg +
>>> points = [(0, 8), (0, 0), (8, 0), (18, 13), (18, -8)]
+>>> path_1 = gdstk.FlexPath(points , 1, datatype=1)
+>>> path_2 = gdstk.FlexPath(points , 1, bend_radius=3)
+
+
+../_images/init0.svg +
>>> def custom_broken_join(p0, v0, p1, v1, center, width):
+...     p0 = numpy.array(p0)
+...     v0 = numpy.array(v0)
+...     p1 = numpy.array(p1)
+...     v1 = numpy.array(v1)
+...     center = numpy.array(center)
+...     # Calculate intersection point p between lines defined by
+...     # p0 + u0 * v0 (for all u0) and p1 + u1 * v1 (for all u1)
+...     den = v1[1] * v0[0] - v1[0] * v0[1]
+...     lim = 1e-12 * ((v0[0] ** 2 + v0[1] ** 2) *
+...                    (v1[0] ** 2 + v1[1] ** 2))
+...     if den ** 2 < lim:
+...         # Lines are parallel: use mid-point
+...         u0 = u1 = 0
+...         p = 0.5 * (p0 + p1)
+...     else:
+...         dx = p1[0] - p0[0]
+...         dy = p1[1] - p0[1]
+...         u0 = (v1[1] * dx - v1[0] * dy) / den
+...         u1 = (v0[1] * dx - v0[0] * dy) / den
+...         p = 0.5 * (p0 + v0 * u0 + p1 + v1 * u1)
+...     if u0 <= 0 and u1 >= 0:
+...         # Inner corner
+...         return [p]
+...     # Outer corner
+...     return [p0, center, p1]
+>>> def custom_pointy_end(p0, v0, p1, v1):
+...     p0 = numpy.array(p0)
+...     v0 = numpy.array(v0)
+...     p1 = numpy.array(p1)
+...     v1 = numpy.array(v1)
+...     r = 0.5 * numpy.sqrt(numpy.sum((p0 - p1) ** 2))
+...     v0 /= numpy.sqrt(numpy.sum(v0 ** 2))
+...     v1 /= numpy.sqrt(numpy.sum(v1 ** 2))
+...     return [p0, 0.5 * (p0 + p1) + 0.5 * (v0 - v1) * r, p1]
+>>> path = gdstk.FlexPath(
+...     [(0, 5), (0, 0), (5, 0), (15, 10), (15, -5)],
+...     3,
+...     joins=custom_broken_join,
+...     ends=custom_pointy_end,
+... )
+
+
+../_images/init11.svg +

Methods

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

apply_repetition()

Create new flexpaths based on this object's repetition attribute.

arc(radius, initial_angle, final_angle[, ...])

Append an elliptical arc to this path.

bezier(xy[, width, offset, relative])

Append a Bézier curve to this path.

commands(path_commands...)

Append sections to this path according to commands.

copy()

Create a copy this flexpath.

cubic(xy[, width, offset, relative])

Append cubic Bézier curves to this path.

cubic_smooth(xy[, width, offset, relative])

Append smooth cubic Bézier curves to this path.

delete_gds_property(attr)

Delete a GDSII property of this element.

delete_property(name)

Delete the first property of this element matching a name.

get_gds_property(attr)

Return a GDSII property of this element.

get_property(name)

Return the values of the first property of this element matching a name.

horizontal(x[, width, offset, relative])

Append horizontal segments to this path.

interpolation(points[, angles, tension_in, ...])

Append a smooth interpolating curve through the given points.

mirror(p1[, p2])

Mirror this path across the line through p1 and p2.

offsets()

Offsets of all paths at every point.

parametric(path_function[, width, offset, ...])

Append a parametric curve to this path.

path_spines()

Central spines of each parallel path.

quadratic(xy[, width, offset, relative])

Append quadratic Bézier curves to this path.

quadratic_smooth(xy[, width, offset, relative])

Append smooth quadratic Bézier curves to this path.

rotate(angle[, center])

Rotate this path.

scale(s[, center])

Scale this path.

segment(xy[, width, offset, relative])

Append straight segments to this path.

set_bend_function(*functions)

Set the bend function for all paths.

set_bend_radius(*radii)

Set the bend radius for all paths.

set_datatypes(*datatypes)

Set the datatypes for all paths.

set_ends(*ends)

Set the end types for all paths.

set_gds_property(attr, value)

Set a GDSII property for this element.

set_joins(*joins)

Set the end types for all paths.

set_layers(*layers)

Set the layers for all paths.

set_property(name, value)

Set a property for this element.

spine()

Central path spine.

to_polygons()

Calculate the polygonal representations of this path.

translate(dx[, dy])

Translate this path.

turn(radius, angle[, width, offset])

Append a circular turn to this path.

vertical(y[, width, offset, relative])

Append vertical segments to this path.

widths()

Widths of all paths at every point.

+

Attributes

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

bend_function

Bend function for each path.

bend_radius

Bend radius for each path.

datatypes

FlexPath data type.

ends

End types for each path.

joins

Join types for each path.

layers

FlexPath layer.

num_paths

Number of paths.

properties

Properties of this element.

raith_data

Raith electron beam lithography data.

repetition

Repetition associated with this element.

scale_width

Scale width flag.

simple_path

Simple path flag.

size

Number of points in the path spine.

tolerance

Path tolerance.

+
+
+apply_repetition() list
+

Create new flexpaths based on this object’s repetition attribute.

+

After the repetition is applied, the original attribute is set to +None.

+
+
Returns:
+

Newly created objects.

+
+
+
+ +
+
+arc(radius, initial_angle, final_angle, rotation=0, width=None, offset=None) self
+

Append an elliptical arc to this path.

+
+
Parameters:
+
    +
  • radius (number or sequence[2]) – Circular arc radius or elliptical +arc radii.

  • +
  • initial_angle – Starting angle (in radians).

  • +
  • final_angle – Ending angle (in radians).

  • +
  • rotation – Arc rotation.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
+
+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), [0.2, 0.3], 0.4, tolerance=1e-3)
+>>> path.vertical(5)
+>>> path.arc(2.5, numpy.pi, 0)
+>>> path.arc(5, -numpy.pi, -numpy.pi / 2)
+
+
+../_images/arc1.svg +
+ +
+
+bend_function
+

Bend function for each path.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+bend_radius
+

Bend radius for each path.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+bezier(xy, width=None, offset=None, relative=False) self
+

Append a Bézier curve to this path.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Curve control points.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.bezier([(4, 1), (4, 3), (0, 5),
+...              (-4, 3), (-4, -2), (0, -4)])
+
+
+../_images/bezier1.svg +
+ +
+
+commands(path_commands...) self
+

Append sections to this path according to commands.

+

Commands are single characters followed by a pre-defined number of +numerical arguments, according to the table below:

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

Command

Primitive

Arguments

L/l

Line segment

x, y

H/h

Horizontal segment

x

V/v

Vertical segment

y

C/c

Cubic Bézier

x0, y0, x1, y1, x2, y2

S/s

Smooth cubic Bézier

x0, y0, x1, y1

Q/q

Quadratic Bézier

x0, y0, x1, y1

T/t

Smooth quadratic Bézier

x, y

a

Circular turn

rad, ang

A

Circular arc

rad, ang0, ang1

E

Elliptical arc

rad0, rad1, ang0, ang1, rot

+

Uppercase commands assume that coordinates are absolute, whereas the +lowercase versions assume they are relative to the previous endpoint.

+
+

Notes

+

The meaning and order of the arguments of all commands are identical +to the corresponding method.

+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), [0.2, 0.4, 0.2], 0.5,
+...                       tolerance=1e-3)
+>>> path.commands("l", 3, 4,
+...               "A", 2, numpy.arctan2(3, -4), numpy.pi / 2,
+...               "h", 0.5,
+...               "a", 3, -numpy.pi)
+
+
+../_images/commands1.svg +
+ +
+
+copy() gdstk.FlexPath
+

Create a copy this flexpath.

+
+
Returns:
+

Copy of this flexpath.

+
+
+
+ +
+
+cubic(xy, width=None, offset=None, relative=False) self
+

Append cubic Bézier curves to this path.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 3 consecutive points is +interpreted as 2 control points and an end point.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Changes in width and offset are split equally among curve parts +defined by xy.

+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.cubic([(0, 1), (1, 1), (1, 0)])
+>>> path.cubic([(1, -1), (2, -1), (2.5, -0.5),
+...             (3, 0), (3, 1), (2, 1)], width=0.5)
+
+
+../_images/cubic1.svg +
+ +
+
+cubic_smooth(xy, width=None, offset=None, relative=False) self
+

Append smooth cubic Bézier curves to this path.

+

The first control point is assumed to be the reflection of the last +control point of this path with respect to its end point.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 2 consecutive points is +interpreted as the second control points and an end point.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Changes in width and offset are split equally among curve parts +defined by xy.

+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.cubic([(0, 1), (1, 1), (1, 0)])
+>>> path.cubic_smooth([(2, -1), (2.5, -0.5), (3, 1), (2, 1)],
+...                   width=0.5)
+
+
+../_images/cubic_smooth1.svg +
+ +
+
+datatypes
+

FlexPath data type.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+delete_gds_property(attr) self
+

Delete a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+ends
+

End types for each path.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+get_gds_property(attr) str
+

Return a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
Returns:
+

Property value. If the property number does not exist, +None is returned.

+
+
Return type:
+

str or None

+
+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+horizontal(x, width=None, offset=None, relative=False) self
+

Append horizontal segments to this path.

+
+
Parameters:
+
    +
  • x (number or sequence) – End point x coordinates.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

If x is a sequence, changes in width and offset are split +equally among segments.

+
+

Examples

+
>>> path = gdstk.FlexPath([(0, 0)], 0.2)
+>>> path.horizontal(2, width=0.4, relative=True)
+>>> path.horizontal(2, offset=[0.4], relative=True)
+>>> path.horizontal(2, relative=True)
+>>> print(path.spine())
+... [[0. 0.]
+...  [2. 0.]
+...  [4. 0.]
+...  [6. 0.]]
+
+
+../_images/horizontal.svg + +
+ +
+
+interpolation(points, angles=None, tension_in=1, tension_out=1, initial_curl=1, final_curl=1, cycle=False, width=None, offset=None, relative=True) self
+

Append a smooth interpolating curve through the given points.

+

Use the Hobby algorithm [1] to calculate a smooth interpolating +path made of cubic Bézier segments between each pair of points. Angle +and tension parameters can be specified at each point, and the path can +be open or closed.

+
+
Parameters:
+
    +
  • points (sequence[N] of points) – Vertices in the interpolating path.

  • +
  • angles (None or sequence[N + 1]) – Tangent angles at each point +(in radians). Angles defined as None are automatically +calculated.

  • +
  • tension_in (number or sequence[N + 1]) – Tension parameter when +arriving at each point. One value per point or a single value used +for all points.

  • +
  • tension_out (number or sequence[N + 1]) – Tension parameter when +leaving each point. One value per point or a single value used for +all points.

  • +
  • initial_curl – Ratio between the mock curvatures at the first point +and at its neighbor. A value of 1 renders the first segment a good +approximation for a circular arc. A value of 0 will better +approximate a straight segment. It has no effect for closed paths +or when an angle is defined for the first point.

  • +
  • final_curl – Ratio between the mock curvatures at the last point and +at its neighbor. It has no effect for closed paths or when an +angle is defined for the first point.

  • +
  • cycle – If True, calculates control points for a closed path, +with an additional segment connecting the first and last points.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> half_pi = numpy.pi / 2
+>>> points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)]
+>>> angles = [half_pi, None, None, None, -half_pi, -half_pi, None]
+>>> path_1 = gdstk.FlexPath((0, 0), 0.2, tolerance=1e-3)
+>>> path_1.interpolation(points, cycle=True)
+>>> path_2 = gdstk.FlexPath((6, -8), 0.2, tolerance=1e-3)
+>>> path_2.interpolation(points, angles, cycle=True, relative=True)
+
+
+../_images/interpolation1.svg + +
+ +
+
+joins
+

Join types for each path.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+layers
+

FlexPath layer.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+mirror(p1, p2=(0, 0)) self
+

Mirror this path across the line through p1 and p2.

+
+
Parameters:
+
    +
  • p1 (coordinate pair or complex) – First point in the mirror line.

  • +
  • p2 (coordinate pair or complex) – Second point in the mirror line.

  • +
+
+
+
+ +
+
+num_paths
+

Number of paths.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+offsets() numpy.ndarray
+

Offsets of all paths at every point.

+
+
Returns:
+

The offsets of each path at each point.

+
+
+
+ +
+
+parametric(path_function, width=None, offset=None, relative=True) self
+

Append a parametric curve to this path.

+
+
Parameters:
+
    +
  • path_function (callable) – Function that defines the path. Must be a +function of one argument (that varies from 0 to 1) that returns a +2-element sequence or complex with the coordinates of the path.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, the return values of path_function are +used as offsets from the current path position, i.e., to ensure a +continuous path, path_function(0) must be (0, 0). Otherwise, +they are used as absolute coordinates.

  • +
+
+
+

Examples

+
>>> def spiral(u):
+...     rad = 2 * u ** 0.5
+...     ang = 3 * numpy.pi * u
+...     return (rad * numpy.cos(ang), rad * numpy.sin(ang))
+>>> path = gdstk.FlexPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.parametric(spiral)
+
+
+../_images/parametric1.svg +
+ +
+
+path_spines() list
+

Central spines of each parallel path.

+
+
Returns:
+

Copy of the points that make up each parallel path.

+
+
+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+quadratic(xy, width=None, offset=None, relative=False) self
+

Append quadratic Bézier curves to this path.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Each set of 2 consecutive points is +interpreted as control point and an end point.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Changes in width and offset are split equally among curve parts +defined by xy.

+
+ +
+ +
+
+quadratic_smooth(xy, width=None, offset=None, relative=False) self
+

Append smooth quadratic Bézier curves to this path.

+

The control point is assumed to be the reflection of the last control +point of this curve with respect to its end point.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Curve end points.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Changes in width and offset are split equally among curve parts +defined by xy.

+
+ +
+ +
+
+raith_data
+

Raith electron beam lithography data.

+
+ +
+
+repetition
+

Repetition associated with this element.

+
+ +
+
+rotate(angle, center=(0, 0)) self
+

Rotate this path.

+
+
Parameters:
+
    +
  • angle – Rotation angle (in radians).

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+scale(s, center=(0, 0)) self
+

Scale this path.

+
+
Parameters:
+
    +
  • s – Scaling factor.

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+scale_width
+

Scale width flag.

+
+ +
+
+segment(xy, width=None, offset=None, relative=False) self
+

Append straight segments to this path.

+
+
Parameters:
+
    +
  • xy – Segment end point or sequence of end points. Each point can be a +pair of coordinates or a complex value.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

If xy is a sequence, changes in width and offset are split +equally among segments.

+
+

Examples

+
>>> points = [(1, 0), (1, 1), (-1, 1), (-1, -1), (1, -1)]
+>>> path_1 = gdstk.FlexPath((0, 0), 0.2)
+>>> path_1.segment(points, 0.6)
+>>> path_2 = gdstk.FlexPath((3, 0), [0.1, 0.1], 0.2)
+>>> path_2.segment(points, offset=0.6, relative=True)
+
+
+../_images/segment1.svg +
+ +
+
+set_bend_function(*functions) self
+

Set the bend function for all paths.

+
+
Parameters:
+

functions – Sequence of callable or None.

+
+
+
+

See also

+

gdstk.FlexPath

+
+
+ +
+
+set_bend_radius(*radii) self
+

Set the bend radius for all paths.

+
+
Parameters:
+

radii – Sequence of floats.

+
+
+
+

See also

+

gdstk.FlexPath

+
+
+ +
+
+set_datatypes(*datatypes) self
+

Set the datatypes for all paths.

+
+
Parameters:
+

datatypes – data type numbers for all paths.

+
+
+
+ +
+
+set_ends(*ends) self
+

Set the end types for all paths.

+
+
Parameters:
+

ends – Sequence of “flush”, “extended”, “round”, “smooth”, a 2-tuple, +or a callable.

+
+
+
+

See also

+

gdstk.FlexPath

+
+
+ +
+
+set_gds_property(attr, value) self
+

Set a GDSII property for this element.

+

GDSII properties are stored under the special name “S_GDS_PROPERTY”, as +defined by the OASIS specification.

+
+
Parameters:
+
    +
  • attr (number) – Property number.

  • +
  • value (str) – Property value.

  • +
+
+
+
+ +
+
+set_joins(*joins) self
+

Set the end types for all paths.

+
+
Parameters:
+

joins – Sequence of “natural”, “miter”, “bevel”, “round”, “smooth”, +or a callable.

+
+
+
+

See also

+

gdstk.FlexPath

+
+
+ +
+
+set_layers(*layers) self
+

Set the layers for all paths.

+
+
Parameters:
+

layers – layer numbers for all paths.

+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+simple_path
+

Simple path flag.

+
+ +
+
+size
+

Number of points in the path spine.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+spine() numpy.ndarray
+

Central path spine.

+
+
Returns:
+

Copy of the points that make up the path at zero offset.

+
+
+
+ +
+
+to_polygons() list
+

Calculate the polygonal representations of this path.

+
+
Returns:
+

The polygonal contours defined by this path.

+
+
+
+ +
+
+tolerance
+

Path tolerance.

+
+ +
+
+translate(dx, dy=None) self
+

Translate this path.

+
+
Parameters:
+
    +
  • dx – Translation in the x coordinate or translation vector.

  • +
  • dy – Translation in the y coordinate.

  • +
+
+
+
+ +
+
+turn(radius, angle, width=None, offset=None) self
+

Append a circular turn to this path.

+
+
Parameters:
+
    +
  • radius – Circular arc radius.

  • +
  • angle – Turning angle. Positive values turn counter clockwise and +negative values, clockwise.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
+
+
+
+ +
+
+vertical(y, width=None, offset=None, relative=False) self
+

Append vertical segments to this path.

+
+
Parameters:
+
    +
  • y (number or sequence) – End point y coordinates.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

If y is a sequence, changes in width and offset are split +equally among segments.

+
+ +
+ +
+
+widths() numpy.ndarray
+

Widths of all paths at every point.

+
+
Returns:
+

The widths of each path at each point.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.Polygon.html b/geometry/gdstk.Polygon.html new file mode 100644 index 000000000..6253580b2 --- /dev/null +++ b/geometry/gdstk.Polygon.html @@ -0,0 +1,696 @@ + + + + + + + gdstk.Polygon — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Polygon

+
+
+class gdstk.Polygon(points, layer=0, datatype=0)
+

Polygonal geometric object.

+
+
Parameters:
+
    +
  • points (sequence) – Vertices of the polygon. Each element can be a +pair of coordinates or a complex value.

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+

Examples

+
>>> polygon_1 = gdstk.Polygon([(0, 0), (1, 0), 1 + 1.5j, 1j])
+>>> polygon_2 = gdstk.Polygon([0j, (-1, 1), (-1, 0)], 2, 3)
+
+
+../_images/init2.svg +

Methods

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

apply_repetition()

Create new polygons based on this object's repetition attribute.

area()

Polygon area.

bounding_box()

Calculate the polygon bounding box.

contain(*points)

Check whether points are inside this polygon.

contain_all(*points)

Check whether all points are inside this polygon.

contain_any(*points)

Check whether any of the points are inside this polygon.

copy()

Create a copy this polygon.

delete_gds_property(attr)

Delete a GDSII property of this element.

delete_property(name)

Delete the first property of this element matching a name.

fillet(radius[, tolerance])

Fillet the corners of this polygon.

fracture([max_points, precision])

Fracture this polygon into a list of polygons.

get_gds_property(attr)

Return a GDSII property of this element.

get_property(name)

Return the values of the first property of this element matching a name.

mirror(p1[, p2])

Mirror this polygon across the line through p1 and p2.

perimeter()

Polygon perimeter.

rotate(angle[, center])

Rotate this polygon.

scale(sx[, sy, center])

Scale this polygon.

set_gds_property(attr, value)

Set a GDSII property for this element.

set_property(name, value)

Set a property for this element.

transform([magnification, x_reflection, ...])

Transform the vertices of this polygon.

translate(dx[, dy])

Translate this polygon.

+

Attributes

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

datatype

Polygon data type.

layer

Polygon layer.

points

Vertices of the polygon.

properties

Properties of this element.

repetition

Repetition associated with this element.

size

Number of vertices in this polygon.

+
+
+apply_repetition() list
+

Create new polygons based on this object’s repetition attribute.

+

After the repetition is applied, the original attribute is set to +None.

+
+
Returns:
+

Newly created objects.

+
+
+
+ +
+
+area() float
+

Polygon area.

+
+
Returns:
+

Area of the polygon.

+
+
+
+ +
+
+bounding_box() tuple
+

Calculate the polygon bounding box.

+
+
Returns:
+

The lower-left and upper-right corners of the bounding box of the +polygon: ((min_x, min_y), (max_x, max_y)).

+
+
+

Examples

+
>>> polygon = gdstk.Polygon([(0, 1), (1, 2), (3, -1)])
+>>> bbox = polygon.bounding_box()
+>>> print(bbox)
+((0.0, -1.0), (3.0, 2.0))
+>>> polygon_bb = gdstk.rectangle(*bbox, datatype=1)
+
+
+../_images/bounding_box.svg +
+ +
+
+contain(*points) bool, tuple
+

Check whether points are inside this polygon.

+

Points on the polygon edges or coinciding with any of its vertices are +considered inside.

+
+
Parameters:
+

points (point or sequence of points) – Points to check. Arguments +can be a pair of coordinates, a complex number, or a sequence of +those.

+
+
Returns:
+

If the argument is a single point, returns a boolean. In the case of +a sequence, a tuple of booleans (one for each point) is returned.

+
+
+
+ +
+
+contain_all(*points) bool
+

Check whether all points are inside this polygon.

+

Points on the polygon edges or coinciding with any of its vertices are +considered inside.

+
+
Parameters:
+

points – Points to check. Each point can be a pair of coordinates or +a complex number.

+
+
Returns:
+

True if all points are inside the polygon, False otherwise.

+
+
+
+ +
+
+contain_any(*points) bool
+

Check whether any of the points are inside this polygon.

+

Points on the polygon edges or coinciding with any of its vertices are +considered inside.

+
+
Parameters:
+

points – Points to check. Each point can be a pair of coordinates or +a complex number.

+
+
Returns:
+

True if any of the points are inside the polygon, False +otherwise.

+
+
+
+ +
+
+copy() gdstk.Polygon
+

Create a copy this polygon.

+
+
Returns:
+

Copy of this polygon.

+
+
+
+ +
+
+datatype
+

Polygon data type.

+
+ +
+
+delete_gds_property(attr) self
+

Delete a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+fillet(radius, tolerance=0.01) self
+

Fillet the corners of this polygon.

+
+
Parameters:
+
    +
  • radius (number or sequence) – Fillet radius. A sequence of values can +be used to define the fillet radius for each vertex.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation of the filleted corners.

  • +
+
+
+
+

Notes

+

The actual fillet radius for a given corner is the specified value +or half the length of the shortest segment adjacent to that corner, +whichever is smaller.

+
+

Examples

+
>>> points = [(0, 0), (1.2, 0), (1.2, 0.3), (1, 0.3), (1.5, 1),
+...           (0, 1.5)]
+>>> polygon_1 = gdstk.Polygon(points, datatype=1)
+>>> polygon_2 = gdstk.Polygon(points).fillet(0.3, tolerance=1e-3)
+
+
+../_images/fillet.svg +
+ +
+
+fracture(max_points=199, precision=1e-3) list
+

Fracture this polygon into a list of polygons.

+
+
Parameters:
+
    +
  • max_points – Maximal number of vertices for each resulting polygon. +Official GDSII documentation requires that all polygons have at +most 199 vertices, but 8190 is usually supported by most software.

  • +
  • precision – Desired vertex precision for fracturing.

  • +
+
+
Returns:
+

List of fractured polygons.

+
+
+
+

Notes

+

If max_points < 5 the return value is an empty list.

+
+

Examples

+
>>> polygon = gdstk.racetrack((0, 0), 30, 60, 40, tolerance=1e-3)
+>>> poly_list = polygon.fracture()
+>>> print(len(poly_list))
+10
+>>> print([p.size for p in poly_list])
+[102, 103, 103, 101, 101, 102, 102, 103, 103, 102]
+
+
+../_images/fracture.svg +
+ +
+
+get_gds_property(attr) str
+

Return a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
Returns:
+

Property value. If the property number does not exist, +None is returned.

+
+
Return type:
+

str or None

+
+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+layer
+

Polygon layer.

+
+ +
+
+mirror(p1, p2=(0, 0)) self
+

Mirror this polygon across the line through p1 and p2.

+
+
Parameters:
+
    +
  • p1 (coordinate pair or complex) – First point in the mirror line.

  • +
  • p2 (coordinate pair or complex) – Second point in the mirror line.

  • +
+
+
+
+ +
+
+perimeter() float
+

Polygon perimeter.

+
+
Returns:
+

Perimeter of the polygon.

+
+
+
+ +
+
+points
+

Vertices of the polygon.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+repetition
+

Repetition associated with this element.

+
+ +
+
+rotate(angle, center=(0, 0)) self
+

Rotate this polygon.

+
+
Parameters:
+
    +
  • angle – Rotation angle (in radians).

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+scale(sx, sy=0, center=(0, 0)) self
+

Scale this polygon.

+
+
Parameters:
+
    +
  • sx – Scaling in the x direction.

  • +
  • sy – Scaling in the y direction. If set to 0, sx is used instead.

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+set_gds_property(attr, value) self
+

Set a GDSII property for this element.

+

GDSII properties are stored under the special name “S_GDS_PROPERTY”, as +defined by the OASIS specification.

+
+
Parameters:
+
    +
  • attr (number) – Property number.

  • +
  • value (str) – Property value.

  • +
+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+size
+

Number of vertices in this polygon.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+transform(magnification=1, x_reflection=False, rotation=0, translation=None, matrix=None) self
+

Transform the vertices of this polygon.

+

The transformation if applied in the order of the arguments in the +method signature, starting with a magnification. If a transformation +matrix is given, it is applied after the other transforms.

+
+
Parameters:
+
    +
  • magnification (number) – Magnification factor.

  • +
  • x_reflection (bool) – If True, the vertices are reflected across +the x axis.

  • +
  • rotation (number) – Rotation angle (in radians).

  • +
  • translation (coordinate pair or complex) – Translation vector.

  • +
  • matrix (matrix-like) – Transformation matrix with 2 or 3 rows and 2 +or 3 columns.

  • +
+
+
+
+

Notes

+

If the number of rows or columns of the transformation matrix is 3, +homogeneous coordinates are used.

+
+
+ +
+
+translate(dx, dy=None) self
+

Translate this polygon.

+
+
Parameters:
+
    +
  • dx – Translation in the x coordinate or translation vector.

  • +
  • dy – Translation in the y coordinate.

  • +
+
+
+
+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.Repetition.html b/geometry/gdstk.Repetition.html new file mode 100644 index 000000000..708108eaa --- /dev/null +++ b/geometry/gdstk.Repetition.html @@ -0,0 +1,316 @@ + + + + + + + gdstk.Repetition — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Repetition

+
+
+class gdstk.Repetition(columns=None, rows=None, spacing=None, v1=None, v2=None, offsets=None, x_offsets=None, y_offsets=None)
+

Repetition object that creates multiple identical elements.

+

A repetition can be set in any polygon, path, label or reference to +indicate that the element should be copied to multiple positions. +Repetitions can be of 5 different types, depending on which arguments +are set:

+
    +
  • Rectangular: requires columns, rows and spacing. Creates a +rectangular array of copies.

  • +
  • Regular: requires columns, rows, v1 and v2. Creates an array +of copies along the specified direction vectors.

  • +
  • Explicit: requires offsets. Creates copies at the specified position +offsets. The original element at offset (0, 0) is always present, so +it should not be specified in the offsets array.

  • +
  • X-explicit: requires x-offsets. Creates a linear array of copies +at the given x coordinates. Coordinate 0 is always included, so it +should not be specified.

  • +
  • Y-explicit: requires y-offsets. Creates a linear array of copies +at the given y coordinates. Coordinate 0 is always included, so it +should not be specified.

  • +
+
+
Parameters:
+
    +
  • columns (int) – Number of copies in the x direction (rectangular) or +along v1 (regular).

  • +
  • rows (int) – Number of copies in the y direction (rectangular) or +along v2 (regular).

  • +
  • spacing (coordinate pair or complex) – Step sizes in x and y +directions for rectangular array.

  • +
  • v1 (coordinate pair or complex) – First vector defining the shape of +a regular array.

  • +
  • v2 (coordinate pair or complex) – Second vector defining the shape of +a regular array.

  • +
  • offsets (sequence of points) – Explicit offsets for copies.

  • +
  • x_offsets (sequence of numbers) – Explicit x coordinates for copies.

  • +
  • y_offsets (sequence of numbers) – Explicit y coordinates for copies.

  • +
+
+
+

Examples

+
>>> ref_array = gdstk.Reference("Some Cell")
+>>> # Create an array of 3 by 2 references:
+>>> ref_array.repetition = gdstk.Repetition(
+...     offsets=[(10, 10), (20, 0), (10, -10)]
+... )
+
+
+
+

Notes

+

All attributes of Repetition objects are read-only.

+
+

Methods

+ + + + + + +

get_offsets()

Calculate all offsets generated by this repetition.

+

Attributes

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

columns

Number of columns in a rectangular or regular array.

offsets

Offsets for an explicit array.

rows

Number of rows in a rectangular or regular array.

size

Number of offsets generated by this repetition.

spacing

Spacing in a rectangular array.

v1

First vector defining a regular array.

v2

Second vector defining a regular array.

x_offsets

X coordinates for an x-explicit array.

y_offsets

Y coordinates for a y-explicit array.

+
+
+columns
+

Number of columns in a rectangular or regular array.

+
+ +
+
+get_offsets() numpy.ndarray
+

Calculate all offsets generated by this repetition.

+
+
Returns:
+

Offsets generated by this repetition.

+
+
+
+ +
+
+offsets
+

Offsets for an explicit array.

+
+ +
+
+rows
+

Number of rows in a rectangular or regular array.

+
+ +
+
+size
+

Number of offsets generated by this repetition.

+
+ +
+
+spacing
+

Spacing in a rectangular array.

+
+ +
+
+v1
+

First vector defining a regular array.

+
+ +
+
+v2
+

Second vector defining a regular array.

+
+ +
+
+x_offsets
+

X coordinates for an x-explicit array.

+
+ +
+
+y_offsets
+

Y coordinates for a y-explicit array.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.RobustPath.html b/geometry/gdstk.RobustPath.html new file mode 100644 index 000000000..c8071c47c --- /dev/null +++ b/geometry/gdstk.RobustPath.html @@ -0,0 +1,1400 @@ + + + + + + + gdstk.RobustPath — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.RobustPath

+
+
+class gdstk.RobustPath(initial_point, width, offset=0, ends='flush', tolerance=1e-2, max_evals=1000, simple_path=False, scale_width=True, layer=0, datatype=0)
+

Robust path creation.

+

RobusPath can be used to create single and multiple parallel paths with +parametrized widths and offsets. End caps can be customized freely. +Intersections between adjacent sections are numerically determined so +that curved sections do not need to be joined smoothly.

+
+
Parameters:
+
    +
  • initial_point (coordinate pair or complex) – Starting point of the +path.

  • +
  • width (number or sequence) – Width of the paths. If this is a +sequence, its length defines the number of paths created.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path.

  • +
  • ends – Definition for the end caps. One of “flush”, “extended”, +“round”, “smooth”, a 2-tuple, or a callable. A 2-tuple defines the +extension length on both ends of the path. A callable must accept +4 arguments (cap end point and direction for both path sides) and +return a sequence of points that define the cap shape.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation of the paths.

  • +
  • max_evals – Maximal number of path evaluations per section. Used for +intersection finding at joins and to create the polygonal +approximation for each section.

  • +
  • simple_path – If True, the paths will be stored as GDSII path +elements. They require less memory, but do not support “smooth” or +callable joins and end caps, or width changes along the path.

  • +
  • scale_width – If False, the path widths are not scaled when +transforming this path.

  • +
  • layer – layer number assigned to this path.

  • +
  • datatype – data type number assigned to this path.

  • +
+
+
+
+

Notes

+

If width is a number and offset a sequence, the number of +parallel paths is defined by the latter.

+

Arguments ends, layer, and datatype can also be lists +with one definition for each path created.

+
+

Examples

+
>>> fpath = gdstk.FlexPath((0, 0), 0.5, tolerance=1e-3)
+>>> fpath.arc(1, 0, numpy.pi/2)
+>>> fpath.arc(1, 0, -numpy.pi/2)
+>>> rpath = gdstk.RobustPath((3, 0), 0.5, tolerance=1e-3)
+>>> rpath.arc(1, 0, numpy.pi/2)
+>>> rpath.arc(1, 0, -numpy.pi/2)
+
+
+../_images/init3.svg +
>>> path = gdstk.RobustPath((0, 0),
+...     [0.8, 0.8, 0.8, 0.8],
+...     1.0,
+...     ends=["flush", "extended", (0.4, 0.8), "round"],
+...     tolerance=1e-3,
+...     layer=[0, 1, 2, 3],
+... )
+>>> path.horizontal(5)
+
+
+../_images/init12.svg +

Methods

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

apply_repetition()

Create new robustpaths based on this object's repetition attribute.

arc(radius, initial_angle, final_angle[, ...])

Append an elliptical arc to this path.

bezier(xy[, width, offset, relative])

Append a Bézier curve to this path.

commands(path_commands...)

Append sections to this path according to commands.

copy()

Create a copy this robustpath.

cubic(xy[, width, offset, relative])

Append a cubic Bézier curve to this path.

cubic_smooth(xy[, width, offset, relative])

Append a smooth cubic Bézier curve to this path.

delete_gds_property(attr)

Delete a GDSII property of this element.

delete_property(name)

Delete the first property of this element matching a name.

get_gds_property(attr)

Return a GDSII property of this element.

get_property(name)

Return the values of the first property of this element matching a name.

gradient(u[, from_below])

Calculate the gradient of this path.

horizontal(x[, width, offset, relative])

Append a horizontal segment to this path.

interpolation(points[, angles, tension_in, ...])

Append a smooth interpolating curve through the given points.

mirror(p1[, p2])

Mirror this path across the line through p1 and p2.

offsets(u[, from_below])

Calculate the offset of this path.

parametric(path_function[, path_gradient, ...])

Append a parametric curve to this path.

path_spines()

Central spines of each parallel path.

position(u[, from_below])

Calculate the position of this path.

quadratic(xy[, width, offset, relative])

Append a quadratic Bézier curve to this path.

quadratic_smooth(xy[, width, offset, relative])

Append a smooth quadratic Bézier curve to this path.

rotate(angle[, center])

Rotate this path.

scale(s[, center])

Scale this path.

segment(xy[, width, offset, relative])

Append a straight segment to this path.

set_datatypes(*datatypes)

Set the datatypes for all paths.

set_ends(*ends)

Set the end types for all paths.

set_gds_property(attr, value)

Set a GDSII property for this element.

set_layers(*layers)

Set the layers for all paths.

set_property(name, value)

Set a property for this element.

spine()

Central path spine.

to_polygons()

Calculate the polygonal representations of this path.

translate(dx[, dy])

Translate this path.

turn(radius, angle[, width, offset])

Append a circular turn to this path.

vertical(y[, width, offset, relative])

Append a vertical segment to this path.

widths(u[, from_below])

Calculate the width of this path.

+

Attributes

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

datatypes

RobustPath data type.

ends

End types for each path.

layers

RobustPath layer.

max_evals

Maximal number of path evaluations per section.

num_paths

Number of paths.

properties

Properties of this element.

repetition

Repetition associated with this element.

scale_width

Scale width flag.

simple_path

Simple path flag.

size

Number of sections in this path.

tolerance

Path tolerance.

+
+
+apply_repetition() list
+

Create new robustpaths based on this object’s repetition attribute.

+

After the repetition is applied, the original attribute is set to +None.

+
+
Returns:
+

Newly created objects.

+
+
+
+ +
+
+arc(radius, initial_angle, final_angle, rotation=0, width=None, offset=None) self
+

Append an elliptical arc to this path.

+
+
Parameters:
+
    +
  • radius (number or sequence[2]) – Circular arc radius or elliptical +arc radii.

  • +
  • initial_angle – Starting angle (in radians).

  • +
  • final_angle – Ending angle (in radians).

  • +
  • rotation – Arc rotation.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
+
+
+

Examples

+
>>> path = gdstk.FlexPath((0, 0), [0.2, 0.3], 0.4, tolerance=1e-3)
+>>> path.vertical(5)
+>>> path.arc(2.5, numpy.pi, 0)
+>>> path.arc((3, 5), -numpy.pi, -numpy.pi / 2)
+
+
+../_images/arc2.svg +
+ +
+
+bezier(xy, width=None, offset=None, relative=False) self
+

Append a Bézier curve to this path.

+
+
Parameters:
+
    +
  • xy (sequence of points) – Control points for the Bézier. Each point +can be a coordinate pair or a complex.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+

Examples

+
>>> path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.bezier(
+...     [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)],
+...     width=lambda u: 0.2 + 0.8 * u ** 2,
+... )
+
+
+../_images/bezier2.svg + +
+ +
+
+commands(path_commands...) self
+

Append sections to this path according to commands.

+

Commands are single characters followed by a pre-defined number of +numerical arguments, according to the table below:

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

Command

Primitive

Arguments

L/l

Line segment

x, y

H/h

Horizontal segment

x

V/v

Vertical segment

y

C/c

Cubic Bézier

x0, y0, x1, y1, x2, y2

S/s

Smooth cubic Bézier

x0, y0, x1, y1

Q/q

Quadratic Bézier

x0, y0, x1, y1

T/t

Smooth quadratic Bézier

x, y

a

Circular turn

rad, ang

A

Circular arc

rad, ang0, ang1

E

Elliptical arc

rad0, rad1, ang0, ang1, rot

+

Uppercase commands assume that coordinates are absolute, whereas the +lowercase versions assume they are relative to the previous endpoint.

+
+

Notes

+

The meaning and order of the arguments of all commands are identical +to the corresponding method.

+
+

Examples

+
>>> path = gdstk.RobustPath((0, 0), [0.2, 0.4, 0.2], 0.5,
+...                         tolerance=1e-3)
+>>> path.commands("l", 3, 4,
+...               "A", 2, numpy.arctan2(3, -4), numpy.pi / 2,
+...               "h", 0.5,
+...               "a", 3, -numpy.pi)
+
+
+../_images/commands2.svg +
+ +
+
+copy() gdstk.RobustPath
+

Create a copy this robustpath.

+
+
Returns:
+

Copy of this robustpath.

+
+
+
+ +
+
+cubic(xy, width=None, offset=None, relative=False) self
+

Append a cubic Bézier curve to this path.

+
+
Parameters:
+
    +
  • xy (sequence of 3 points) – Control points and end point for the +Bézier. Each point can be a coordinate pair or a complex.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+

Examples

+
>>> path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.cubic([(0.5, 0.8), (0.5, 2.2), (0, 3)])
+>>> path.cubic([(0.8, -0.5), (2.2, -0.5), (3, 0)], relative=True)
+>>> path.cubic([(-0.5, -0.8), (-0.5, -2.2), (0, -3)], relative=True)
+
+
+../_images/cubic2.svg + +
+ +
+
+cubic_smooth(xy, width=None, offset=None, relative=False) self
+

Append a smooth cubic Bézier curve to this path.

+

The first control point of the Bézier is such that the gradient of the +path is continuous.

+
+
Parameters:
+
    +
  • xy (sequence of 2 points) – Second control point and end point for +the Bézier. Each can be a coordinate pair or a complex.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+

Examples

+
>>> path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.cubic([(0.5, 0.8), (0.5, 2.2), (0, 3)])
+>>> path.cubic_smooth([(3.5, 0.8), (3, 0)], relative=True)
+>>> path.cubic_smooth([(-0.5, -2.2), (0, -3)], relative=True)
+
+
+../_images/cubic_smooth2.svg + +
+ +
+
+datatypes
+

RobustPath data type.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+delete_gds_property(attr) self
+

Delete a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+ends
+

End types for each path.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+get_gds_property(attr) str
+

Return a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
Returns:
+

Property value. If the property number does not exist, +None is returned.

+
+
Return type:
+

str or None

+
+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+gradient(u, from_below=True) numpy.ndarray
+

Calculate the gradient of this path.

+
+
Parameters:
+
    +
  • u (number) – Where in the path to calculate the position. The value +must be in the range 0 thru gdstk.RobustPath.size, +inclusive.

  • +
  • from_below – If there is a discontinuity at u, use the value +approaching from below.

  • +
+
+
Returns:
+

The spine gradient of the path at u.

+
+
+
+ +
+
+horizontal(x, width=None, offset=None, relative=False) self
+

Append a horizontal segment to this path.

+
+
Parameters:
+
    +
  • x (number) – End point x coordinate.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+ +
+ +
+
+interpolation(points, angles=None, tension_in=1, tension_out=1, initial_curl=1, final_curl=1, cycle=False, width=None, offset=None, relative=True) self
+

Append a smooth interpolating curve through the given points.

+

Use the Hobby algorithm [1] to calculate a smooth interpolating +path made of cubic Bezier segments between each pair of points. Angle +and tension parameters can be specified at each point, and the path can +be open or closed.

+
+
Parameters:
+
    +
  • points (sequence[N] of points) – Vertices in the interpolating path.

  • +
  • angles (None or sequence[N + 1]) – Tangent angles at each point +(in radians). Angles defined as None are automatically +calculated.

  • +
  • tension_in (number or sequence[N + 1]) – Tension parameter when +arriving at each point. One value per point or a single value used +for all points.

  • +
  • tension_out (number or sequence[N + 1]) – Tension parameter when +leaving each point. One value per point or a single value used for +all points.

  • +
  • initial_curl – Ratio between the mock curvatures at the first point +and at its neighbor. A value of 1 renders the first segment a good +approximation for a circular arc. A value of 0 will better +approximate a straight segment. It has no effect for closed paths +or when an angle is defined for the first point.

  • +
  • final_curl – Ratio between the mock curvatures at the last point and +at its neighbor. It has no effect for closed paths or when an +angle is defined for the first point.

  • +
  • cycle – If True, calculates control points for a closed path, +with an additional segment connecting the first and last points.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+

Examples

+
>>> half_pi = numpy.pi / 2
+>>> points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)]
+>>> angles = [half_pi, None, None, None, -half_pi, -half_pi, None]
+>>> path_1 = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path_1.interpolation(points, cycle=True)
+>>> path_2 = gdstk.RobustPath((6, -8), 0.2, tolerance=1e-3)
+>>> path_2.interpolation(points, angles, cycle=True, relative=True)
+
+
+../_images/interpolation2.svg + + +
+ +
+
+layers
+

RobustPath layer.

+
+

Notes

+

This attribute is read-only.

+
+ +
+ +
+
+max_evals
+

Maximal number of path evaluations per section.

+
+ +
+
+mirror(p1, p2=(0, 0)) self
+

Mirror this path across the line through p1 and p2.

+
+
Parameters:
+
    +
  • p1 (coordinate pair or complex) – First point in the mirror line.

  • +
  • p2 (coordinate pair or complex) – Second point in the mirror line.

  • +
+
+
+
+ +
+
+num_paths
+

Number of paths.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+offsets(u, from_below=True) numpy.ndarray
+

Calculate the offset of this path.

+
+
Parameters:
+
    +
  • u (number) – Where in the path to calculate the width. The value must +be in the range 0 thru gdstk.RobustPath.size, inclusive.

  • +
  • from_below – If there is a discontinuity at u, use the value +approaching from below.

  • +
+
+
Returns:
+

The offsets of each path at u.

+
+
+
+ +
+
+parametric(path_function, path_gradient=None, width=None, offset=None, relative=True) self
+

Append a parametric curve to this path.

+
+
Parameters:
+
    +
  • path_function (callable) – Function that defines the path. Must be a +function of one argument (that varies from 0 to 1) that returns a +2-element sequence or complex with the coordinates of the path.

  • +
  • path_gradient (callable) – Function that returns the path gradient. +Must be a function of one argument (that varies from 0 to 1) that +returns a 2-element sequence or complex with the gradient.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, the return values of path_function are +used as offsets from the current path position, i.e., to ensure a +continuous path, path_function(0) must be (0, 0). Otherwise, +they are used as absolute coordinates.

  • +
+
+
+

Examples

+
>>> def spiral(u):
+...    rad = 2 * u ** 0.5
+...    ang = 3 * numpy.pi * u
+...    return (rad * numpy.cos(ang), rad * numpy.sin(ang))
+>>> path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.parametric(spiral, width=lambda u: 0.2 + 0.6 * u ** 2)
+
+
+../_images/parametric2.svg +
+ +
+
+path_spines() list
+

Central spines of each parallel path.

+
+
Returns:
+

Copy of the points that make up each parallel path.

+
+
+
+ +
+
+position(u, from_below=True) numpy.ndarray
+

Calculate the position of this path.

+
+
Parameters:
+
    +
  • u (number) – Where in the path to calculate the position. The value +must be in the range 0 thru gdstk.RobustPath.size, +inclusive.

  • +
  • from_below – If there is a discontinuity at u, use the value +approaching from below.

  • +
+
+
Returns:
+

The spine position of the path at u.

+
+
+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+quadratic(xy, width=None, offset=None, relative=False) self
+

Append a quadratic Bézier curve to this path.

+
+
Parameters:
+
    +
  • xy (sequence of 2 points) – Control point and end point for the +Bézier. Each point can be a coordinate pair or a complex.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+ +
+ +
+
+quadratic_smooth(xy, width=None, offset=None, relative=False) self
+

Append a smooth quadratic Bézier curve to this path.

+

The control point of the Bézier is such that the gradient of the path is +continuous.

+
+
Parameters:
+
    +
  • xy (coordinate pair or complex) – End point for the Bézier.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+ +
+ +
+
+repetition
+

Repetition associated with this element.

+
+ +
+
+rotate(angle, center=(0, 0)) self
+

Rotate this path.

+
+
Parameters:
+
    +
  • angle – Rotation angle (in radians).

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+scale(s, center=(0, 0)) self
+

Scale this path.

+
+
Parameters:
+
    +
  • s – Scaling factor.

  • +
  • center (coordinate pair or complex) – Center of the transformation.

  • +
+
+
+
+ +
+
+scale_width
+

Scale width flag.

+
+ +
+
+segment(xy, width=None, offset=None, relative=False) self
+

Append a straight segment to this path.

+
+
Parameters:
+
    +
  • xy (coordinate pair or complex) – Segment end point.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+

Examples

+
>>> path = gdstk.RobustPath((0, 0), 0.2, tolerance=1e-3)
+>>> path.segment((5, 0), 1.0)
+>>> path.segment((5, 3), (0.2, "constant"))
+>>> path.segment((0, 3), (1.2, "smooth"))
+>>> path.segment(
+...     (0, 7),
+...     lambda u: 0.2 + 0.8 * numpy.cos(2 * numpy.pi * u) ** 2
+... )
+
+
+../_images/segment2.svg +
>>> path = gdstk.RobustPath((0, 0), [0.2, 0.2], 0.3, tolerance=1e-3)
+>>> path.segment((5, 0), offset=0.8)
+>>> path.segment((5, 3), offset=(0.3, "constant"))
+>>> path.segment((0, 3), offset=(1.0, "smooth"))
+>>> path.segment((0, 7), offset=[
+...     lambda u: -0.2 - 0.8 * numpy.cos(2 * numpy.pi * u) ** 2,
+...     lambda u: 0.2 + 0.8 * numpy.cos(2 * numpy.pi * u) ** 2
+... ])
+
+
+../_images/segment11.svg +
+ +
+
+set_datatypes(*datatypes) self
+

Set the datatypes for all paths.

+
+
Parameters:
+

datatypes – data type numbers for all paths.

+
+
+
+ +
+
+set_ends(*ends) self
+

Set the end types for all paths.

+
+
Parameters:
+

ends – Sequence of “flush”, “extended”, “round”, “smooth”, a 2-tuple, +or a callable.

+
+
+
+

See also

+

gdstk.RobustPath

+
+
+ +
+
+set_gds_property(attr, value) self
+

Set a GDSII property for this element.

+

GDSII properties are stored under the special name “S_GDS_PROPERTY”, as +defined by the OASIS specification.

+
+
Parameters:
+
    +
  • attr (number) – Property number.

  • +
  • value (str) – Property value.

  • +
+
+
+
+ +
+
+set_layers(*layers) self
+

Set the layers for all paths.

+
+
Parameters:
+

layers – layer numbers for all paths.

+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+simple_path
+

Simple path flag.

+
+ +
+
+size
+

Number of sections in this path.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+spine() numpy.ndarray
+

Central path spine.

+
+
Returns:
+

Copy of the points that make up the path at zero offset.

+
+
+
+ +
+
+to_polygons() list
+

Calculate the polygonal representations of this path.

+
+
Returns:
+

The polygonal contours defined by this path.

+
+
+
+ +
+
+tolerance
+

Path tolerance.

+
+ +
+
+translate(dx, dy=None) self
+

Translate this path.

+
+
Parameters:
+
    +
  • dx – Translation in the x coordinate or translation vector.

  • +
  • dy – Translation in the y coordinate.

  • +
+
+
+
+ +
+
+turn(radius, angle, width=None, offset=None) self
+

Append a circular turn to this path.

+
+
Parameters:
+
    +
  • radius – Circular arc radius.

  • +
  • angle – Turning angle. Positive values turn counter clockwise and +negative values, clockwise.

  • +
  • width (number or sequence) – Width at the end point(s). If this is a +sequence, it must define the width for each path. The width is +linearly tapered from its previous value.

  • +
  • offset (number or sequence) – If this is a number, it is treated as +the distance between centers of adjacent paths. If it is a +sequence, each number represents the absolute offset from the +center of the path. The offsets are linearly tapered from their +previous values.

  • +
+
+
+
+ +
+
+vertical(y, width=None, offset=None, relative=False) self
+

Append a vertical segment to this path.

+
+
Parameters:
+
    +
  • y (number) – End point x coordinate.

  • +
  • width (number, tuple, or callable) – Width of this section. A tuple +of 2 elements (number, str) can be used to define the width value +and the interpolation type from the previous section to the end +point (“constant”, “linear”, or “smooth”). If only a number is +used, the interpolation defaults to “linear”. A callable must +accept a single number from 0 to 1 and return the desired width at +the corresponding position along the section.

  • +
  • offset (number, tuple, or callable) – Offset from the central path +position. A tuple or callable can be used as in width.

  • +
  • relative – If True, coordinates are relative to the last point.

  • +
+
+
+
+

Notes

+

Arguments width and offset can also be lists with one +definition for each path.

+

If offset is a single number or tuple, it is treated as the +distance between adjacent paths.

+
+ +
+ +
+
+widths(u, from_below=True) numpy.ndarray
+

Calculate the width of this path.

+
+
Parameters:
+
    +
  • u (number) – Where in the path to calculate the width. The value must +be in the range 0 thru gdstk.RobustPath.size, inclusive.

  • +
  • from_below – If there is a discontinuity at u, use the value +approaching from below.

  • +
+
+
Returns:
+

The widths of each path at u.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.all_inside.html b/geometry/gdstk.all_inside.html new file mode 100644 index 000000000..3db120874 --- /dev/null +++ b/geometry/gdstk.all_inside.html @@ -0,0 +1,165 @@ + + + + + + + gdstk.all_inside — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.all_inside

+
+
+gdstk.all_inside(points, polygons) bool
+

Check whether all points are inside the set of polygons.

+

Points on polygon edges or coinciding with any of their vertices are +considered inside.

+
+
Parameters:
+
    +
  • points – Points to check. Each point can be a pair of coordinates or +a complex number.

  • +
  • polygons (Polygon, FlexPath, RobustPath, Reference, sequence) – Polygons to test against. If this is a sequence, each element can +be any of the polygonal types or a sequence of points (coordinate +pairs or complex).

  • +
+
+
Returns:
+

True if all points are inside the polygon set, False otherwise.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.any_inside.html b/geometry/gdstk.any_inside.html new file mode 100644 index 000000000..a91ed2385 --- /dev/null +++ b/geometry/gdstk.any_inside.html @@ -0,0 +1,165 @@ + + + + + + + gdstk.any_inside — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.any_inside

+
+
+gdstk.any_inside(points, polygons) bool
+

Check whether any of the points are inside the set of polygons.

+

Points on polygon edges or coinciding with any of their vertices are +considered inside.

+
+
Parameters:
+
    +
  • points – Points to check. Each point can be a pair of coordinates or +a complex number.

  • +
  • polygons (Polygon, FlexPath, RobustPath, Reference, sequence) – Polygons to test against. If this is a sequence, each element can +be any of the polygonal types or a sequence of points (coordinate +pairs or complex).

  • +
+
+
Returns:
+

True if any point is inside the polygon set, False otherwise.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.boolean.html b/geometry/gdstk.boolean.html new file mode 100644 index 000000000..a2fc8c516 --- /dev/null +++ b/geometry/gdstk.boolean.html @@ -0,0 +1,190 @@ + + + + + + + gdstk.boolean — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.boolean

+
+
+gdstk.boolean(operand1, operand2, operation, precision=1e-3, layer=0, datatype=0) list
+

Execute boolean (clipping) operations between polygons.

+
+
Parameters:
+
    +
  • operand1 (Polygon, FlexPath, RobustPath, Reference, sequence) – First +operand. If this is a sequence, each element can be any of the +polygonal types or a sequence of points (coordinate pairs or +complex).

  • +
  • operand2 (Polygon, FlexPath, RobustPath, Reference, sequence) – Second operand.

  • +
  • operation (str) – Boolean operation to be executed. One of “or”, +“and”, “xor”, or “not”. The “not” operation performs the set +difference operand1 - operand2.

  • +
  • precision – Desired precision for rounding vertex coordinates.

  • +
  • layer – layer number assigned to the resulting polygons.

  • +
  • datatype – data type number assigned to the resulting polygons.

  • +
+
+
Returns:
+

List of gdstk.Polygon.

+
+
+

Examples

+
>>> circle = gdstk.ellipse((0, 0), 50)
+>>> path = gdstk.FlexPath((-50, 30), [5, 5], 10)
+>>> path.interpolation([(20, 15), (0, 0), (-20, -15), (50, -30)],
+...                    angles=[0.3, None, None, None, 0.3])
+>>> text = gdstk.text("GDSTK", 40, (-2.5 * 40 * 9 / 16, -40 / 2))
+>>> result = gdstk.boolean(circle, text + [path], "not")
+
+
+../_images/boolean.svg +
+

Notes

+
    +
  1. Repetitions are not applied to any elements, except references +and their contents.

  2. +
  3. All polygons in operand1 are merged during the operation, as +well as those in operand2. As such, if, for example, +operand2 is an empty list, the result of the operation will be +the union of polygons in operand1.

  4. +
+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.contour.html b/geometry/gdstk.contour.html new file mode 100644 index 000000000..fc3d76c38 --- /dev/null +++ b/geometry/gdstk.contour.html @@ -0,0 +1,181 @@ + + + + + + + gdstk.contour — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.contour

+
+
+gdstk.contour(data, level=0, length_scale=1, precision=0.01, layer=0, datatype=0) list
+

Extract polygonal contours from 2-d array data at given level.

+
+
Parameters:
+
    +
  • data (array-like[M][N]) – 2-dimensional array with shape (M, N).

  • +
  • level – Polygons are created representing the regions where data is +at least level.

  • +
  • length_scale – Distance between neighboring elements in data.

  • +
  • precision – Desired precision for rounding vertex coordinates.

  • +
  • layer – layer number assigned to the resulting polygons.

  • +
  • datatype – data type number assigned to the resulting polygons.

  • +
+
+
Returns:
+

List of gdstk.Polygon.

+
+
+

Examples

+
>>> y, x = numpy.mgrid[0.5:1.5:128j, -1:1:255j]
+>>> data = (numpy.sin(4 * numpy.pi * x * y)
+...         - 0.8 * numpy.sin(2 * numpy.pi * y))
+>>> contours = gdstk.contour(data, 0, 1 / 127, 0.01 / 127)
+>>> rect = gdstk.rectangle((0, 0), (2, 1), datatype=1)
+
+
+../_images/contour.svg +
+

Notes

+

The length scale for the polygons is one element of data, i.e., +the full region represented by data represents a rectangular area +of lenght_scale * (N - 1) × length_scale * (M - 1). Argument +precision is understood in this length scale.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.cross.html b/geometry/gdstk.cross.html new file mode 100644 index 000000000..261f8f971 --- /dev/null +++ b/geometry/gdstk.cross.html @@ -0,0 +1,166 @@ + + + + + + + gdstk.cross — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.cross

+
+
+gdstk.cross(center, full_size, arm_width, layer=0, datatype=0) gdstk.Polygon
+

Create a cross shape.

+
+
Parameters:
+
    +
  • center (coordinate pair or complex) – Center of the cross.

  • +
  • full_size (number) – Total length of the cross.

  • +
  • arm_width (number) – Width of the arms.

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+

Examples

+
>>> cross1 = gdstk.cross((0, 0), 10, 1)
+>>> cross2 = gdstk.cross((0.5, 0.5), 5, 0.75, layer=1)
+
+
+../_images/cross.svg +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.ellipse.html b/geometry/gdstk.ellipse.html new file mode 100644 index 000000000..f2dca5b94 --- /dev/null +++ b/geometry/gdstk.ellipse.html @@ -0,0 +1,180 @@ + + + + + + + gdstk.ellipse — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.ellipse

+
+
+gdstk.ellipse(center, radius, inner_radius=None, initial_angle=0, final_angle=0, tolerance=0.01, layer=0, datatype=0) gdstk.Polygon
+

Create an ellipse, circle, slice or ring.

+
+
Parameters:
+
    +
  • center (coordinate pair or complex) – Circle/ellipse center.

  • +
  • radius (number or sequence) – Circle radius of the circle. A pair of +numbers can be used to define an ellipse.

  • +
  • inner_radius (number or sequence) – If set, creates a ring.

  • +
  • initial_angle – Initial angle to define a slice.

  • +
  • final_angle – Final slice angle.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation of this shape.

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+

Examples

+
>>> circle = gdstk.ellipse((0, 0), 40)
+>>> ellipse = gdstk.ellipse((100, 0), (40, 30), layer=1)
+>>> ring = gdstk.ellipse((0, 100), 40, inner_radius=(30, 20),
+                         layer=2)
+>>> c_slice = gdstk.ellipse((100, 100), 40,
+...                         initial_angle=-numpy.pi / 4,
+...                         final_angle=5 * numpy.pi / 4,
+...                         layer=3)
+>>> r_slice = gdstk.ellipse((50, 200), (70, 30), (60, 20),
+...                         -3 * numpy.pi / 4, numpy.pi / 2,
+...                         layer=4)
+
+
+../_images/ellipse.svg +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.inside.html b/geometry/gdstk.inside.html new file mode 100644 index 000000000..3695c882b --- /dev/null +++ b/geometry/gdstk.inside.html @@ -0,0 +1,165 @@ + + + + + + + gdstk.inside — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.inside

+
+
+gdstk.inside(points, polygons) tuple
+

Check whether each point is inside the set of polygons.

+

Points on polygon edges or coinciding with any of their vertices are +considered inside.

+
+
Parameters:
+
    +
  • points – Points to check. Each point can be a pair of coordinates or +a complex number.

  • +
  • polygons (Polygon, FlexPath, RobustPath, Reference, sequence) – Polygons to test against. If this is a sequence, each element can +be any of the polygonal types or a sequence of points (coordinate +pairs or complex).

  • +
+
+
Returns:
+

Tuple of booleans (one for each point).

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.offset.html b/geometry/gdstk.offset.html new file mode 100644 index 000000000..4e839bedb --- /dev/null +++ b/geometry/gdstk.offset.html @@ -0,0 +1,192 @@ + + + + + + + gdstk.offset — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.offset

+
+
+gdstk.offset(polygons, distance, join='miter', tolerance=2, precision=1e-3, use_union=False, layer=0, datatype=0) list
+

Dilate or erode polygons.

+
+
Parameters:
+
    +
  • polygons (Polygon, FlexPath, RobustPath, Reference, sequence) – Polygons to offset. If this is a sequence, each element can be any +of the polygonal types or a sequence of points (coordinate pairs +or complex).

  • +
  • distance (number) – Offset distance. Positive values dilate the +geometry, whereas negative values erode it.

  • +
  • join – Type of joins for the offset polygon. One of “miter”, “bevel”, +or “round”.

  • +
  • tolerance – For miter joints, this number must be at least 2 and it +represents the maximal distance in multiples of offset between new +vertices and their original position before beveling to avoid +spikes at acute joints. For round joints, it indicates the +curvature resolution in number of points per full circle.

  • +
  • precision – Desired precision for rounding vertex coordinates.

  • +
  • use_union – Apply a union operation before the offset to merge +adjacent polygons.

  • +
  • layer – layer number assigned to the resulting polygons.

  • +
  • datatype – data type number assigned to the resulting polygons.

  • +
+
+
Returns:
+

List of gdstk.Polygon.

+
+
+

Examples

+
>>> text = gdstk.text("#A", 10, (0, 0), datatype=1)
+>>> circle = gdstk.ellipse((5, 11), 5, initial_angle=0,
+...                        final_angle=numpy.pi, datatype=1)
+>>> path = gdstk.FlexPath([(0, -1), (5, -10), (10, -1)], 1,
+>>>                       datatype=1)
+>>> dilated = gdstk.offset(text + [circle, path], 0.4)
+>>> eroded = gdstk.offset(text + [circle, path], -0.4,
+...                       use_union=True, layer=1)
+
+
+../_images/offset.svg +
+

Notes

+

Repetitions are not applied to any elements, except references and +their contents.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.racetrack.html b/geometry/gdstk.racetrack.html new file mode 100644 index 000000000..5a7db54af --- /dev/null +++ b/geometry/gdstk.racetrack.html @@ -0,0 +1,170 @@ + + + + + + + gdstk.racetrack — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.racetrack

+
+
+gdstk.racetrack(center, straight_length, radius, inner_radius=0, vertical=False, tolerance=0.01, layer=0, datatype=0) gdstk.Polygon
+

Create a racetrack shape.

+
+
Parameters:
+
    +
  • center (coordinate pair or complex) – Polygon center.

  • +
  • straight_length (number) – Length of the straight segment.

  • +
  • radius (number) – Radius of the circular arc.

  • +
  • inner_radius (number) – If greater than 0, create a racetrack ring.

  • +
  • vertical – If True, the racetrack is created vertically.

  • +
  • tolerance – Tolerance used for calculating the polygonal +approximation for the circular arcs.

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+

Examples

+
>>> racetrack1 = gdstk.racetrack((0, 0), 8, 5)
+>>> racetrack2 = gdstk.racetrack((18, 0), 8, 5, 3, True)
+
+
+../_images/racetrack.svg +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.rectangle.html b/geometry/gdstk.rectangle.html new file mode 100644 index 000000000..e5aa269ba --- /dev/null +++ b/geometry/gdstk.rectangle.html @@ -0,0 +1,159 @@ + + + + + + + gdstk.rectangle — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.rectangle

+
+
+gdstk.rectangle(corner1, corner2, layer=0, datatype=0) gdstk.Polygon
+

Create a rectangle.

+
+
Parameters:
+
    +
  • corner1 (coordinate pair or complex) – First rectangle corner.

  • +
  • corner2 (coordinate pair or complex) – Opposing corner.

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.regular_polygon.html b/geometry/gdstk.regular_polygon.html new file mode 100644 index 000000000..7a2583c60 --- /dev/null +++ b/geometry/gdstk.regular_polygon.html @@ -0,0 +1,169 @@ + + + + + + + gdstk.regular_polygon — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.regular_polygon

+
+
+gdstk.regular_polygon(center, side_length, sides, rotation=0, layer=0, datatype=0) gdstk.Polygon
+

Create a regular polygon.

+
+
Parameters:
+
    +
  • center (coordinate pair or complex) – Polygon center.

  • +
  • side_length (number) – Length of the sides of the polygon.

  • +
  • sides (integer) – Number of polygon sides.

  • +
  • rotation – Rotation angle (in radians).

  • +
  • layer – layer number assigned to this polygon.

  • +
  • datatype – data type number assigned to this polygon.

  • +
+
+
+

Examples

+
>>> poly3 = gdstk.regular_polygon((0, 0), 9, 3)
+>>> poly4 = gdstk.regular_polygon((10, 0), 7, 4, layer=1)
+>>> poly5 = gdstk.regular_polygon((0, 10), 5, 5, layer=2)
+>>> poly6 = gdstk.regular_polygon((10, 10), 4, 6, layer=3)
+
+
+../_images/regular_polygon.svg +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.slice.html b/geometry/gdstk.slice.html new file mode 100644 index 000000000..9efbb6e36 --- /dev/null +++ b/geometry/gdstk.slice.html @@ -0,0 +1,182 @@ + + + + + + + gdstk.slice — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.slice

+
+
+gdstk.slice(polygons, position, axis, precision=1e-3) list
+

Slice polygons along x and y axes.

+
+
Parameters:
+
    +
  • polygons (Polygon, FlexPath, RobustPath, Reference, sequence) – Polygons to offset. If this is a sequence, each element can be any +of the polygonal types or a sequence of points (coordinate pairs +or complex).

  • +
  • position (number or sequence) – Cut positions.

  • +
  • axis (str) – One of “x” or “y”. Indicated the axis where positions +are specified. The cut direction is orthogonal to this axis.

  • +
  • precision – Desired precision for rounding vertex coordinates.

  • +
+
+
Returns:
+

List with N + 1 elements, where N is the number of cut positions. +Each element is a list of polygons obtained between cuts.

+
+
+

Examples

+
>>> triangle = gdstk.regular_polygon((-10, 0), 8, 3)
+>>> ring = gdstk.ellipse((10, 0), 8, 5, layer=1)
+>>> result = gdstk.slice([triangle, ring], (-10, -5, 0, 6, 14), "x")
+>>> print(len(result))
+6
+>>> print([len(polys) for polys in result])
+[1, 1, 0, 1, 2, 1]
+
+
+../_images/slice.svg +
+

Notes

+

Repetitions are not applied to any elements, except references and +their contents.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/geometry/gdstk.text.html b/geometry/gdstk.text.html new file mode 100644 index 000000000..96c0c8fbe --- /dev/null +++ b/geometry/gdstk.text.html @@ -0,0 +1,179 @@ + + + + + + + gdstk.text — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.text

+
+
+gdstk.text(text, size, position, vertical=False, layer=0, datatype=0) list
+

Create polygonal text.

+
+
Parameters:
+
    +
  • text (str) – Text string.

  • +
  • size (number) – Full height of the font.

  • +
  • position (coordinate pair or complex) – Text starting position.

  • +
  • vertical – Writing direction.

  • +
  • layer – layer number assigned to the polygons.

  • +
  • datatype – data type number assigned to the polygons.

  • +
+
+
Returns:
+

List of gdstk.Polygon.

+
+
+

Examples

+
>>> text = gdstk.text(f"Created with\nGDSTK {gdstk.__version__}", 1,
+...                   (0, 0))
+>>> rect = gdstk.rectangle((0, -5 / 4), (12 * 9 / 16, 1),
+...                        datatype=1)
+
+
+../_images/text.svg +
+

Notes

+

The character aspect ratio is 1:2. For horizontal text, spacings +between characters and between lines are 9 / 16 and 5 / 4 times the +full height size, respectively. For vertical text, characters +and columns are respectively spaced by 9 / 8 and 1 times size.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/gettingstarted.html b/gettingstarted.html new file mode 100644 index 000000000..27e12c9dd --- /dev/null +++ b/gettingstarted.html @@ -0,0 +1,1486 @@ + + + + + + + Getting Started — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +
+

Getting Started

+

GDSII files contain a hierarchical representation of any polygonal geometry. +They are mainly used in the microelectronics industry for the design of mask +layouts, but are also employed in other areas.

+

Because it is a hierarchical format, repeated structures, such as identical +transistors, can be defined once and referenced multiple times in the layout, +reducing the file size.

+

There is one important limitation in the GDSII format: it only supports weakly +simple polygons, that is, +polygons whose segments are allowed to intersect, but not cross.

+

In particular, curves and shapes with holes are not directly supported. +Holes can be defined, nonetheless, by connecting their boundary to the boundary +of the enclosing shape. In the case of curves, they must be approximated by a +polygon. The number of points in the polygonal approximation can be increased +to better approximate the original curve up to some acceptable error.

+

The original GDSII format limits the number of vertices in a polygon to 199. +This limit seems arbitrary, as the maximal number of vertices that can be +stored in a GDSII record is 8190. Nonetheless, most modern software disregard +both limits and allow an arbitrary number of points per polygon. Gdstk follows +the modern version of GDSII, but this is an important issue to keep in mind if +the generated file is to be used in older systems.

+

The units used to represent shapes in the GDSII format are defined by the user. +The default unit in Gdstk is 1 µm (10⁻⁶ m), but that can be easily changed by +the user.

+
+

First Layout

+

Let’s create our first layout file:

+
+
+
import gdstk
+
+# The GDSII file is called a library, which contains multiple cells.
+lib = gdstk.Library()
+
+# Geometry must be placed in cells.
+cell = lib.new_cell("FIRST")
+
+# Create the geometry (a single rectangle) and add it to the cell.
+rect = gdstk.rectangle((0, 0), (2, 1))
+cell.add(rect)
+
+# Save the library in a GDSII or OASIS file.
+lib.write_gds("first.gds")
+lib.write_oas("first.oas")
+
+# Optionally, save an image of the cell as SVG.
+cell.write_svg("first.svg")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("library", 1e-6, 1e-9);
+
+    Cell cell = {};
+    cell.name = copy_string("FIRST", NULL);
+    lib.cell_array.append(&cell);
+
+    Polygon rect = rectangle(Vec2{0, 0}, Vec2{2, 1}, make_tag(0, 0));
+    cell.polygon_array.append(&rect);
+
+    lib.write_gds("first.gds", 0, NULL);
+    lib.write_oas("first.oas", 0, 6, OASIS_CONFIG_DETECT_ALL);
+    cell.write_svg("first.svg", 10, 6, NULL, NULL, "#222222", 5, true, NULL);
+
+    rect.clear();
+    cell.clear();
+    lib.clear();
+    return 0;
+}
+
+
+
+
+

After importing the gdstk module, we create a library lib to hold the +design.

+

All layout elements must be added to cells, which can be though of pieces of +papers where the geometry is drawn. Later, a cell can reference others to +build hierarchical designs, as if stamping the referenced cell into the first, +as we’ll see in References.

+

We create a gdstk.Cell with name “FIRST” (cells are identified by +name, therefore cell names must be unique within a library) and add a +gdstk.rectangle() to it.

+

Finally, the whole library is saved in a GDSII file called “first.gds” and an +OASIS file “first.oas” in the current directory. The GDSII or OASIS files can +be opened in a number of viewers and editors, such as KLayout.

+
+
+

Polygons

+

General polygons can be defined by an ordered list of vertices. The +orientation of the vertices (clockwise/counter-clockwise) is not important: +they will be ordered internally.

+
+
+
# Create a polygon from a list of vertices
+points = [(0, 0), (2, 2), (2, 6), (-6, 6), (-6, -6), (-4, -4), (-4, 4), (0, 4)]
+poly = gdstk.Polygon(points)
+
+
+
+
+
void example_polygons(Cell& out_cell) {
+    Vec2 points[] = {{0, 0}, {2, 2}, {2, 6}, {-6, 6}, {-6, -6}, {-4, -4}, {-4, 4}, {0, 4}};
+
+    // This has to be heap-allocated so that it doesn't go out of scope once
+    // the function returns.  We also don't worry about leaking it at the end
+    // of the program.  The OS will take care of it.
+    Polygon* poly = (Polygon*)allocate_clear(sizeof(Polygon));
+    poly->point_array.extend({.capacity = 0, .count = COUNT(points), .items = points});
+    out_cell.polygon_array.append(poly);
+}
+
+
+
+
+_images/polygons.svg +
+

Holes

+

As mentioned in Getting Started, holes have to be connected to the outer +boundary of the polygon, as in the following example:

+
+
+
# Manually connect the hole to the outer boundary
+cutout = gdstk.Polygon(
+    [(0, 0), (5, 0), (5, 5), (0, 5), (0, 0), (2, 2), (2, 3), (3, 3), (3, 2), (2, 2)]
+)
+
+
+
+
+
void example_holes(Cell& out_cell) {
+    Vec2 points[] = {{0, 0}, {5, 0}, {5, 5}, {0, 5}, {0, 0},
+                     {2, 2}, {2, 3}, {3, 3}, {3, 2}, {2, 2}};
+    Polygon* poly = (Polygon*)allocate_clear(sizeof(Polygon));
+    poly->point_array.extend({.capacity = 0, .count = COUNT(points), .items = points});
+    out_cell.polygon_array.append(poly);
+}
+
+
+
+
+_images/holes.svg +
+
+

Circles

+

The gdstk.ellipse() function creates circles, ellipses, doughnuts, arcs +and slices. In all cases, the argument tolerance will control the number +of vertices used to approximate the curved shapes.

+

When saving a library with gdstk.Library.write_gds(), if the number of +vertices in the polygon is larger than max_points (199 by default), it will +be fractured in many smaller polygons with at most max_points vertices +each.

+

OASIS files don’t have a limit to the number of polygon vertices, so no +polygons are fractured when saving. They also have support for circles. When +saving an OASIS file, polygonal circles will be detected within a predefined +tolerance and automatically converted.

+
+
+
# Circle centered at (0, 0), with radius 2 and tolerance 0.1
+circle = gdstk.ellipse((0, 0), 2, tolerance=0.01)
+
+# To create an ellipse, simply pass a list with 2 radii.
+# Because the tolerance is small (resulting a large number of
+# vertices), the ellipse is fractured in 2 polygons.
+ellipse = gdstk.ellipse((4, 0), [1, 2], tolerance=1e-4)
+
+# Circular arc example
+arc = gdstk.ellipse(
+    (2, 4),
+    2,
+    inner_radius=1,
+    initial_angle=-0.2 * numpy.pi,
+    final_angle=1.2 * numpy.pi,
+    tolerance=0.01,
+)
+
+
+
+
+
void example_circles(Cell& out_cell) {
+    Polygon* circle = (Polygon*)allocate_clear(sizeof(Polygon));
+    *circle = ellipse(Vec2{0, 0}, 2, 2, 0, 0, 0, 0, 0.01, 0);
+    out_cell.polygon_array.append(circle);
+
+    Polygon* ellipse_ = (Polygon*)allocate_clear(sizeof(Polygon));
+    *ellipse_ = ellipse(Vec2{4, 0}, 1, 2, 0, 0, 0, 0, 1e-4, 0);
+    out_cell.polygon_array.append(ellipse_);
+
+    Polygon* arc = (Polygon*)allocate_clear(sizeof(Polygon));
+    *arc = ellipse(Vec2{2, 4}, 2, 2, 1, 1, -0.2 * M_PI, 1.2 * M_PI, 0.01, 0);
+    out_cell.polygon_array.append(arc);
+}
+
+
+
+
+_images/circles.svg +
+
+

Curves

+

Constructing complex polygons by manually listing all vertices in +gdstk.Polygon can be challenging. The class gdstk.Curve can +be used to facilitate the creation of polygons by drawing their shapes +step-by-step. The syntax is inspired by the SVG path specification.

+
+
+
# Construct a curve made of a sequence of line segments
+c1 = gdstk.Curve((0, 0)).segment([(1, 0), (2, 1), (2, 2), (0, 2)])
+p1 = gdstk.Polygon(c1.points())
+
+# Construct another curve using relative coordinates
+c2 = gdstk.Curve((3, 1)).segment([(1, 0), (2, 1), (2, 2), (0, 2)], relative=True)
+p2 = gdstk.Polygon(c2.points())
+
+
+
+
+
void example_curves1(Cell& out_cell) {
+    Vec2 points[] = {{1, 0}, {2, 1}, {2, 2}, {0, 2}};
+
+    // Curve points will be copied to the polygons, so allocating the curve on
+    // the stack is fine.
+    Curve c1 = {};
+    c1.init(Vec2{0, 0}, 0.01);
+    c1.segment({.capacity = 0, .count = COUNT(points), .items = points}, false);
+
+    Polygon* p1 = (Polygon*)allocate_clear(sizeof(Polygon));
+    p1->point_array.extend(c1.point_array);
+    out_cell.polygon_array.append(p1);
+    c1.clear();
+
+    Curve c2 = {};
+    c2.init(Vec2{3, 1}, 0.01);
+    c2.segment({.capacity = 0, .count = COUNT(points), .items = points}, true);
+
+    Polygon* p2 = (Polygon*)allocate_clear(sizeof(Polygon));
+    p2->point_array.extend(c2.point_array);
+    out_cell.polygon_array.append(p2);
+    c2.clear();
+}
+
+
+
+
+_images/curves.svg +

Coordinate pairs can be given as a complex number: real and imaginary parts are +used as x and y coordinates, respectively. That is useful to define points in +polar coordinates.

+

Elliptical arcs have syntax similar to gdstk.ellipse(), but they allow +for an extra rotation of the major axis of the ellipse.

+
+
+
# Use complex numbers to facilitate writing polar coordinates
+c3 = gdstk.Curve(2j).segment(4 * numpy.exp(1j * numpy.pi / 6), relative=True)
+# Elliptical arcs have syntax similar to gdstk.ellipse
+c3.arc((4, 2), 0.5 * numpy.pi, -0.5 * numpy.pi)
+p3 = gdstk.Polygon(c3.points())
+
+
+
+
+
void example_curves2(Cell& out_cell) {
+    Curve c3 = {};
+    c3.init(Vec2{0, 2}, 0.01);
+    c3.segment(4 * cplx_from_angle(M_PI / 6), true);
+    c3.arc(4, 2, M_PI / 2, -M_PI / 2, 0);
+
+    Polygon* p3 = (Polygon*)allocate_clear(sizeof(Polygon));
+    p3->point_array.extend(c3.point_array);
+    out_cell.polygon_array.append(p3);
+    c3.clear();
+}
+
+
+
+
+_images/curves_1.svg +

Curves sections can be constructed as cubic, quadratic and general-degree +Bézier curves. Additionally, a smooth interpolating curve can be calculated +with the method gdstk.Curve.interpolation(), which has a number of +arguments to control the shape of the curve.

+
+
+
# Cubic Bezier curves can be easily created
+c4 = gdstk.Curve((0, 0), tolerance=1e-3)
+c4.cubic([(0, 1), (1, 1), (1, 0)])
+# Smooth continuation:
+c4.cubic_smooth([(1, -1), (1, 0)], relative=True)
+
+# Similarly for quadratic Bezier curves
+c4.quadratic([(0.5, 1), (1, 0)], relative=True)
+c4.quadratic_smooth((1, 0), relative=True)
+
+# Smooth interpolating curve
+c4.interpolation([(4, -1), (3, -2), (2, -1.5), (1, -2), (0, -1), (0, 0)])
+p4 = gdstk.Polygon(c4.points())
+
+
+
+
+
void example_curves3(Cell& out_cell) {
+    Curve c4 = {};
+    c4.init(Vec2{0, 0}, 1e-3);
+
+    Vec2 points1[] = {{0, 1}, {1, 1}, {1, 0}};
+    c4.cubic({.capacity = 0, .count = COUNT(points1), .items = points1}, false);
+
+    Vec2 points2[] = {{1, -1}, {1, 0}};
+    c4.cubic_smooth({.capacity = 0, .count = COUNT(points2), .items = points2}, true);
+
+    Vec2 points3[] = {{0.5, 1}, {1, 0}};
+    c4.quadratic({.capacity = 0, .count = COUNT(points3), .items = points3}, true);
+
+    c4.quadratic_smooth(Vec2{1, 0}, true);
+
+    Vec2 points4[] = {{4, -1}, {3, -2}, {2, -1.5}, {1, -2}, {0, -1}, {0, 0}};
+    double angles[COUNT(points4) + 1] = {};
+    bool angle_constraints[COUNT(points4) + 1] = {};
+    Vec2 tension[COUNT(points4) + 1] = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}};
+
+    c4.interpolation({.capacity = 0, .count = COUNT(points4), .items = points4}, angles,
+                     angle_constraints, tension, 1, 1, false, false);
+
+    // The last point will coincide with the first (this can be checked at
+    // runtime with the `closed` method), so we remove it.
+    if (c4.closed()) {
+        c4.remove(c4.point_array.count - 1);
+    }
+    Polygon* p4 = (Polygon*)allocate_clear(sizeof(Polygon));
+    p4->point_array.extend(c4.point_array);
+    out_cell.polygon_array.append(p4);
+    c4.clear();
+}
+
+
+
+
+_images/curves_2.svg +
+
+

Transformations

+

All polygons can be transformed through gdstk.Polygon.translate(), +gdstk.Polygon.rotate(), gdstk.Polygon.scale(), and +gdstk.Polygon.mirror(). The transformations are applied in-place, i.e., +no new polygons are created.

+
+
+
poly = gdstk.rectangle((-2, -2), (2, 2))
+poly.rotate(numpy.pi / 4)
+poly.scale(1, 0.5)
+
+
+
+
+
void example_transformations(Cell& out_cell) {
+    Polygon* poly = (Polygon*)allocate_clear(sizeof(Polygon));
+    *poly = rectangle(Vec2{-2, -2}, Vec2{2, 2}, 0);
+    poly->rotate(M_PI / 4, Vec2{0, 0});
+    poly->scale(Vec2{1, 0.5}, Vec2{0, 0});
+    out_cell.polygon_array.append(poly);
+}
+
+
+
+
+_images/transformations.svg +
+
+

Layer and Datatype

+

All shapes are tagged with 2 properties: layer and data type (or text type in +the case of gdstk.Label). They are always 0 by default, but can be +any integer in the range from 0 to 255.

+

These properties have no predefined meaning. It is up to the system using the +file to chose with to do with those tags. For example, in the CMOS fabrication +process, each layer could represent a different lithography level.

+

In the example below, a single file stores different fabrication masks in +separate layer and data type configurations. Python dictionaries are used to +simplify the assignment to each polygon.

+
+
+
# Layer/datatype definitions for each step in the fabrication
+ld = {
+    "full etch": {"layer": 1, "datatype": 3},
+    "partial etch": {"layer": 2, "datatype": 3},
+    "lift-off": {"layer": 0, "datatype": 7},
+}
+
+p1 = gdstk.rectangle((-3, -3), (3, 3), **ld["full etch"])
+p2 = gdstk.rectangle((-5, -3), (-3, 3), **ld["partial etch"])
+p3 = gdstk.rectangle((5, -3), (3, 3), **ld["partial etch"])
+p4 = gdstk.regular_polygon((0, 0), 2, 6, **ld["lift-off"])
+
+
+
+
+
void example_layerdatatype(Cell& out_cell) {
+    Tag t_full_etch = make_tag(1, 3);
+    Tag t_partial_etch = make_tag(2, 3);
+    Tag t_lift_off = make_tag(0, 7);
+
+    Polygon* poly[4];
+    for (uint64_t i = 0; i < COUNT(poly); i++) poly[i] = (Polygon*)allocate_clear(sizeof(Polygon));
+
+    *poly[0] = rectangle(Vec2{-3, -3}, Vec2{3, 3}, t_full_etch);
+    *poly[1] = rectangle(Vec2{-5, -3}, Vec2{-3, 3}, t_partial_etch);
+    *poly[2] = rectangle(Vec2{5, -3}, Vec2{3, 3}, t_partial_etch);
+    *poly[3] = regular_polygon(Vec2{0, 0}, 2, 6, 0, t_lift_off);
+
+    out_cell.polygon_array.extend({.capacity = 0, .count = COUNT(poly), .items = poly});
+}
+
+
+
+
+_images/layer_and_datatype.svg +
+
+
+

References

+

References are responsible for the hierarchical structure of the layout. +Through references, the cell content can be reused in another cell (without +actually copying the whole geometry). As an example, imagine the we are +designing an electronic circuit that uses hundreds of transistors, all with the +same shape. We can draw the transistor just once and reference it throughout +the circuit, rotating or mirroring each instance as necessary.

+

Besides creating single references, it is also possible to create full 2D +arrays with a single entity, both using gdstk.Reference. Both uses +are exemplified below.

+
+
+
# Create a cell with a component that is used repeatedly
+contact = gdstk.Cell("CONTACT")
+contact.add(p1, p2, p3, p4)
+
+# Create a cell with the complete device
+device = gdstk.Cell("DEVICE")
+device.add(cutout)
+# Add 2 references to the component changing size and orientation
+ref1 = gdstk.Reference(contact, (3.5, 1), magnification=0.25)
+ref2 = gdstk.Reference(contact, (1, 3.5), magnification=0.25, rotation=numpy.pi / 2)
+device.add(ref1, ref2)
+
+# The final layout has several repetitions of the complete device
+main = gdstk.Cell("MAIN")
+main.add(gdstk.Reference(device, (0, 0), columns=3, rows=2, spacing=(6, 7)))
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    Tag t_full_etch = make_tag(1, 3);
+    Tag t_partial_etch = make_tag(2, 3);
+    Tag t_lift_off = make_tag(0, 7);
+
+    char lib_name[] = "library";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    // CONTACT
+
+    char contact_cell_name[] = "CONTACT";
+    Cell contact_cell = {.name = contact_cell_name};
+    lib.cell_array.append(&contact_cell);
+
+    Polygon contact_poly[4];
+    contact_poly[0] = rectangle(Vec2{-3, -3}, Vec2{3, 3}, t_full_etch);
+    contact_poly[1] = rectangle(Vec2{-5, -3}, Vec2{-3, 3}, t_partial_etch);
+    contact_poly[2] = rectangle(Vec2{5, -3}, Vec2{3, 3}, t_partial_etch);
+    contact_poly[3] = regular_polygon(Vec2{0, 0}, 2, 6, 0, t_lift_off);
+
+    Polygon* p[] = {contact_poly, contact_poly + 1, contact_poly + 2, contact_poly + 3};
+    contact_cell.polygon_array.extend({.capacity = 0, .count = COUNT(p), .items = p});
+
+    // DEVICE
+
+    char device_cell_name[] = "DEVICE";
+    Cell device_cell = {.name = device_cell_name};
+    lib.cell_array.append(&device_cell);
+
+    Vec2 cutout_points[] = {{0, 0}, {5, 0}, {5, 5}, {0, 5}, {0, 0},
+                            {2, 2}, {2, 3}, {3, 3}, {3, 2}, {2, 2}};
+    Polygon cutout_poly = {};
+    cutout_poly.point_array.extend(
+        {.capacity = 0, .count = COUNT(cutout_points), .items = cutout_points});
+    device_cell.polygon_array.append(&cutout_poly);
+
+    Reference contact_ref1 = {
+        .type = ReferenceType::Cell,
+        .cell = &contact_cell,
+        .origin = Vec2{3.5, 1},
+        .magnification = 0.25,
+    };
+    device_cell.reference_array.append(&contact_ref1);
+
+    Reference contact_ref2 = {
+        .type = ReferenceType::Cell,
+        .cell = &contact_cell,
+        .origin = Vec2{1, 3.5},
+        .rotation = M_PI / 2,
+        .magnification = 0.25,
+    };
+    device_cell.reference_array.append(&contact_ref2);
+
+    // MAIN
+
+    char main_cell_name[] = "MAIN";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    Reference device_ref = {
+        .type = ReferenceType::Cell,
+        .cell = &device_cell,
+        .magnification = 1,
+        .repetition = {RepetitionType::Rectangular, 3, 2, Vec2{6, 7}},
+    };
+    main_cell.reference_array.append(&device_ref);
+
+    // Output
+
+    lib.write_gds("references.gds", 0, NULL);
+
+    for (uint64_t i = 0; i < COUNT(contact_poly); i++) contact_poly[i].clear();
+    cutout_poly.clear();
+    contact_cell.polygon_array.clear();
+    device_cell.polygon_array.clear();
+    device_cell.reference_array.clear();
+    main_cell.reference_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/references.svg +
+
+

Paths

+

Besides polygons, the GDSII and OASIS formats define paths, witch are +polygonal chains with +associated width and end caps. The width is a single number, constant +throughout the path, and the end caps can be flush, round (GDSII only), or +extended by a custom distance.

+

There is no specification for the joins between adjacent segments, so it is up +to the system using the file to specify those. Usually the joins are straight +extensions of the path boundaries up to some beveling limit. Gdstk also uses +this specification for the joins.

+

It is possible to circumvent all of the above limitations within Gdstk by +storing paths as polygons in the GDSII or OASIS file. The disadvantage of this +solution is that other software will not be able to edit the geometry as paths, +since that information is lost.

+

The construction of paths (either GDSII/OASIS paths or polygonal paths) in +Gdstk is based on gdstk.FlexPath and gdstk.RobustPath.

+
+

Flexible Paths

+

The class gdstk.FlexPath is a mirror of gdstk.Curve before, +with additional features to facilitate path creation:

+
    +
  • all curve construction methods are available;

  • +
  • path width can be easily controlled throughout the path;

  • +
  • end caps and joins can be specified by the user;

  • +
  • straight segments can be automatically joined by circular arcs;

  • +
  • multiple parallel paths can be designed simultaneously;

  • +
  • spacing between parallel paths is arbitrary - the user specifies the offset +of each path individually.

  • +
+
+
+
# Path defined by a sequence of points and stored as a GDSII path
+fp1 = gdstk.FlexPath(
+    [(0, 0), (3, 0), (3, 2), (5, 3), (3, 4), (0, 4)], 1, simple_path=True
+)
+
+# Other construction methods can still be used
+fp1.interpolation([(0, 2), (2, 2), (4, 3), (5, 1)], relative=True)
+
+# Multiple parallel paths separated by 0.5 with different widths,
+# end caps, and joins.  Because of the join specification, they
+# cannot be stared as GDSII paths, only as polygons.
+fp2 = gdstk.FlexPath(
+    [(12, 0), (8, 0), (8, 3), (10, 2)],
+    [0.3, 0.2, 0.4],
+    0.5,
+    ends=["extended", "flush", "round"],
+    joins=["bevel", "miter", "round"],
+)
+fp2.arc(2, -0.5 * numpy.pi, 0.5 * numpy.pi)
+fp2.arc(1, 0.5 * numpy.pi, 1.5 * numpy.pi)
+
+
+
+
+
Cell* example_flexpath1(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    FlexPath* fp = (FlexPath*)allocate_clear(sizeof(FlexPath));
+    fp->init(Vec2{0, 0}, 1, 0.5, 0, 0.01, 0);
+    fp->simple_path = true;
+
+    Vec2 points1[] = {{3, 0}, {3, 2}, {5, 3}, {3, 4}, {0, 4}};
+    fp->segment({.capacity = 0, .count = COUNT(points1), .items = points1}, NULL, NULL, false);
+
+    out_cell->flexpath_array.append(fp);
+
+    fp = (FlexPath*)allocate_clear(sizeof(FlexPath));
+    const double widths[] = {0.3, 0.2, 0.4};
+    const double offsets[] = {-0.5, 0, 0.5};
+    const Tag tags[] = {0, 0, 0};
+    fp->init(Vec2{12, 0}, 3, widths, offsets, 0.01, tags);
+
+    fp->elements[0].end_type = EndType::HalfWidth;
+    fp->elements[0].join_type = JoinType::Bevel;
+
+    fp->elements[1].end_type = EndType::Flush;
+    fp->elements[1].join_type = JoinType::Miter;
+
+    fp->elements[2].end_type = EndType::Round;
+    fp->elements[2].join_type = JoinType::Round;
+
+    Vec2 points2[] = {{8, 0}, {8, 3}, {10, 2}};
+    fp->segment({.capacity = 0, .count = COUNT(points2), .items = points2}, NULL, NULL, false);
+
+    fp->arc(2, 2, -M_PI / 2, M_PI / 2, 0, NULL, NULL);
+    fp->arc(1, 1, M_PI / 2, 1.5 * M_PI, 0, NULL, NULL);
+
+    out_cell->flexpath_array.append(fp);
+    return out_cell;
+}
+
+
+
+
+_images/flexible_paths.svg +

The corner type “circular bend” (together with the bend_radius argument) can +be used to automatically curve the path.

+
+
+
# Path created with automatic bends of radius 5
+points = [(0, 0), (0, 10), (20, 0), (18, 15), (8, 15)]
+fp3 = gdstk.FlexPath(points, 0.5, bend_radius=5, simple_path=True)
+
+# Same path, generated with natural joins, for comparison
+fp4 = gdstk.FlexPath(points, 0.5, layer=1, simple_path=True)
+
+
+
+
+
Cell* example_flexpath2(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    Vec2 points[] = {{0, 10}, {20, 0}, {18, 15}, {8, 15}};
+
+    for (uint64_t i = 0; i < 2; i++) {
+        FlexPath* fp = (FlexPath*)allocate_clear(sizeof(FlexPath));
+        fp->init(Vec2{0, 0}, 1, 0.5, 0, 0.01, 0);
+        fp->simple_path = true;
+        if (i == 0) {
+            fp->elements[0].bend_type = BendType::Circular;
+            fp->elements[0].bend_radius = 5;
+        } else {
+            fp->elements[0].tag = make_tag(1, 0);
+        }
+        fp->segment({.capacity = 0, .count = COUNT(points), .items = points}, NULL, NULL, false);
+        out_cell->flexpath_array.append(fp);
+    }
+
+    return out_cell;
+}
+
+
+
+
+_images/flexible_paths_2.svg +

Width and offset variations are possible throughout the path. Changes are +linearly tapered in the path section they are defined. Note that, because +width changes are not possible for GDSII/OASIS paths, they will be stored as +polygonal objects.

+
+
+
# Straight segment showing the possibility of width and offset changes
+fp5 = gdstk.FlexPath((0, 0), [0.5, 0.5], 1)
+fp5.horizontal(2)
+fp5.horizontal(4, width=0.8, offset=1.8)
+fp5.horizontal(6)
+
+
+
+
+
Cell* example_flexpath3(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    double widths[] = {0.5, 0.5};
+    double offsets[] = {-0.5, 0.5};
+    Tag tags[] = {0, 0};
+    FlexPath* fp = (FlexPath*)allocate_clear(sizeof(FlexPath));
+    fp->init(Vec2{0, 0}, 2, widths, offsets, 0.01, tags);
+
+    fp->horizontal(2, NULL, NULL, false);
+
+    widths[0] = 0.8;
+    widths[1] = 0.8;
+    offsets[0] = -0.9;
+    offsets[1] = 0.9;
+    fp->horizontal(4, widths, offsets, false);
+
+    fp->horizontal(6, NULL, NULL, false);
+
+    out_cell->flexpath_array.append(fp);
+
+    return out_cell;
+}
+
+
+
+
+_images/flexible_paths_3.svg +
+
+

Robust Paths

+

In some situations, gdstk.FlexPath is unable to properly calculate all +the joins. This often happens when the width or offset of the path is +relatively large with respect to the length of the segments being joined. +Curves that meet other curves or segments at sharp angles are a typical example +where this often happens.

+

The class gdstk.RobustPath can be used in such scenarios where curved +sections are expected to meet at sharp angles. The drawbacks of using +gdstk.RobustPath are the extra computational resources required to +calculate all joins and the impossibility of specifying joins. The advantages +are, as mentioned earlier, more robustness when generating the final geometry, +and freedom to use custom functions to parameterize the widths or offsets of +the paths.

+
+
+
# Create 4 parallel paths in different layers
+rp = gdstk.RobustPath(
+    (0, 50),
+    [2, 0.5, 1, 1],
+    [0, 0, -1, 1],
+    ends=["extended", "round", "flush", "flush"],
+    layer=[1, 0, 2, 2],
+)
+rp.segment((0, 45))
+rp.segment(
+    (0, 5),
+    width=[lambda u: 2 + 16 * u * (1 - u), 0.5, 1, 1],
+    offset=[
+        0,
+        lambda u: 8 * u * (1 - u) * numpy.cos(12 * numpy.pi * u),
+        lambda u: -1 - 8 * u * (1 - u),
+        lambda u: 1 + 8 * u * (1 - u),
+    ],
+)
+rp.segment((0, 0))
+rp.interpolation(
+    [(15, 5)],
+    angles=[0, 0.5 * numpy.pi],
+    width=0.5,
+    offset=[-0.25, 0.25, -0.75, 0.75],
+)
+rp.parametric(
+    lambda u: numpy.array((4 * numpy.sin(6 * numpy.pi * u), 45 * u)),
+    offset=[
+        lambda u: -0.25 * numpy.cos(24 * numpy.pi * u),
+        lambda u: 0.25 * numpy.cos(24 * numpy.pi * u),
+        -0.75,
+        0.75,
+    ],
+)
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+double parametric1(double u, void*) { return 2 + 16 * u * (1 - u); }
+
+double parametric2(double u, void*) { return 8 * u * (1 - u) * cos(12 * M_PI * u); }
+
+double parametric3(double u, void*) { return -1 - 8 * u * (1 - u); }
+
+double parametric4(double u, void*) { return 1 + 8 * u * (1 - u); }
+
+double parametric5(double u, void*) { return -0.25 * cos(24 * M_PI * u); }
+
+double parametric6(double u, void*) { return 0.25 * cos(24 * M_PI * u); }
+
+Vec2 parametric7(double u, void*) { return Vec2{4 * sin(6 * M_PI * u), 45 * u}; }
+
+int main(int argc, char* argv[]) {
+    double widths[] = {2, 0.5, 1, 1};
+    double offsets[] = {0, 0, -1, 1};
+    Tag tags[] = {make_tag(1, 0), make_tag(0, 0), make_tag(2, 0), make_tag(2, 0)};
+    RobustPath rp = {};
+    rp.init(Vec2{0, 50}, 4, widths, offsets, 0.01, 1000, tags);
+    rp.scale_width = true;
+    rp.elements[0].end_type = EndType::HalfWidth;
+    rp.elements[1].end_type = EndType::Round;
+    rp.elements[2].end_type = EndType::Flush;
+    rp.elements[3].end_type = EndType::Flush;
+
+    rp.segment(Vec2{0, 45}, NULL, NULL, false);
+
+    Interpolation width1[] = {
+        {.type = InterpolationType::Parametric},
+        {.type = InterpolationType::Constant},
+        {.type = InterpolationType::Constant},
+        {.type = InterpolationType::Constant},
+    };
+    width1[0].function = parametric1;
+    for (int i = 1; i < COUNT(width1); i++) {
+        width1[i].value = rp.elements[i].end_width;
+    }
+    Interpolation offset1[] = {
+        {.type = InterpolationType::Constant},
+        {.type = InterpolationType::Parametric},
+        {.type = InterpolationType::Parametric},
+        {.type = InterpolationType::Parametric},
+    };
+    offset1[0].value = 0;
+    offset1[1].function = parametric2;
+    offset1[2].function = parametric3;
+    offset1[3].function = parametric4;
+    rp.segment(Vec2{0, 5}, width1, offset1, false);
+
+    rp.segment(Vec2{0, 0}, NULL, NULL, false);
+
+    Vec2 point = {15, 5};
+    double angles[] = {0, M_PI / 2};
+    bool angle_constraints[] = {true, true};
+    Vec2 tension[] = {{1, 1}, {1, 1}};
+    Interpolation width2[] = {
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+    };
+    Interpolation offset2[] = {
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+        {.type = InterpolationType::Linear},
+    };
+    for (int i = 0; i < COUNT(width2); i++) {
+        width2[i].initial_value = rp.elements[i].end_width;
+        width2[i].final_value = 0.5;
+        offset2[i].initial_value = rp.elements[i].end_offset;
+    }
+    offset2[0].final_value = -0.25;
+    offset2[1].final_value = 0.25;
+    offset2[2].final_value = -0.75;
+    offset2[3].final_value = 0.75;
+    rp.interpolation({.capacity = 0, .count = 1, .items = &point}, angles, angle_constraints,
+                     tension, 1, 1, false, width2, offset2, false);
+
+    Interpolation offset3[] = {
+        {.type = InterpolationType::Parametric},
+        {.type = InterpolationType::Parametric},
+        {.type = InterpolationType::Constant},
+        {.type = InterpolationType::Constant},
+    };
+    offset3[0].function = parametric5;
+    offset3[1].function = parametric6;
+    offset3[2].value = -0.75;
+    offset3[3].value = 0.75;
+    rp.parametric(parametric7, NULL, NULL, NULL, NULL, offset3, true);
+
+    char robustpath_cell_name[] = "RobustPath";
+    Cell robustpath_cell = {.name = robustpath_cell_name};
+    robustpath_cell.robustpath_array.append(&rp);
+
+    char lib_name[] = "Paths";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+    lib.cell_array.append(&robustpath_cell);
+
+    lib.write_gds("robustpaths.gds", 0, NULL);
+
+    rp.clear();
+    robustpath_cell.robustpath_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/robust_paths.svg +

Note that, analogously to gdstk.FlexPath, gdstk.RobustPath +can be stored as a GDSII/OASIS path as long as its width is kept constant.

+
+
+
+

Text

+

In the context of a GDSII/OASIS file, text is supported in the form of labels, +which are ASCII annotations placed somewhere in the geometry of a given cell. +Similar to polygons, labels are tagged with layer and text type values (text +type is the label equivalent of the polygon data type). They are supported by +the class gdstk.Label.

+

Additionally, Gdstk offers the possibility of creating text as polygons to be +included with the geometry. The function gdstk.text() creates polygonal +text that can be used in the same way as any other polygons in Gdstk. The font +used to render the characters contains only horizontal and vertical edges, +which is important for some laser writing systems.

+
+
+
# Label centered at (1, 3)
+label = gdstk.Label("Sample label", (5, 3), texttype=2)
+
+# Horizontal text with height 2.25
+htext = gdstk.text("12345", 2.25, (0.25, 6))
+
+# Vertical text with height 1.5
+vtext = gdstk.text("ABC", 1.5, (10.5, 4), vertical=True)
+
+rect = gdstk.rectangle((0, 0), (10, 6), layer=10)
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    char lib_name[] = "Text";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    char text_cell_name[] = "Text";
+    Cell text_cell = {.name = text_cell_name};
+    lib.cell_array.append(&text_cell);
+
+    char label_text[] = "Sample label";
+    Label label = {
+        .tag = make_tag(0, 2),
+        .text = label_text,
+        .origin = Vec2{5, 3},
+        .magnification = 1,
+    };
+    text_cell.label_array.append(&label);
+
+    Array<Polygon*> all_text = {};
+    text("12345", 2.25, Vec2{0.25, 6}, false, 0, all_text);
+    text("ABC", 1.5, Vec2{10.5, 4}, true, 0, all_text);
+    text_cell.polygon_array.extend(all_text);
+
+    Polygon rect = rectangle(Vec2{0, 0}, Vec2{10, 6}, make_tag(10, 0));
+    text_cell.polygon_array.append(&rect);
+
+    lib.write_gds("text.gds", 0, NULL);
+
+    for (uint64_t i = 0; i < all_text.count; i++) {
+        all_text[i]->clear();
+        free_allocation(all_text[i]);
+    }
+    all_text.clear();
+    rect.clear();
+    text_cell.label_array.clear();
+    text_cell.polygon_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/text1.svg +
+
+

Geometry Operations

+

Gdstk offers a number of functions and methods to modify existing geometry. +The most useful operations include gdstk.boolean(), gdstk.slice(), +gdstk.offset(), and gdstk.Polygon.fillet().

+
+

Boolean Operations

+

Boolean operations (gdstk.boolean()) can be performed on polygons, paths +and whole cells. Four operations are defined: union (“or”), intersection +(“and”), subtraction (“not”), and symmetric difference (“xor”). They can be +computationally expensive, so it is usually advisable to avoid using boolean +operations whenever possible. If they are necessary, keeping the number of +vertices is all polygons as low as possible also helps.

+
+
+
# Create some text
+text = gdstk.text("GDSTK", 4, (0, 0))
+# Create a rectangle extending the text's bounding box by 1
+rect = gdstk.rectangle((-1, -1), (5 * 4 * 9 / 16 + 1, 4 + 1))
+
+# Subtract the text from the rectangle
+inv = gdstk.boolean(rect, text, "not")
+
+
+
+
+
Cell* example_boolean(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    Array<Polygon*> txt = {};
+    text("GDSTK", 4, Vec2{0, 0}, false, 0, txt);
+
+    Polygon rect = rectangle(Vec2{-1, -1}, Vec2{5 * 4 * 9 / 16 + 1, 4 + 1}, 0);
+
+    boolean(rect, txt, Operation::Not, 1000, out_cell->polygon_array);
+
+    for (int i = 0; i < txt.count; i++) {
+        txt[i]->clear();
+        free_allocation(txt[i]);
+    }
+    txt.clear();
+    rect.clear();
+
+    return out_cell;
+}
+
+
+
+
+_images/boolean_operations.svg +
+
+

Slice Operation

+

As the name indicates, a slice operation subdivides a set of polygons along +horizontal or vertical cut lines.

+
+
+
ring1 = gdstk.ellipse((-6, 0), 6, inner_radius=4)
+ring2 = gdstk.ellipse((0, 0), 6, inner_radius=4)
+ring3 = gdstk.ellipse((6, 0), 6, inner_radius=4)
+
+# Slice the first ring across x=-3, the second ring across x=-3
+# and x=3, and the third ring across x=3
+slices1 = gdstk.slice(ring1, -3, "x")
+slices2 = gdstk.slice(ring2, [-3, 3], "x")
+slices3 = gdstk.slice(ring3, 3, "x")
+
+slices = gdstk.Cell("SLICES")
+
+# Keep only the left side of slices1, the center part of slices2
+# and the right side of slices3
+slices.add(*slices1[0])
+slices.add(*slices2[1])
+slices.add(*slices3[1])
+
+
+
+
+
Cell* example_slice(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    Polygon ring[3];
+    ring[0] = ellipse(Vec2{-6, 0}, 6, 6, 4, 4, 0, 0, 0.01, 0);
+    ring[1] = ellipse(Vec2{0, 0}, 6, 6, 4, 4, 0, 0, 0.01, 0);
+    ring[2] = ellipse(Vec2{6, 0}, 6, 6, 4, 4, 0, 0, 0.01, 0);
+
+    double x[] = {-3, 3};
+    Array<double> cuts = {.capacity = 0, .count = 1, .items = x};
+    Array<Polygon*> result[3] = {};
+    slice(ring[0], cuts, true, 1000, result);
+    out_cell->polygon_array.extend(result[0]);
+    for (uint64_t i = 0; i < result[1].count; i++) {
+        result[1][i]->clear();
+        free_allocation(result[1][i]);
+    }
+    result[0].clear();
+    result[1].clear();
+
+    cuts.count = 2;
+    slice(ring[1], cuts, true, 1000, result);
+    out_cell->polygon_array.extend(result[1]);
+    for (uint64_t i = 0; i < result[0].count; i++) {
+        result[0][i]->clear();
+        free_allocation(result[0][i]);
+    }
+    for (uint64_t i = 0; i < result[2].count; i++) {
+        result[2][i]->clear();
+        free_allocation(result[2][i]);
+    }
+    result[0].clear();
+    result[1].clear();
+    result[2].clear();
+
+    cuts.count = 1;
+    cuts.items = x + 1;
+    slice(ring[2], cuts, true, 1000, result);
+    out_cell->polygon_array.extend(result[1]);
+    for (uint64_t i = 0; i < result[0].count; i++) {
+        result[0][i]->clear();
+        free_allocation(result[0][i]);
+    }
+    result[0].clear();
+    result[1].clear();
+
+    ring[0].clear();
+    ring[1].clear();
+    ring[2].clear();
+
+    return out_cell;
+}
+
+
+
+
+_images/slice_operation.svg +
+
+

Offset Operation

+

The function gdstk.offset() dilates or erodes polygons by a fixed amount. +It can operate on individual polygons or sets of them, in which case it may be +necessary to set use_union = True to remove the impact of inner edges. The +same is valid for polygons with holes.

+
+
+
rect1 = gdstk.rectangle((-4, -4), (1, 1))
+rect2 = gdstk.rectangle((-1, -1), (4, 4))
+
+# Erosion: because we set `use_union=True`, the inner boundaries have no effect
+outer = gdstk.offset([rect1, rect2], -0.5, use_union=True, layer=1)
+
+
+
+
+
Cell* example_offset(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    Polygon* rect = (Polygon*)allocate(sizeof(Polygon));
+    *rect = rectangle(Vec2{-4, -4}, Vec2{1, 1}, 0);
+    out_cell->polygon_array.append(rect);
+
+    rect = (Polygon*)allocate(sizeof(Polygon));
+    *rect = rectangle(Vec2{-1, -1}, Vec2{4, 4}, 0);
+    out_cell->polygon_array.append(rect);
+
+    uint64_t start = out_cell->polygon_array.count;
+    offset(out_cell->polygon_array, -0.5, OffsetJoin::Miter, 2, 1000, true,
+           out_cell->polygon_array);
+    for (uint64_t i = start; i < out_cell->polygon_array.count; i++) {
+        out_cell->polygon_array[i]->tag = make_tag(1, 0);
+    }
+
+    return out_cell;
+}
+
+
+
+
+_images/offset_operation.svg +
+
+

Fillet Operation

+

The method gdstk.Polygon.fillet() can be used to round polygon corners.

+
+
+
flexpath = gdstk.FlexPath([(-8, -4), (0, -4), (0, 4), (8, 4)], 4)
+filleted_path = flexpath.to_polygons()[0]
+filleted_path.fillet(1.5)
+
+
+
+
+
Cell* example_fillet(const char* name) {
+    Cell* out_cell = (Cell*)allocate_clear(sizeof(Cell));
+    out_cell->name = copy_string(name, NULL);
+
+    FlexPath flexpath = {};
+    flexpath.init(Vec2{-8, -4}, 1, 4, 0, 0.01, 0);
+    Vec2 points[] = {{0, -4}, {0, 4}, {8, 4}};
+    flexpath.segment({.capacity = 0, .count = COUNT(points), .items = points}, NULL, NULL, false);
+
+    Array<Polygon*> poly_array = {};
+    flexpath.to_polygons(false, 0, poly_array);
+    flexpath.clear();
+
+    double r = 1.5;
+    for (int i = 0; i < poly_array.count; i++)
+        poly_array[i]->fillet({.capacity = 0, .count = 1, .items = &r}, 0.01);
+
+    out_cell->polygon_array.extend(poly_array);
+    poly_array.clear();
+
+    return out_cell;
+}
+
+
+
+
+_images/fillet_operation.svg +
+
+
+

GDSII/OASIS Library

+

All the information used to create a GDSII/OASIS file is kept within an +instance of gdstk.Library. Besides all the geometric and hierarchical +information, this class also holds a name and the units for all entities. The +name can be any ASCII string — it is simply stored in the file and has no other +purpose in Gdstk. The units require some attention because they can impact the +resolution of the polygons in the library when written to a file.

+
+

A Note About Units

+

Two values are defined when creating a gdstk.Library: unit and +precision. The value of unit defines the unit size—in meters—for all +entities in the library. For example, if unit = 1e-6 (10⁻⁶ m, the default +value), a vertex at (1, 2) should be interpreted as a vertex in real world +position (1 × 10⁻⁶ m, 2 × 10⁻⁶ m). If unit changes to 0.001, then that +same vertex would be located (in real world coordinates) at (0.001 m, 0.002 m), +or (1 mm, 2 mm).

+

The value of precision has to do with the type used to store coordinates in the +GDSII file: signed 4-byte integers. Because of that, a finer coordinate grid +than 1 unit is usually desired to define coordinates. That grid is +defined, in meters, by precision, which defaults to 1e-9 (10⁻⁹ m). +When the GDSII file is written, all vertices are snapped to the grid defined by +precision. For example, for the default values of unit and +precision, a vertex at (1.0512, 0.0001) represents real world coordinates +(1.0512 × 10⁻⁶ m, 0.0001 × 10⁻⁶ m), or (1051.2 × 10⁻⁹ m, 0.1 × 10⁻⁹ m), which +will be rounded to integers: (1051 × 10⁻⁹ m, 0 × 10⁻⁹ m), or (1.051 × 10⁻⁶ m, 0 +× 10⁻⁶ m). The actual coordinate values written in the GDSII file will be the +integers (1051, 0). By reducing the value of precision from 10⁻⁹ m to +10⁻¹² m, for example, the coordinates will have 3 additional decimal places of +precision, so the stored values would be (1051200, 100).

+

The downside of increasing the number of decimal places in the file is reducing +the range of coordinates that can be stored (in real world units). That is +because the range of coordinate values that can be written in the file are +[-(2³²); 2³¹ - 1] = [-2,147,483,648; 2,147,483,647]. For the default +precsision, this range is [-2.147483648 m; 2.147483647 m]. If +precision is set to 10⁻¹² m, the same range is reduced by 1000 times: +[-2.147483648 mm; 2.147483647 mm].

+

GDSII files keep a record of both unit and precision, which means that +some care must be taken when mixing geometry from different files to ensure +they have the same unit. For that reason, the use of the industry standard +(unit = 1e-6) is recommended. OASIS files always use this standard for +units, whereas precision can be freely chosen. For that reason, when +saving or loading an OASIS file with Gdstk, the units can be automatic +converted.

+
+
+

Saving a Layout File

+

To save a GDSII file, simply use the gdstk.Library.write_gds() method, as +in the First Layout. An OASIS file can be similarly created with +gdstk.Library.write_oas().

+

An SVG image from a specific cell can also be exported through +gdstk.Cell.write_svg(), which was also demonstrated in +First Layout.

+
+
+

Loading a Layout File

+

The functions gdstk.read_gds() and gdstk.read_oas() load an +existing GDSII or OASIS file into a new instance of gdstk.Library.

+
+
+
# Load a GDSII file into a new library.
+lib1 = gdstk.read_gds("filename.gds")
+# Verify the unit used in the library.
+print(lib1.unit)
+
+# Load the same file, but convert all units to nm.
+lib2 = gdstk.read_gds("filename.gds", 1e-9)
+
+# Load an OASIS file into a third library.
+# The library will use unit=1e-6, the default for OASIS.
+lib3 = gdstk.read_oas("filename.oas")
+
+
+
+
+
// Use units from infile
+Library lib1 = read_gds("filename.gds", 0);
+
+// Convert to new unit
+Library lib2 = read_gds("filename.gds", 1e-9);
+
+// Use default OASIS unit (1e-6)
+Library lib3 = read_oas("filename.oas");
+
+
+
+
+

Access to the cells in the loaded library is primarily provided through the +list gdstk.Library.cells. As a shorthand, if the desired cell name is +know, the idiom lib1["CELL_NAME"] can be used, although it is not as +efficient as building a cell dictionary if a large number of queries is +expected.

+

Additionally, the method gdstk.Library.top_level() can be used to find +the top-level cells in the library (cells on the top of the hierarchy, i.e., +cell that are not referenced by any other cells).

+
+
+

Raw Cells

+

Library loaded using the previous method have all their elements interpreted +and re-created by Gdstk. This can be time-consuming for large layouts. If the +reason for loading a file is simply to re-use it’s cells without any +modifications, the function gdstk.read_rawcells() is much more efficient.

+
+
+
# Load all cells from a GDSII file without creating the actual geometry
+cells = gdstk.read_rawcells("filename.gds")
+
+# Use some loaded cell in the current design
+my_ref = gdstk.Reference(cells["SOME_CELL"], (0, 0))
+
+
+
+
+
Map<RawCell*> cells = read_rawcells("filename.gds");
+
+Reference my_ref = {};
+my_ref.init(cells.get("SOME_CELL"), 1);
+
+
+
+
+
+

Note

+

This method only works when using the GDSII format; OASIS does not support +gdstk.RawCell. Units are not changed in this process, so the +current design must use the same unit and precision as the loaded +cells.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/allocator.html b/headers/allocator.html new file mode 100644 index 000000000..bb5a60ec4 --- /dev/null +++ b/headers/allocator.html @@ -0,0 +1,171 @@ + + + + + + + allocator.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

allocator.h

+
#ifdef GDSTK_CUSTOM_ALLOCATOR
+
+void* allocate(uint64_t size);
+
+void* reallocate(void* ptr, uint64_t size);
+
+void* allocate_clear(uint64_t size);
+
+void free_allocation(void* ptr);
+
+#else  // GDSTK_CUSTOM_ALLOCATOR
+
+inline void* allocate(uint64_t size) { return malloc(size); };
+
+inline void* reallocate(void* ptr, uint64_t size) { return realloc(ptr, size); };
+
+inline void* allocate_clear(uint64_t size) { return calloc(1, size); };
+
+inline void free_allocation(void* ptr) { free(ptr); };
+
+#endif  // GDSTK_CUSTOM_ALLOCATOR
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/array.html b/headers/array.html new file mode 100644 index 000000000..6aef3ea5d --- /dev/null +++ b/headers/array.html @@ -0,0 +1,297 @@ + + + + + + + array.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

array.h

+
template <class T>
+struct Array {
+    uint64_t capacity;  // allocated capacity
+    uint64_t count;     // number of slots used
+    T* items;           // slots
+
+    T& operator[](uint64_t idx) { return items[idx]; }
+    const T& operator[](uint64_t idx) const { return items[idx]; }
+
+    void print(bool all) const {
+        printf("Array <%p>, count %" PRIu64 "/%" PRIu64 "\n", this, count, capacity);
+        if (all && count > 0) {
+            printf("<%p>", (void*)items[0]);
+            for (uint64_t i = 0; i < count; ++i) {
+                printf(" <%p>", (void*)items[i]);
+            }
+            putchar('\n');
+        }
+    }
+
+    void clear() {
+        if (items) free_allocation(items);
+        items = NULL;
+        capacity = 0;
+        count = 0;
+    }
+
+    bool contains(const T& item) const { return index(item) < count; }
+
+    // Return the index of an array item.  If the item is not found, return the
+    // array count.
+    uint64_t index(const T& item) const {
+        T* it = items;
+        for (uint64_t j = 0; j < count; j++)
+            if (*(it++) == item) return j;
+        return count;
+    }
+
+    void append(T item) {
+        if (count == capacity) {
+            capacity = capacity >= INITIAL_ARRAY_CAPACITY ? capacity * ARRAY_GROWTH_FACTOR
+                                                          : INITIAL_ARRAY_CAPACITY;
+            items = (T*)reallocate(items, sizeof(T) * capacity);
+        }
+        items[count++] = item;
+    }
+
+    // Does NOT check capacity. To be used after ensure_slots, for example.
+    void append_unsafe(T item) { items[count++] = item; }
+
+    // Insert item at specified index, pushing the remaining forward
+    void insert(uint64_t index_, T item) {
+        if (count == capacity) {
+            capacity = capacity >= INITIAL_ARRAY_CAPACITY ? capacity * ARRAY_GROWTH_FACTOR
+                                                          : INITIAL_ARRAY_CAPACITY;
+            items = (T*)reallocate(items, sizeof(T) * capacity);
+        }
+        if (index_ >= count) {
+            append_unsafe(item);
+        } else {
+            memmove(items + index_ + 1, items + index_, sizeof(T) * (count - index_));
+            items[index_] = item;
+            count++;
+        }
+    }
+
+    // Remove the item at index by substituting it with the last item in the
+    // array.
+    void remove_unordered(uint64_t index_) { items[index_] = items[--count]; }
+
+    // Remove the item at index and pull the remaining to fill the gap.
+    void remove(uint64_t index_) {
+        memmove(items + index_, items + index_ + 1, sizeof(T) * ((--count) - index_));
+    }
+
+    // Remove (ordered) the first occurrence of a specific item in the array.
+    // Return false if the item cannot be found.
+    bool remove_item(const T& item) {
+        uint64_t i = index(item);
+        if (i == count) return false;
+        remove(i);
+        return true;
+    }
+
+    // Ensure at least the specified number of free slots at the end
+    void ensure_slots(uint64_t free_slots) {
+        if (capacity < count + free_slots) {
+            capacity = count + free_slots;
+            items = (T*)reallocate(items, sizeof(T) * capacity);
+        }
+    }
+
+    // Extend the array by appending all elements from src (in order)
+    void extend(const Array<T>& src) {
+        ensure_slots(src.count);
+        memcpy(items + count, src.items, sizeof(T) * src.count);
+        count += src.count;
+    }
+
+    // The instance should be zeroed before copy_from
+    void copy_from(const Array<T>& src) {
+        capacity = src.count;
+        count = src.count;
+        if (count > 0) {
+            items = (T*)allocate(sizeof(T) * capacity);
+            memcpy(items, src.items, sizeof(T) * count);
+        } else {
+            items = NULL;
+        }
+    }
+};
+
+template <>
+inline void Array<Vec2>::print(bool all) const {
+    printf("Array <%p>, count %" PRIu64 "/%" PRIu64 "\n", this, count, capacity);
+    if (all && count > 0) {
+        printf("(%lg, %lg)", items[0].x, items[0].y);
+        for (uint64_t i = 1; i < count; ++i) {
+            printf(" (%lg, %lg)", items[i].x, items[i].y);
+        }
+        putchar('\n');
+    }
+}
+
+template <>
+inline void Array<IntVec2>::print(bool all) const {
+    printf("Array <%p>, count %" PRIu64 "/%" PRIu64 "\n", this, count, capacity);
+    if (all && count > 0) {
+        printf(" (%" PRId64 ", %" PRId64 ")", items[0].x, items[0].y);
+        for (uint64_t i = 1; i < count; ++i) {
+            printf(" (%" PRId64 ", %" PRId64 ")", items[i].x, items[i].y);
+        }
+        putchar('\n');
+    }
+}
+
+template <>
+inline void Array<double>::print(bool all) const {
+    printf("Array <%p>, count %" PRIu64 "/%" PRIu64 "\n", this, count, capacity);
+    if (all && count > 0) {
+        printf(" %lg", items[0]);
+        for (uint64_t i = 1; i < count; ++i) {
+            printf(" %lg", items[i]);
+        }
+        putchar('\n');
+    }
+}
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/cell.html b/headers/cell.html new file mode 100644 index 000000000..b959ef06b --- /dev/null +++ b/headers/cell.html @@ -0,0 +1,315 @@ + + + + + + + cell.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

cell.h

+
// Must return true if the first argument is ordered before (is less than) the
+// second argument.
+typedef bool (*PolygonComparisonFunction)(Polygon* const&, Polygon* const&);
+
+// This structure is used for caching bounding box and convex hull results from
+// cells.  This is a snapshot of the cells at a specific point in time.  It
+// must be invalidated whenever the cell contents changes.
+struct GeometryInfo {
+    Array<Vec2> convex_hull;
+    Vec2 bounding_box_min;
+    Vec2 bounding_box_max;
+
+    // These flags indicate whether the convex hull and bounding box values are
+    // valid, even when convex_hull.count == 0 or bounding_box_min.x >
+    // bounding_box_max.x (empty cell)
+    bool convex_hull_valid;
+    bool bounding_box_valid;
+
+    void clear() {
+        convex_hull.clear();
+        convex_hull_valid = false;
+        bounding_box_valid = false;
+    }
+};
+
+struct Cell {
+    // NULL-terminated string with cell name.  The GDSII specification allows
+    // only ASCII-encoded strings.  The OASIS specification restricts the
+    // allowed characters to the range 0x21–0x7E (the space character, 0x20, is
+    // forbidden).  Gdstk does NOT enforce either rule.
+    //
+    // Cells in a library are identified by their name, so names must be
+    // unique.  This rule is not enforced in Gdstk, but it is assumed to be
+    // followed (various hash maps are built based on cell names).
+    char* name;
+
+    // Elements should be added to (or removed from) the cell using these arrays
+    Array<Polygon*> polygon_array;
+    Array<Reference*> reference_array;
+    Array<FlexPath*> flexpath_array;
+    Array<RobustPath*> robustpath_array;
+    Array<Label*> label_array;
+
+    Property* properties;
+
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void init(const char* name_) { name = copy_string(name_, NULL); }
+
+    void print(bool all) const;
+
+    void clear();
+
+    void free_all() {
+        for (uint64_t j = 0; j < polygon_array.count; j++) {
+            polygon_array[j]->clear();
+            free_allocation(polygon_array[j]);
+        }
+        for (uint64_t j = 0; j < flexpath_array.count; j++) {
+            flexpath_array[j]->clear();
+            free_allocation(flexpath_array[j]);
+        }
+        for (uint64_t j = 0; j < robustpath_array.count; j++) {
+            robustpath_array[j]->clear();
+            free_allocation(robustpath_array[j]);
+        }
+        for (uint64_t j = 0; j < reference_array.count; j++) {
+            reference_array[j]->clear();
+            free_allocation(reference_array[j]);
+        }
+        for (uint64_t j = 0; j < label_array.count; j++) {
+            label_array[j]->clear();
+            free_allocation(label_array[j]);
+        }
+        clear();
+    }
+
+    // Bounding box corners are returned in min and max.  For an empty cell,
+    // return min.x > max.x.  Internally, this function simply calls the
+    // caching version with an empty cache.
+    void bounding_box(Vec2& min, Vec2& max) const;
+    // Caching version of the bounding box calculation.  The returned
+    // GeometryInfo is guaranteed to have the information about this cell
+    // instance (bounding_box_valid == true).
+    GeometryInfo bounding_box(Map<GeometryInfo>& cache) const;
+
+    // The convex hull of the cell is appended to result (it doesn't need to be
+    // empty).  Internally, this function simply calls the caching version with
+    // an empty cache.
+    void convex_hull(Array<Vec2>& result) const;
+    // Caching version of the convex hull calculation.
+    GeometryInfo convex_hull(Map<GeometryInfo>& cache) const;
+
+    // This cell instance must be zeroed before copy_from.  If a new_name is
+    // NULL, use the same name as the source cell.  If deep_copy == true, new
+    // elements (polygons, paths, references, and labels) are allocated and
+    // copied from the source cell.  Otherwise, the same pointers are used.
+    void copy_from(const Cell& cell, const char* new_name, bool deep_copy);
+
+    // Append a (newly allocated) copy of all the polygons in the cell to
+    // result.  If paths are included, their polygonal representation is
+    // calculated and also appended.  Polygons from references are included up
+    // to depth levels, i.e., if depth == 0, no polygons from references are
+    // included, depth == 1 includes polygons from referenced cells (with their
+    // transformation properly applied), but not from references thereof, and
+    // so on.  Depth < 0, removes the limit in the recursion depth.  If filter
+    // is true, only polygons with the indicated tag are appended.
+    void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth, bool filter,
+                      Tag tag, Array<Polygon*>& result) const;
+
+    // Similar to get_polygons, but for paths and labels.
+    void get_flexpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                       Array<FlexPath*>& result) const;
+    void get_robustpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                         Array<RobustPath*>& result) const;
+    void get_labels(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                    Array<Label*>& result) const;
+
+    // Insert all dependencies in result.  Dependencies are cells that appear
+    // in this cell's references. If recursive, include the whole dependency
+    // tree (dependencies of dependencies).
+    void get_dependencies(bool recursive, Map<Cell*>& result) const;
+    void get_raw_dependencies(bool recursive, Map<RawCell*>& result) const;
+
+    // Append all tags found in polygons and paths/labels to result.
+    // References are not included in the result.
+    void get_shape_tags(Set<Tag>& result) const;
+    void get_label_tags(Set<Tag>& result) const;
+
+    // Transform a cell hierarchy into a flat cell, with no dependencies, by
+    // inserting the elements from this cell's references directly into the
+    // cell (with the corresponding transformations).  Removed references are
+    // appended to removed_references.
+    void flatten(bool apply_repetitions, Array<Reference*>& removed_references);
+
+    // Change the tags of all elements in this cell.  Map keys are the current
+    // tags and map values are the desired new tags.  Elements in references
+    // are not remapped (use get_dependencies to loop over and remap them).
+    void remap_tags(const TagMap& map);
+
+    // These functions output the cell and its contents in the GDSII and SVG
+    // formats.  They are not supposed to be called by the user.  Use
+    // Library.write_gds and Cell.write_svg instead.
+    ErrorCode to_gds(FILE* out, double scaling, uint64_t max_points, double precision,
+                     const tm* timestamp) const;
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision, const char* attributes,
+                     PolygonComparisonFunction comp) const;
+
+    // Output this cell to filename in SVG format.  The geometry is drawn in
+    // the default units (px), but can be scaled freely.  Argument precision
+    // defines the maximum desired precision for floating point representation
+    // in the SVG file.  Arguments shape_style and label_style, if not NULL,
+    // can de used to customize the SVG style of elements by tag.  If
+    // background is not NULL, it should be a valid SVG color for the image
+    // background.  Argument pad defines the margin (in px) added around the
+    // cell bounding box, unless pad_as_percentage == true, in which case it is
+    // interpreted as a percentage of the largest bounding box dimension.
+    // Argument comp in to_svg can be used to sort the polygons in the SVG
+    // output, which affects their draw order.
+    ErrorCode write_svg(const char* filename, double scaling, uint32_t precision,
+                        StyleMap* shape_style, StyleMap* label_style, const char* background,
+                        double pad, bool pad_as_percentage, PolygonComparisonFunction comp) const;
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/clipper_tools.html b/headers/clipper_tools.html new file mode 100644 index 000000000..97377ce73 --- /dev/null +++ b/headers/clipper_tools.html @@ -0,0 +1,211 @@ + + + + + + + clipper_tools.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

clipper_tools.h

+
enum struct Operation { Or, And, Xor, Not };
+enum struct OffsetJoin { Miter, Bevel, Round };
+
+// The following operations are executed in an integer grid of vertices, so the
+// geometry should be scaled by a large enough factor to garante a minimal
+// precision level.  However, if the scaling factor is too large, it may cause
+// overflow of coordinates.  Resulting polygons are appended to result.
+
+// Boolean (clipping) operations on polygons
+ErrorCode boolean(const Array<Polygon*>& polys1, const Array<Polygon*>& polys2, Operation operation,
+                  double scaling, Array<Polygon*>& result);
+
+inline ErrorCode boolean(const Polygon& poly1, const Array<Polygon*>& polys2, Operation operation,
+                         double scaling, Array<Polygon*>& result) {
+    const Polygon* p1 = &poly1;
+    const Array<Polygon*> polys1 = {1, 1, (Polygon**)&p1};
+    return boolean(polys1, polys2, operation, scaling, result);
+}
+
+inline ErrorCode boolean(const Array<Polygon*>& polys1, const Polygon& poly2, Operation operation,
+                         double scaling, Array<Polygon*>& result) {
+    const Polygon* p2 = &poly2;
+    const Array<Polygon*> polys2 = {1, 1, (Polygon**)&p2};
+    return boolean(polys1, polys2, operation, scaling, result);
+}
+
+inline ErrorCode boolean(const Polygon& poly1, const Polygon& poly2, Operation operation,
+                         double scaling, Array<Polygon*>& result) {
+    const Polygon* p1 = &poly1;
+    const Polygon* p2 = &poly2;
+    const Array<Polygon*> polys1 = {1, 1, (Polygon**)&p1};
+    const Array<Polygon*> polys2 = {1, 1, (Polygon**)&p2};
+    return boolean(polys1, polys2, operation, scaling, result);
+}
+
+// Shorthand for joining a set of polygons
+inline ErrorCode merge(const Array<Polygon*>& polygons, double scaling, Array<Polygon*>& result) {
+    const Array<Polygon*> empty = {};
+    return boolean(polygons, empty, Operation::Or, scaling, result);
+}
+
+// Dilates or erodes polygons according to distance (negative distance results
+// in erosion).  The effects of internal polygon edges (in polygons with holes,
+// for example) can be suppressed by setting use_union to true.  Resulting
+// polygons are appended to result.
+ErrorCode offset(const Array<Polygon*>& polys, double distance, OffsetJoin join, double tolerance,
+                 double scaling, bool use_union, Array<Polygon*>& result);
+
+inline ErrorCode offset(const Polygon& poly, double distance, OffsetJoin join, double tolerance,
+                        double scaling, bool use_union, Array<Polygon*>& result) {
+    const Polygon* p = &poly;
+    const Array<Polygon*> polys = {1, 1, (Polygon**)&p};
+    return offset(polys, distance, join, tolerance, scaling, use_union, result);
+}
+
+// Slice the given polygon along the coordinates in positions.  Positions must be sorted.  Cuts are
+// vertical (horizontal) when x_axis is set to true (false).  Argument result must be an array with
+// length at least positions.count + 1.  The resulting slices are appended to the arrays in their
+// respective bins.
+ErrorCode slice(const Polygon& polygon, const Array<double>& positions, bool x_axis, double scaling,
+                Array<Polygon*>* result);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/curve.html b/headers/curve.html new file mode 100644 index 000000000..c1f588370 --- /dev/null +++ b/headers/curve.html @@ -0,0 +1,304 @@ + + + + + + + curve.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

curve.h

+
struct CurveInstruction {
+    union {
+        char command;
+        double number;
+    };
+};
+
+// Curves can used to build complex shapes by concatenating straight or curved
+// sections.  Once complete, their point_array can be used to create a polygon.
+// They are also used to build the FlexPath spine.
+struct Curve {
+    // Before appending any section to a curve, it must contain at least 1
+    // point in its point_array
+    Array<Vec2> point_array;
+
+    // Tolerance for approximating curved sections with straight lines
+    double tolerance;
+
+    // Used internally.  Keep record of the last Bézier control point, which is
+    // used for smooth continuations.
+    Vec2 last_ctrl;
+
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void print(bool all) const;
+
+    // Point array must be in a valid state before initialization
+    void init(const Vec2 initial_position, double tolerance_) {
+        point_array.append(initial_position);
+        tolerance = tolerance_;
+    }
+
+    // This curve instance must be zeroed before copy_from
+    void copy_from(const Curve& curve) {
+        point_array.copy_from(curve.point_array);
+        tolerance = curve.tolerance;
+        last_ctrl = curve.last_ctrl;
+    }
+
+    void clear() { point_array.clear(); }
+
+    void append(const Vec2 v) { point_array.append(v); }
+
+    void append_unsafe(const Vec2 v) { point_array.append_unsafe(v); }
+
+    void remove(uint64_t index) { point_array.remove(index); }
+
+    void ensure_slots(uint64_t free_slots) { point_array.ensure_slots(free_slots); }
+
+    // A curve is considered closed if the distance between the first and last
+    // points is less then of equal to tolerance
+    bool closed() const {
+        if (point_array.count < 2) return false;
+        const Vec2 v = point_array[0] - point_array[point_array.count - 1];
+        return v.length_sq() <= tolerance * tolerance;
+    }
+
+    // In the following functions, the flag relative indicates whether the
+    // points are given relative to the last point in the curve.  If multiple
+    // coordinates are used, all coordinates are relative to the same reference
+    // (last curve point at the time of execution)
+    void horizontal(double coord_x, bool relative);
+    void horizontal(const Array<double> coord_x, bool relative);
+    void vertical(double coord_y, bool relative);
+    void vertical(const Array<double> coord_y, bool relative);
+    void segment(Vec2 end_point, bool relative);
+    void segment(const Array<Vec2> points, bool relative);
+
+    // Every 3 points define a cubic Bézier section with 2 control points
+    // followed by the section end point (starting point being the current last
+    // point of the curve)
+    void cubic(const Array<Vec2> points, bool relative);
+
+    // Every 2 points define a cubic Bézier section with 1 control point
+    // followed by the section end point (starting point being the current last
+    // point of the curve and the first control calculated from the previous
+    // curve section for continuity)
+    void cubic_smooth(const Array<Vec2> points, bool relative);
+
+    // Every 2 points define a quadratic Bézier section with 1 control point
+    // followed by the section end point (starting point being the current last
+    // point of the curve)
+    void quadratic(const Array<Vec2> points, bool relative);
+
+    // Quadratic Bézier section with control point calculated from the previous
+    // curve section for continuity
+    void quadratic_smooth(Vec2 end_point, bool relative);
+
+    // Every point is used as the end point of a quadratic Bézier section (the
+    // control point is calculated from the previous curve section for
+    // continuity)
+    void quadratic_smooth(const Array<Vec2> points, bool relative);
+
+    // Single Bézier section defined by any number of control points
+    void bezier(const Array<Vec2> points, bool relative);
+
+    // Create a smooth interpolation curve through points using cubic Bézier
+    // sections.  The angle at any point i can be constrained to the value
+    // angles[i] if angle_constraints[i] is true.  The tension array controls
+    // the input and output tensions of the curve at each point (the input at
+    // the first point and output at the last point are only meaningful for
+    // closed curves).  Because the first point of the interpolation is the
+    // last point in the curve, the lengths of the arrays angles,
+    // angle_constraints, and tension must be points.count + 1.  No argument
+    // can be NULL.
+    void interpolation(const Array<Vec2> points, double* angles, bool* angle_constraints,
+                       Vec2* tension, double initial_curl, double final_curl, bool cycle,
+                       bool relative);
+
+    // Add an elliptical arc to the curve. Argument rotation is used to rotate
+    // the axes of the ellipse.
+    void arc(double radius_x, double radius_y, double initial_angle, double final_angle,
+             double rotation);
+
+    // Add a parametric curve section to the curve.  If relative is true,
+    // curve_function(0, data) should be (0, 0) for the curve to be continuous.
+    void parametric(ParametricVec2 curve_function, void* data, bool relative);
+
+    // Short-hand function for appending several sections at once.  Array items
+    // must be formed by a series of instruction characters followed by the
+    // correct number of arguments for that instruction.  Instruction
+    // characters and arguments are:
+    // - Line segment:            'L', x, y
+    // - Horizontal segment:      'H', x
+    // - Vertical segment:        'V', y
+    // - Cubic Bézier:            'C', x0, y0, x1, y1, x2, y2
+    // - Smooth cubic Bézier:     'S', x0, y0, x1, y1
+    // - Quadratic Bézier:        'Q', x0, y0, x1, y1
+    // - Smooth quadratic Bézier: 'T', x, y
+    // - Elliptical arc:          'E', rad0, rad1, angle0, angle1, rotation
+    // - Circular arc:            'A', radius, angle0, angle1
+    // - Circular turn:           'a', radius, angle
+    // Coordinates in instructions L, H, V, C, S, Q and T are absolute.  Lower
+    // case versions of those instructions can be used for relative coordinates
+    // (in this case, each section will be relative to the previous).  Return
+    // the number of items processed.  If n < count, item n could not be
+    // parsed.
+    uint64_t commands(const CurveInstruction* items, uint64_t count);
+
+    // Add a circular arc to the curve ensuring continuity.  Positive
+    // (negative) angles create counter-clockwise (clockwise) turns.
+    void turn(double radius, double angle) {
+        const Vec2 direction = point_array[point_array.count - 1] - last_ctrl;
+        double initial_angle = direction.angle() + (angle < 0 ? 0.5 * M_PI : -0.5 * M_PI);
+        arc(radius, radius, initial_angle, initial_angle + angle, 0);
+    }
+
+   private:
+    void append_cubic(const Vec2 p0, const Vec2 p1, const Vec2 p2, const Vec2 p3);
+    void append_quad(const Vec2 p0, const Vec2 p1, const Vec2 p2);
+    void append_bezier(const Array<Vec2> ctrl);
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/flexpath.html b/headers/flexpath.html new file mode 100644 index 000000000..29bf99135 --- /dev/null +++ b/headers/flexpath.html @@ -0,0 +1,297 @@ + + + + + + + flexpath.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

flexpath.h

+
// A flexpath holds a spine and any number of elements.  The spine dictates the
+// general shape of the path, but it is a simple curve, it doesn't have
+// information about width.  The elements are the concrete paths that are
+// created based on the spine, a width and, optionally, an offset from the
+// spine.  Both width and offset can change along the spine.
+
+struct FlexPathElement {
+    Tag tag;
+
+    // Array of widths and offsets for this path element.  The array count must
+    // match the spine count.  Each Vec2 v holds the width of the path divided
+    // by 2 in v.e[0] and the path offset in v.e[1] for the respective point
+    // along the spine.
+    Array<Vec2> half_width_and_offset;
+
+    JoinType join_type;
+    JoinFunction join_function;
+    void* join_function_data;  // User data passed directly to join_function
+
+    EndType end_type;
+    Vec2 end_extensions;
+    EndFunction end_function;
+    void* end_function_data;  // User data passed directly to end_function
+
+    BendType bend_type;
+    double bend_radius;
+    BendFunction bend_function;
+    void* bend_function_data;  // User data passed directly to bend_function
+};
+
+struct FlexPath {
+    Curve spine;
+    FlexPathElement* elements;  // Array with count num_elements
+    uint64_t num_elements;
+
+    // If simple_path is true, all elements will be treated as if they have
+    // constant widths (using the first elements in their respective
+    // half_width_and_offset arrays) and saved as paths, not polygonal
+    // boundaries.
+    bool simple_path;
+
+    // Flag indicating whether the width of the path elements should be scaled
+    // when scaling the path (manually or through references).
+    bool scale_width;
+
+    Repetition repetition;
+    Property* properties;
+
+    RaithData raith_data;
+
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    // These are initialization routines to facilitate the creation of new
+    // flexpaths.  In versions with argument num_elements_, the elements array
+    // will be dynamically allocated (and num_elements properly set).
+    // Otherwise, num_elements and elements are expected to be already
+    // allocated and set.  Arguments width, offset and tag can be single values
+    // (which are applied to all elements) or arrays with count num_elements,
+    // one value for each path element.  Argument separation is the desired
+    // distance between adjacent elements.
+    void init(const Vec2 initial_position, double width, double offset, double tolerance, Tag tag);
+    void init(const Vec2 initial_position, const double* width, const double* offset,
+              double tolerance, const Tag* tag);
+    void init(const Vec2 initial_position, uint64_t num_elements_, double width, double separation,
+              double tolerance, Tag tag);
+    void init(const Vec2 initial_position, uint64_t num_elements_, const double* width,
+              const double* offset, double tolerance, const Tag* tag);
+
+    void print(bool all) const;
+
+    void clear();
+
+    // This path instance must be zeroed before copy_from
+    void copy_from(const FlexPath& path);
+
+    void translate(const Vec2 v);
+    void scale(double scale, const Vec2 center);
+    void mirror(const Vec2 p0, const Vec2 p1);
+    void rotate(double angle, const Vec2 center);
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and translating by origin at the end.  This is equivalent
+    // to the transformation defined by a Reference with the same arguments.
+    void transform(double magnification, bool x_reflection, double rotation, const Vec2 origin);
+
+    // Append the copies of this path defined by its repetition to result.
+    void apply_repetition(Array<FlexPath*>& result);
+
+    // These functions are equivalent to those for curves (curve.h), with the
+    // addition of width and offset, which can be NULL (no width or offset
+    // changes) or arrays with count num_elements.
+    void horizontal(double coord_x, const double* width, const double* offset, bool relative);
+    void horizontal(const Array<double> coord_x, const double* width, const double* offset,
+                    bool relative);
+    void vertical(double coord_y, const double* width, const double* offset, bool relative);
+    void vertical(const Array<double> coord_y, const double* width, const double* offset,
+                  bool relative);
+    void segment(Vec2 end_point, const double* width, const double* offset, bool relative);
+    void segment(const Array<Vec2> point_array, const double* width, const double* offset,
+                 bool relative);
+    void cubic(const Array<Vec2> point_array, const double* width, const double* offset,
+               bool relative);
+    void cubic_smooth(const Array<Vec2> point_array, const double* width, const double* offset,
+                      bool relative);
+    void quadratic(const Array<Vec2> point_array, const double* width, const double* offset,
+                   bool relative);
+    void quadratic_smooth(Vec2 end_point, const double* width, const double* offset, bool relative);
+    void quadratic_smooth(const Array<Vec2> point_array, const double* width, const double* offset,
+                          bool relative);
+    void bezier(const Array<Vec2> point_array, const double* width, const double* offset,
+                bool relative);
+    void interpolation(const Array<Vec2> point_array, double* angles, bool* angle_constraints,
+                       Vec2* tension, double initial_curl, double final_curl, bool cycle,
+                       const double* width, const double* offset, bool relative);
+    void arc(double radius_x, double radius_y, double initial_angle, double final_angle,
+             double rotation, const double* width, const double* offset);
+    void turn(double radius, double angle, const double* width, const double* offset);
+    void parametric(ParametricVec2 curve_function, void* data, const double* width,
+                    const double* offset, bool relative);
+    uint64_t commands(const CurveInstruction* items, uint64_t count);
+
+    // Append the polygonal representation of this path to result.  If filter
+    // is true, only elements with the indicated tag are processed.
+    // Overlapping points are removed from the path before any processing is
+    // executed.
+    ErrorCode to_polygons(bool filter, Tag tag, Array<Polygon*>& result);
+
+    // Calculate the center of an element of this path and append the resulting
+    // curve to result.
+    ErrorCode element_center(const FlexPathElement* el, Array<Vec2>& result);
+
+    // These functions output the polygon in the GDSII, OASIS and SVG formats.
+    // They are not supposed to be called by the user.  Because fracturing
+    // occurs at cell_to_gds, the polygons must be checked there and, if
+    // needed, fractured.  Therefore, to_gds should be used only when
+    // simple_path == true to produce true GDSII path elements.  The same is
+    // valid for to_oas, even though no fracturing ever occurs for OASIS files.
+    ErrorCode to_gds(FILE* out, double scaling);
+    ErrorCode to_oas(OasisStream& out, OasisState& state);
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision);
+
+   private:
+    void remove_overlapping_points();
+    void fill_offsets_and_widths(const double* width, const double* offset);
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/font.html b/headers/font.html new file mode 100644 index 000000000..2ee0ab921 --- /dev/null +++ b/headers/font.html @@ -0,0 +1,361 @@ + + + + + + + font.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

font.h

+
// Public Domain version of the unscii-16 font from http://pelulamu.net/unscii/
+// codepoints 0x21 thru 0x7F
+
+// This header contains the data for the default font in Gdstk, used in the
+// text function.  Given a desired code point CP within the range of defined
+// code points, we use it to index into arrays _num_polys and _first_poly:
+//
+// _num_poly[CP - FIRST_CODEPOINT] = p_count is the number of polygons in the
+// requested glyph.
+//
+// _first_poly[CP - FIRST_CODEPOINT] = p_idx is the index into _num_coords and
+// _first_coord.
+//
+// _num_coords[p_idx] = c_count is the number of coordinates in polygon p_idx
+// (counting x and y separately, so it is always an even number).  The polygon
+// p_idx can be drawn using c_count coordinates from _first_coord:
+//
+// (_first_coord[p_idx], _first_coord[p_idx + 1]),
+// …,
+// (_first_coord[p_idx + c_count - 2], _first_coord[p_idx + c_count - 1])
+//
+// To draw the remaining polygons in the glyph, keep incrementing p_idx to draw
+// all p_count polygons.
+
+// Font metrics
+#define FIRST_CODEPOINT 0x21
+#define HORIZONTAL_STEP 9
+#define HORIZONTAL_TAB (4 * HORIZONTAL_STEP)
+#define HORIZONTAL_LINESKIP 20
+#define VERTICAL_STEP (2 * HORIZONTAL_STEP)
+#define VERTICAL_TAB (4 * VERTICAL_STEP)
+#define VERTICAL_LINESKIP 16
+
+const Vec2 _all_coords[] = {
+    5, 7,  5, 15, 3, 15, 3, 7,  5, 3,  5, 5,  3, 5,  3, 3,  3, 12, 3, 15, 1, 15, 1, 12, 7, 12,
+    7, 15, 5, 15, 5, 12, 3, 3,  3, 6,  4, 6,  4, 3,  6, 3,  6, 6,  7, 6,  7, 7,  6, 7,  6, 10,
+    7, 10, 7, 11, 6, 11, 6, 14, 4, 14, 4, 11, 3, 11, 3, 14, 1, 14, 1, 11, 0, 11, 0, 10, 1, 10,
+    1, 7,  3, 7,  3, 10, 4, 10, 4, 7,  3, 7,  1, 7,  0, 7,  0, 6,  1, 6,  1, 3,  2, 4,  3, 4,
+    3, 2,  5, 2,  5, 4,  6, 4,  6, 5,  7, 5,  7, 7,  6, 7,  6, 8,  5, 8,  5, 9,  4, 9,  4, 10,
+    3, 10, 3, 12, 5, 12, 5, 11, 7, 11, 7, 12, 6, 12, 6, 13, 5, 13, 5, 15, 3, 15, 3, 13, 2, 13,
+    2, 12, 1, 12, 1, 10, 2, 10, 2, 9,  3, 9,  3, 8,  4, 8,  4, 7,  5, 7,  5, 5,  3, 5,  3, 6,
+    1, 6,  1, 5,  2, 5,  4, 12, 4, 10, 3, 10, 3, 8,  2, 8,  2, 6,  1, 6,  1, 4,  0, 4,  0, 2,
+    2, 2,  2, 4,  3, 4,  3, 6,  4, 6,  4, 8,  5, 8,  5, 10, 6, 10, 6, 12, 7, 12, 7, 14, 5, 14,
+    5, 12, 2, 10, 2, 13, 0, 13, 0, 10, 7, 3,  7, 6,  5, 6,  5, 3,  1, 9,  1, 8,  0, 8,  0, 4,
+    1, 4,  1, 3,  4, 3,  4, 4,  2, 4,  2, 8,  3, 8,  3, 7,  4, 7,  4, 4,  5, 4,  5, 3,  7, 3,
+    7, 4,  6, 4,  6, 7,  7, 7,  7, 9,  6, 9,  6, 8,  5, 8,  5, 9,  4, 9,  4, 10, 5, 10, 5, 11,
+    6, 11, 6, 13, 5, 13, 5, 14, 2, 14, 2, 13, 1, 13, 1, 11, 3, 11, 3, 13, 4, 13, 4, 11, 3, 11,
+    1, 11, 2, 11, 2, 9,  2, 12, 2, 11, 4, 11, 4, 12, 5, 12, 5, 15, 3, 15, 3, 12, 3, 12, 2, 12,
+    2, 5,  3, 5,  3, 3,  4, 3,  4, 2,  6, 2,  6, 3,  5, 3,  5, 5,  4, 5,  4, 12, 5, 12, 5, 14,
+    6, 14, 6, 15, 4, 15, 4, 14, 3, 14, 3, 12, 4, 12, 4, 5,  3, 5,  3, 3,  2, 3,  2, 2,  4, 2,
+    4, 3,  5, 3,  5, 5,  6, 5,  6, 12, 5, 12, 5, 14, 4, 14, 4, 15, 2, 15, 2, 14, 3, 14, 2, 10,
+    2, 9,  0, 9,  0, 8,  2, 8,  2, 7,  1, 7,  1, 5,  3, 5,  3, 7,  5, 7,  5, 5,  7, 5,  7, 7,
+    6, 7,  6, 8,  8, 8,  8, 9,  6, 9,  6, 10, 7, 10, 7, 12, 5, 12, 5, 10, 3, 10, 3, 12, 1, 12,
+    1, 10, 1, 9,  1, 8,  3, 8,  3, 5,  5, 5,  5, 8,  7, 8,  7, 9,  5, 9,  5, 12, 3, 12, 3, 9,
+    3, 3,  2, 3,  2, 2,  1, 2,  1, 1,  3, 1,  3, 2,  4, 2,  4, 3,  5, 3,  5, 6,  2, 6,  2, 5,
+    3, 5,  7, 9,  1, 9,  1, 8,  7, 8,  5, 3,  5, 6,  3, 6,  3, 3,  5, 14, 5, 12, 4, 12, 4, 10,
+    3, 10, 3, 8,  2, 8,  2, 6,  1, 6,  1, 4,  0, 4,  0, 2,  2, 2,  2, 4,  3, 4,  3, 6,  4, 6,
+    4, 8,  5, 8,  5, 10, 6, 10, 6, 12, 7, 12, 7, 14, 8, 14, 8, 16, 6, 16, 6, 14, 6, 5,  7, 5,
+    7, 12, 6, 12, 6, 13, 5, 13, 5, 14, 2, 14, 2, 13, 1, 13, 1, 12, 0, 12, 0, 5,  2, 5,  2, 7,
+    3, 7,  3, 8,  2, 8,  2, 12, 3, 12, 3, 13, 4, 13, 4, 12, 5, 12, 5, 10, 4, 10, 4, 9,  5, 9,
+    5, 5,  4, 5,  4, 4,  3, 4,  3, 5,  2, 5,  0, 5,  1, 5,  1, 4,  2, 4,  2, 3,  5, 3,  5, 4,
+    6, 4,  4, 9,  3, 9,  3, 8,  4, 8,  2, 12, 1, 12, 1, 11, 3, 11, 3, 4,  1, 4,  1, 3,  7, 3,
+    7, 4,  5, 4,  5, 14, 3, 14, 3, 13, 2, 13, 1, 11, 3, 11, 3, 13, 5, 13, 5, 9,  4, 9,  4, 8,
+    3, 8,  3, 7,  2, 7,  2, 6,  1, 6,  1, 3,  7, 3,  7, 4,  3, 4,  3, 6,  4, 6,  4, 7,  5, 7,
+    5, 8,  6, 8,  6, 9,  7, 9,  7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 2, 4,  2, 3,  6, 3,
+    6, 4,  7, 4,  7, 8,  6, 8,  6, 9,  7, 9,  7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 1, 11,
+    3, 11, 3, 13, 5, 13, 5, 9,  3, 9,  3, 8,  5, 8,  5, 4,  3, 4,  3, 6,  1, 6,  1, 4,  6, 3,
+    6, 7,  7, 7,  7, 8,  6, 8,  6, 14, 4, 14, 4, 13, 3, 13, 3, 12, 2, 12, 2, 11, 1, 11, 1, 10,
+    0, 10, 0, 8,  2, 8,  2, 10, 3, 10, 3, 11, 4, 11, 4, 8,  2, 8,  0, 8,  0, 7,  4, 7,  4, 3,
+    2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  7, 9,  6, 9,  6, 10, 3, 10, 3, 13, 7, 13, 7, 14, 1, 14,
+    1, 9,  5, 9,  5, 4,  3, 4,  3, 6,  1, 6,  1, 4,  7, 9,  6, 9,  6, 10, 3, 10, 3, 12, 4, 12,
+    4, 13, 6, 13, 6, 14, 3, 14, 3, 13, 2, 13, 2, 12, 1, 12, 1, 4,  3, 4,  3, 9,  5, 9,  5, 4,
+    3, 4,  1, 4,  2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  5, 10, 4, 10, 4, 8,  3, 8,  3, 3,  5, 3,
+    5, 8,  6, 8,  6, 10, 7, 10, 7, 14, 1, 14, 1, 13, 5, 13, 7, 8,  6, 8,  6, 9,  7, 9,  7, 13,
+    6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 1, 10, 3, 10, 3, 13, 5, 13, 5, 9,  4, 9,  4, 10, 3, 10,
+    1, 10, 1, 9,  2, 9,  2, 8,  1, 8,  1, 4,  3, 4,  3, 8,  4, 8,  4, 7,  5, 7,  5, 4,  3, 4,
+    1, 4,  2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  5, 5,  4, 5,  4, 4,  2, 4,  2, 3,  5, 3,  5, 4,
+    6, 4,  6, 5,  7, 5,  7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 1, 9,  3, 9,  3, 13, 5, 13,
+    5, 9,  3, 9,  1, 9,  2, 9,  2, 8,  5, 8,  5, 10, 5, 13, 3, 13, 3, 10, 5, 3,  5, 6,  3, 6,
+    3, 3,  5, 10, 5, 13, 3, 13, 3, 10, 3, 3,  2, 3,  2, 2,  1, 2,  1, 1,  3, 1,  3, 2,  4, 2,
+    4, 3,  5, 3,  5, 6,  2, 6,  2, 5,  3, 5,  4, 11, 3, 11, 3, 10, 2, 10, 2, 9,  1, 9,  1, 8,
+    2, 8,  2, 7,  3, 7,  3, 6,  4, 6,  4, 5,  5, 5,  5, 4,  7, 4,  7, 5,  6, 5,  6, 6,  5, 6,
+    5, 7,  4, 7,  4, 8,  3, 8,  3, 9,  4, 9,  4, 10, 5, 10, 5, 11, 6, 11, 6, 12, 7, 12, 7, 13,
+    5, 13, 5, 12, 4, 12, 7, 11, 1, 11, 1, 10, 7, 10, 7, 7,  1, 7,  1, 6,  7, 6,  2, 11, 3, 11,
+    3, 10, 4, 10, 4, 9,  5, 9,  5, 8,  4, 8,  4, 7,  3, 7,  3, 6,  2, 6,  2, 5,  1, 5,  1, 4,
+    3, 4,  3, 5,  4, 5,  4, 6,  5, 6,  5, 7,  6, 7,  6, 8,  7, 8,  7, 9,  6, 9,  6, 10, 5, 10,
+    5, 11, 4, 11, 4, 12, 3, 12, 3, 13, 1, 13, 1, 12, 2, 12, 1, 12, 3, 12, 3, 14, 5, 14, 5, 11,
+    4, 11, 4, 10, 3, 10, 3, 7,  5, 7,  5, 10, 6, 10, 6, 11, 7, 11, 7, 14, 6, 14, 6, 15, 2, 15,
+    2, 14, 1, 14, 5, 3,  5, 5,  3, 5,  3, 3,  0, 4,  1, 4,  1, 3,  6, 3,  6, 4,  2, 4,  2, 13,
+    5, 13, 5, 10, 3, 10, 3, 6,  6, 6,  6, 7,  7, 7,  7, 13, 6, 13, 6, 14, 1, 14, 1, 13, 0, 13,
+    3, 3,  3, 8,  5, 8,  5, 3,  7, 3,  7, 12, 6, 12, 6, 13, 5, 13, 5, 14, 3, 14, 3, 13, 2, 13,
+    2, 12, 1, 12, 1, 9,  3, 9,  3, 12, 5, 12, 5, 9,  3, 9,  1, 9,  1, 3,  7, 7,  6, 7,  6, 8,
+    5, 8,  5, 9,  6, 9,  6, 10, 7, 10, 7, 13, 6, 13, 6, 14, 1, 14, 1, 9,  3, 9,  3, 13, 5, 13,
+    5, 10, 4, 10, 4, 9,  3, 9,  1, 9,  1, 4,  3, 4,  3, 8,  4, 8,  4, 7,  5, 7,  5, 4,  3, 4,
+    1, 4,  1, 3,  6, 3,  6, 4,  7, 4,  1, 4,  2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  7, 6,  5, 6,
+    5, 4,  3, 4,  3, 13, 5, 13, 5, 11, 7, 11, 7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 6, 5,
+    7, 5,  7, 12, 6, 12, 6, 13, 5, 13, 5, 14, 1, 14, 1, 4,  3, 4,  3, 13, 4, 13, 4, 12, 5, 12,
+    5, 5,  4, 5,  4, 4,  3, 4,  1, 4,  1, 3,  5, 3,  5, 4,  6, 4,  7, 3,  7, 4,  3, 4,  3, 8,
+    6, 8,  6, 9,  3, 9,  3, 13, 7, 13, 7, 14, 1, 14, 1, 3,  3, 3,  3, 9,  6, 9,  6, 10, 3, 10,
+    3, 13, 7, 13, 7, 14, 1, 14, 1, 3,  1, 4,  2, 4,  2, 3,  7, 3,  7, 9,  4, 9,  4, 8,  5, 8,
+    5, 4,  3, 4,  3, 13, 5, 13, 5, 11, 7, 11, 7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 3, 3,
+    3, 8,  5, 8,  5, 3,  7, 3,  7, 14, 5, 14, 5, 9,  3, 9,  3, 14, 1, 14, 1, 3,  1, 4,  1, 3,
+    7, 3,  7, 4,  5, 4,  5, 13, 7, 13, 7, 14, 1, 14, 1, 13, 3, 13, 3, 4,  2, 4,  2, 3,  6, 3,
+    6, 4,  7, 4,  7, 14, 5, 14, 5, 4,  3, 4,  3, 6,  1, 6,  1, 4,  2, 3,  2, 8,  3, 8,  3, 7,
+    4, 7,  4, 5,  5, 5,  5, 3,  7, 3,  7, 5,  6, 5,  6, 7,  5, 7,  5, 8,  4, 8,  4, 9,  5, 9,
+    5, 10, 6, 10, 6, 12, 7, 12, 7, 14, 5, 14, 5, 12, 4, 12, 4, 10, 3, 10, 3, 9,  2, 9,  2, 14,
+    0, 14, 0, 3,  7, 3,  7, 4,  3, 4,  3, 14, 1, 14, 1, 3,  2, 3,  2, 10, 3, 10, 3, 8,  4, 8,
+    4, 10, 5, 10, 5, 3,  7, 3,  7, 14, 5, 14, 5, 13, 4, 13, 4, 11, 3, 11, 3, 13, 2, 13, 2, 14,
+    0, 14, 0, 3,  2, 3,  2, 8,  3, 8,  3, 7,  4, 7,  4, 5,  5, 5,  5, 3,  7, 3,  7, 14, 5, 14,
+    5, 9,  4, 9,  4, 10, 3, 10, 3, 12, 2, 12, 2, 14, 0, 14, 0, 3,  7, 13, 6, 13, 6, 14, 2, 14,
+    2, 13, 1, 13, 1, 4,  3, 4,  3, 13, 5, 13, 5, 4,  3, 4,  1, 4,  2, 4,  2, 3,  6, 3,  6, 4,
+    7, 4,  3, 3,  3, 8,  6, 8,  6, 9,  7, 9,  7, 13, 6, 13, 6, 14, 1, 14, 1, 9,  3, 9,  3, 13,
+    5, 13, 5, 9,  3, 9,  1, 9,  1, 3,  4, 2,  5, 2,  5, 1,  7, 1,  7, 2,  6, 2,  6, 4,  7, 4,
+    7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 1, 4,  3, 4,  3, 13, 5, 13, 5, 4,  3, 4,  1, 4,
+    2, 4,  2, 3,  4, 3,  3, 3,  3, 8,  4, 8,  4, 7,  5, 7,  5, 3,  7, 3,  7, 7,  6, 7,  6, 9,
+    7, 9,  7, 13, 6, 13, 6, 14, 1, 14, 1, 9,  3, 9,  3, 13, 5, 13, 5, 9,  3, 9,  1, 9,  1, 3,
+    2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  7, 7,  6, 7,  6, 8,  5, 8,  5, 9,  4, 9,  4, 10, 3, 10,
+    3, 13, 5, 13, 5, 11, 7, 11, 7, 13, 6, 13, 6, 14, 2, 14, 2, 13, 1, 13, 1, 10, 2, 10, 2, 9,
+    3, 9,  3, 8,  4, 8,  4, 7,  5, 7,  5, 4,  3, 4,  3, 6,  1, 6,  1, 4,  5, 3,  5, 13, 7, 13,
+    7, 14, 1, 14, 1, 13, 3, 13, 3, 3,  2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  7, 14, 5, 14, 5, 4,
+    3, 4,  3, 14, 1, 14, 1, 4,  2, 7,  2, 5,  3, 5,  3, 3,  5, 3,  5, 5,  6, 5,  6, 7,  7, 7,
+    7, 14, 5, 14, 5, 7,  3, 7,  3, 14, 1, 14, 1, 7,  2, 3,  2, 4,  3, 4,  3, 6,  4, 6,  4, 4,
+    5, 4,  5, 3,  7, 3,  7, 14, 5, 14, 5, 7,  4, 7,  4, 9,  3, 9,  3, 7,  2, 7,  2, 14, 0, 14,
+    0, 3,  1, 12, 1, 11, 2, 11, 2, 10, 3, 10, 3, 7,  2, 7,  2, 6,  1, 6,  1, 5,  0, 5,  0, 3,
+    2, 3,  2, 5,  3, 5,  3, 6,  5, 6,  5, 5,  6, 5,  6, 3,  8, 3,  8, 5,  7, 5,  7, 6,  6, 6,
+    6, 7,  5, 7,  5, 10, 6, 10, 6, 11, 7, 11, 7, 12, 8, 12, 8, 14, 6, 14, 6, 12, 5, 12, 5, 11,
+    3, 11, 3, 12, 2, 12, 2, 14, 0, 14, 0, 12, 1, 12, 1, 10, 2, 10, 2, 9,  3, 9,  3, 3,  5, 3,
+    5, 9,  6, 9,  6, 10, 7, 10, 7, 12, 8, 12, 8, 14, 6, 14, 6, 12, 5, 12, 5, 10, 3, 10, 3, 12,
+    2, 12, 2, 14, 0, 14, 0, 12, 5, 11, 4, 11, 4, 9,  3, 9,  3, 8,  2, 8,  2, 6,  1, 6,  1, 3,
+    7, 3,  7, 4,  3, 4,  3, 6,  4, 6,  4, 8,  5, 8,  5, 9,  6, 9,  6, 11, 7, 11, 7, 14, 1, 14,
+    1, 13, 5, 13, 6, 2,  6, 3,  4, 3,  4, 14, 6, 14, 6, 15, 2, 15, 2, 2,  1, 14, 1, 12, 2, 12,
+    2, 10, 3, 10, 3, 8,  4, 8,  4, 6,  5, 6,  5, 4,  6, 4,  6, 2,  8, 2,  8, 4,  7, 4,  7, 6,
+    6, 6,  6, 8,  5, 8,  5, 10, 4, 10, 4, 12, 3, 12, 3, 14, 2, 14, 2, 16, 0, 16, 0, 14, 4, 3,
+    2, 3,  2, 2,  6, 2,  6, 15, 2, 15, 2, 14, 4, 14, 2, 13, 1, 13, 1, 11, 0, 11, 0, 9,  2, 9,
+    2, 11, 3, 11, 3, 13, 4, 13, 4, 11, 5, 11, 5, 9,  7, 9,  7, 11, 6, 11, 6, 13, 5, 13, 5, 14,
+    4, 14, 4, 15, 3, 15, 3, 14, 2, 14, 8, 1,  0, 1,  0, 0,  8, 0,  4, 13, 4, 12, 5, 12, 5, 11,
+    7, 11, 7, 12, 6, 12, 6, 13, 5, 13, 5, 15, 3, 15, 3, 13, 6, 9,  6, 10, 2, 10, 2, 9,  5, 9,
+    5, 8,  2, 8,  2, 7,  1, 7,  1, 4,  3, 4,  3, 7,  5, 7,  5, 4,  3, 4,  1, 4,  2, 4,  2, 3,
+    7, 3,  7, 9,  7, 9,  6, 9,  6, 10, 3, 10, 3, 14, 1, 14, 1, 4,  3, 4,  3, 9,  5, 9,  5, 4,
+    3, 4,  1, 4,  1, 3,  6, 3,  6, 4,  7, 4,  1, 4,  2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  7, 5,
+    5, 5,  5, 4,  3, 4,  3, 9,  5, 9,  5, 8,  7, 8,  7, 9,  6, 9,  6, 10, 2, 10, 2, 9,  1, 9,
+    5, 14, 5, 10, 2, 10, 2, 9,  1, 9,  1, 4,  3, 4,  3, 9,  5, 9,  5, 4,  3, 4,  1, 4,  2, 4,
+    2, 3,  7, 3,  7, 14, 2, 4,  2, 3,  6, 3,  6, 4,  3, 4,  3, 6,  7, 6,  7, 9,  6, 9,  6, 10,
+    2, 10, 2, 9,  1, 9,  1, 7,  3, 7,  3, 9,  5, 9,  5, 7,  3, 7,  1, 7,  1, 4,  2, 10, 1, 10,
+    1, 9,  2, 9,  2, 3,  4, 3,  4, 9,  7, 9,  7, 10, 4, 10, 4, 13, 7, 13, 7, 14, 3, 14, 3, 13,
+    2, 13, 5, 1,  1, 1,  1, 0,  6, 0,  6, 1,  7, 1,  7, 10, 2, 10, 2, 9,  1, 9,  1, 4,  3, 4,
+    3, 9,  5, 9,  5, 4,  3, 4,  1, 4,  2, 4,  2, 3,  5, 3,  3, 3,  3, 9,  5, 9,  5, 3,  7, 3,
+    7, 9,  6, 9,  6, 10, 3, 10, 3, 14, 1, 14, 1, 3,  5, 12, 5, 14, 3, 14, 3, 12, 3, 3,  7, 3,
+    7, 4,  5, 4,  5, 10, 1, 10, 1, 9,  3, 9,  6, 12, 6, 14, 4, 14, 4, 12, 1, 1,  1, 0,  5, 0,
+    5, 1,  6, 1,  6, 10, 4, 10, 4, 1,  3, 3,  3, 6,  4, 6,  4, 5,  5, 5,  5, 3,  7, 3,  7, 5,
+    6, 5,  6, 6,  5, 6,  5, 7,  6, 7,  6, 8,  7, 8,  7, 10, 5, 10, 5, 8,  4, 8,  4, 7,  3, 7,
+    3, 14, 1, 14, 1, 3,  3, 3,  7, 3,  7, 4,  5, 4,  5, 14, 1, 14, 1, 13, 3, 13, 2, 3,  2, 8,
+    3, 8,  3, 4,  4, 4,  4, 8,  5, 8,  5, 3,  7, 3,  7, 9,  6, 9,  6, 10, 4, 10, 4, 9,  2, 9,
+    2, 10, 0, 10, 0, 3,  3, 3,  3, 9,  5, 9,  5, 3,  7, 3,  7, 9,  6, 9,  6, 10, 1, 10, 1, 3,
+    7, 9,  6, 9,  6, 10, 2, 10, 2, 9,  1, 9,  1, 4,  3, 4,  3, 9,  5, 9,  5, 4,  3, 4,  1, 4,
+    2, 4,  2, 3,  6, 3,  6, 4,  7, 4,  3, 0,  3, 3,  6, 3,  6, 4,  7, 4,  7, 9,  6, 9,  6, 10,
+    1, 10, 1, 4,  3, 4,  3, 9,  5, 9,  5, 4,  3, 4,  1, 4,  1, 0,  5, 0,  7, 0,  7, 10, 2, 10,
+    2, 9,  1, 9,  1, 4,  3, 4,  3, 9,  5, 9,  5, 4,  3, 4,  1, 4,  2, 4,  2, 3,  5, 3,  3, 3,
+    3, 9,  5, 9,  5, 7,  7, 7,  7, 9,  6, 9,  6, 10, 1, 10, 1, 3,  1, 7,  2, 7,  2, 6,  5, 6,
+    5, 4,  1, 4,  1, 3,  6, 3,  6, 4,  7, 4,  7, 6,  6, 6,  6, 7,  3, 7,  3, 9,  7, 9,  7, 10,
+    2, 10, 2, 9,  1, 9,  1, 10, 1, 9,  2, 9,  2, 4,  3, 4,  3, 3,  7, 3,  7, 4,  4, 4,  4, 9,
+    7, 9,  7, 10, 4, 10, 4, 13, 2, 13, 2, 10, 2, 4,  2, 3,  7, 3,  7, 10, 5, 10, 5, 4,  3, 4,
+    3, 10, 1, 10, 1, 4,  2, 5,  2, 4,  3, 4,  3, 3,  5, 3,  5, 4,  6, 4,  6, 5,  7, 5,  7, 10,
+    5, 10, 5, 5,  3, 5,  3, 10, 1, 10, 1, 5,  1, 5,  1, 3,  3, 3,  3, 4,  4, 4,  4, 3,  6, 3,
+    6, 5,  7, 5,  7, 10, 5, 10, 5, 5,  4, 5,  4, 8,  3, 8,  3, 5,  2, 5,  2, 10, 0, 10, 0, 5,
+    1, 8,  1, 7,  2, 7,  2, 6,  1, 6,  1, 5,  0, 5,  0, 3,  2, 3,  2, 5,  3, 5,  3, 6,  4, 6,
+    4, 5,  5, 5,  5, 3,  7, 3,  7, 5,  6, 5,  6, 6,  5, 6,  5, 7,  6, 7,  6, 8,  7, 8,  7, 10,
+    5, 10, 5, 8,  4, 8,  4, 7,  3, 7,  3, 8,  2, 8,  2, 10, 0, 10, 0, 8,  2, 4,  2, 3,  5, 3,
+    5, 1,  2, 1,  2, 0,  6, 0,  6, 1,  7, 1,  7, 10, 5, 10, 5, 4,  3, 4,  3, 10, 1, 10, 1, 4,
+    5, 8,  4, 8,  4, 7,  3, 7,  3, 6,  2, 6,  2, 5,  1, 5,  1, 3,  7, 3,  7, 4,  3, 4,  3, 5,
+    4, 5,  4, 6,  5, 6,  5, 7,  6, 7,  6, 8,  7, 8,  7, 10, 1, 10, 1, 9,  5, 9,  3, 9,  0, 9,
+    0, 8,  3, 8,  3, 3,  4, 3,  4, 2,  7, 2,  7, 3,  5, 3,  5, 8,  4, 8,  4, 9,  5, 9,  5, 14,
+    7, 14, 7, 15, 4, 15, 4, 14, 3, 14, 5, 2,  5, 16, 3, 16, 3, 2,  2, 9,  3, 9,  3, 8,  2, 8,
+    2, 3,  0, 3,  0, 2,  3, 2,  3, 3,  4, 3,  4, 8,  7, 8,  7, 9,  4, 9,  4, 14, 3, 14, 3, 15,
+    0, 15, 0, 14, 2, 14, 0, 12, 1, 12, 1, 13, 2, 13, 2, 14, 3, 14, 3, 12, 6, 12, 6, 13, 7, 13,
+    7, 15, 6, 15, 6, 14, 5, 14, 5, 13, 4, 13, 4, 15, 1, 15, 1, 14, 0, 14, 2, 6,  2, 8,  1, 8,
+    1, 14, 2, 14, 2, 16, 0, 16, 0, 6,  3, 8,  3, 14, 2, 14, 2, 8,  5, 10, 5, 2,  6, 2,  6, 10,
+    7, 10, 7, 12, 4, 12, 4, 10,
+};
+
+uint16_t _first_poly[] = {
+    0,  2,  4,  5,  6,  9,  10, 11, 12, 13,  14,  15,  16,  17,  18,  19,  21, 22, 23, 24,
+    25, 26, 27, 28, 29, 30, 32, 34, 35, 37,  38,  40,  41,  42,  43,  44,  45, 46, 47, 48,
+    49, 50, 51, 52, 53, 54, 55, 56, 57, 58,  59,  60,  61,  62,  63,  64,  65, 66, 67, 68,
+    69, 70, 71, 72, 73, 74, 75, 76, 77, 78,  79,  80,  81,  83,  85,  86,  87, 88, 89, 90,
+    91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 108,
+};
+
+uint16_t _num_polys[] = {
+    2, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0,
+};
+
+uint16_t _first_coord[] = {
+    0,    4,    8,    12,   16,   50,   94,   118,  122,  126,  172,  180,  200,  220,  248,  260,
+    274,  278,  282,  310,  352,  356,  370,  400,  428,  455,  475,  501,  515,  552,  578,  582,
+    586,  590,  604,  640,  644,  648,  684,  704,  708,  728,  751,  785,  805,  828,  840,  850,
+    870,  882,  894,  906,  938,  944,  964,  984,  1002, 1019, 1043, 1066, 1102, 1110, 1122, 1138,
+    1158, 1202, 1226, 1250, 1258, 1286, 1294, 1318, 1322, 1334, 1354, 1371, 1391, 1407, 1428, 1444,
+    1464, 1476, 1480, 1488, 1492, 1500, 1524, 1532, 1550, 1560, 1578, 1595, 1611, 1621, 1641, 1657,
+    1667, 1683, 1703, 1739, 1755, 1779, 1799, 1803, 1823, 1843, 1851, 1855,
+};
+
+uint16_t _num_coords[] = {
+    4,  4,  4,  4,  34, 44, 24, 4,  4,  46, 8,  20, 20, 28, 12, 14, 4,  4,  28, 42, 4,  14,
+    30, 28, 27, 20, 26, 14, 37, 26, 4,  4,  4,  14, 36, 4,  4,  36, 20, 4,  20, 23, 34, 20,
+    23, 12, 10, 20, 12, 12, 12, 32, 6,  20, 20, 18, 17, 24, 23, 36, 8,  12, 16, 20, 44, 24,
+    24, 8,  28, 8,  24, 4,  12, 20, 17, 20, 16, 21, 16, 20, 12, 4,  8,  4,  8,  24, 8,  18,
+    10, 18, 17, 16, 10, 20, 16, 10, 16, 20, 36, 16, 24, 20, 4,  20, 20, 8,  4,  8,
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/gdsii.html b/headers/gdsii.html new file mode 100644 index 000000000..901d19318 --- /dev/null +++ b/headers/gdsii.html @@ -0,0 +1,233 @@ + + + + + + + gdsii.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdsii.h

+
enum struct GdsiiRecord : uint8_t {
+    HEADER = 0X00,
+    BGNLIB = 0X01,
+    LIBNAME = 0X02,
+    UNITS = 0X03,
+    ENDLIB = 0X04,
+    BGNSTR = 0X05,
+    STRNAME = 0X06,
+    ENDSTR = 0X07,
+    BOUNDARY = 0X08,
+    PATH = 0X09,
+    SREF = 0X0A,
+    AREF = 0X0B,
+    TEXT = 0X0C,
+    LAYER = 0X0D,
+    DATATYPE = 0X0E,
+    WIDTH = 0X0F,
+    XY = 0X10,
+    ENDEL = 0X11,
+    SNAME = 0X12,
+    COLROW = 0X13,
+    TEXTNODE = 0X14,
+    NODE = 0X15,
+    TEXTTYPE = 0X16,
+    PRESENTATION = 0X17,
+    SPACING = 0X18,
+    STRING = 0X19,
+    STRANS = 0X1A,
+    MAG = 0X1B,
+    ANGLE = 0X1C,
+    UINTEGER = 0X1D,
+    USTRING = 0X1E,
+    REFLIBS = 0X1F,
+    FONTS = 0X20,
+    PATHTYPE = 0X21,
+    GENERATIONS = 0X22,
+    ATTRTABLE = 0X23,
+    STYPTABLE = 0X24,
+    STRTYPE = 0X25,
+    ELFLAGS = 0X26,
+    ELKEY = 0X27,
+    LINKTYPE = 0X28,
+    LINKKEYS = 0X29,
+    NODETYPE = 0X2A,
+    PROPATTR = 0X2B,
+    PROPVALUE = 0X2C,
+    BOX = 0X2D,
+    BOXTYPE = 0X2E,
+    PLEX = 0X2F,
+    BGNEXTN = 0X30,
+    ENDEXTN = 0X31,
+    TAPENUM = 0X32,
+    TAPECODE = 0X33,
+    STRCLASS = 0X34,
+    RESERVED = 0X35,
+    FORMAT = 0X36,
+    MASK = 0X37,
+    ENDMASKS = 0X38,
+    LIBDIRSIZE = 0X39,
+    SRFNAME = 0X3A,
+    LIBSECUR = 0X3B,
+    RAITHMBMSPATH = 0x5A,
+    RAITHPXXDATA = 0x62,
+};
+
+enum struct GdsiiDataType : uint8_t {
+    NoData = 0,
+    BitArray = 1,
+    TwoByteSignedInteger = 2,
+    FourByteSignedInteger = 3,
+    FourByteReal = 4,
+    EightByteReal = 5,
+    AsciiString = 6
+};
+
+uint64_t gdsii_real_from_double(double value);
+
+double gdsii_real_to_double(uint64_t real);
+
+// Read a record and swaps only first 2 bytes (record length).  The size of the
+// buffer must be passed in buffer_count.  On return, the record length
+// (including header) is returned in buffer_count.
+ErrorCode gdsii_read_record(FILE* in, uint8_t* buffer, uint64_t& buffer_count);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/gdstk.html b/headers/gdstk.html new file mode 100644 index 000000000..951560850 --- /dev/null +++ b/headers/gdstk.html @@ -0,0 +1,204 @@ + + + + + + + gdstk.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.h

+
/*
+Copyright 2020 Lucas Heitzmann Gabrielli.
+This file is part of gdstk, distributed under the terms of the
+Boost Software License - Version 1.0.  See the accompanying
+LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
+*/
+
+#ifndef GDSTK_HEADER_GDSTK
+#define GDSTK_HEADER_GDSTK
+
+#define __STDC_FORMAT_MACROS 1
+#define _USE_MATH_DEFINES
+
+#define GDSTK_VERSION "0.9.53"
+
+// If GDSTK_CUSTOM_ALLOCATOR is defined, the user must supply implementations
+// for the following dynamic memory management functions:
+// void* allocate(uint64_t size);
+// void* reallocate(void* ptr, uint64_t size);
+// void* allocate_clear(uint64_t size);
+// void free_allocation(void* ptr);
+// They will be used throughout the library instead of malloc, realloc, calloc
+// and free.
+//
+// #define GDSTK_CUSTOM_ALLOCATOR
+
+// After installation, this should be the only header required to be included
+// by the user.  All other headers are included below.
+
+#include "array.hpp"
+#include "cell.hpp"
+#include "clipper_tools.hpp"
+#include "curve.hpp"
+#include "flexpath.hpp"
+#include "gdsii.hpp"
+#include "gdswriter.hpp"
+#include "label.hpp"
+#include "library.hpp"
+#include "map.hpp"
+#include "oasis.hpp"
+#include "pathcommon.hpp"
+#include "polygon.hpp"
+#include "raithdata.hpp"
+#include "rawcell.hpp"
+#include "reference.hpp"
+#include "repetition.hpp"
+#include "robustpath.hpp"
+#include "set.hpp"
+#include "sort.hpp"
+#include "style.hpp"
+#include "utils.hpp"
+#include "vec.hpp"
+
+#endif
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/gdswriter.html b/headers/gdswriter.html new file mode 100644 index 000000000..4b0427776 --- /dev/null +++ b/headers/gdswriter.html @@ -0,0 +1,237 @@ + + + + + + + gdswriter.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdswriter.h

+
// Struct used to write GDSII files incrementally, so that not all cells need
+// to be held in memory simultaneously.  It should not be created manually, but
+// through gdswriter_init.  Once created, use write_cell and write_rawcell to
+// output all layout cells as needed, then call close to finalize the GDSII
+// file.
+struct GdsWriter {
+    FILE* out;
+    double unit;
+    double precision;
+    uint64_t max_points;
+    tm timestamp;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    ErrorCode write_cell(Cell& cell) const {
+        return cell.to_gds(out, unit / precision, max_points, precision, &timestamp);
+    }
+
+    ErrorCode write_rawcell(RawCell& rawcell) const { return rawcell.to_gds(out); }
+
+    void close() {
+        uint16_t buffer_end[] = {4, 0x0400};
+        big_endian_swap16(buffer_end, COUNT(buffer_end));
+        fwrite(buffer_end, sizeof(uint16_t), COUNT(buffer_end), out);
+        fclose(out);
+    }
+};
+
+// Create a GDSII file with the given filename for output and write the header
+// information to the file.  If max_points > 4, polygons written from
+// write_cell will be fractured to max_points.  GDSII files include a
+// timestamp, which can be specified by the caller or left NULL, in which case
+// the current time will be used.  If not NULL, any errors will be reported
+// through error_code.
+inline GdsWriter gdswriter_init(const char* filename, const char* library_name, double unit,
+                                double precision, uint64_t max_points, tm* timestamp,
+                                ErrorCode* error_code) {
+    GdsWriter result = {NULL, unit, precision, max_points};
+
+    if (timestamp) {
+        result.timestamp = *timestamp;
+    } else {
+        get_now(result.timestamp);
+    }
+
+    result.out = fopen(filename, "wb");
+    if (result.out == NULL) {
+        fputs("[GDSTK] Unable to open GDSII file for output.\n", error_logger);
+        if (error_code) *error_code = ErrorCode::OutputFileOpenError;
+        return result;
+    }
+
+    uint64_t len = strlen(library_name);
+    if (len % 2) len++;
+    uint16_t buffer_start[] = {6,
+                               0x0002,
+                               0x0258,
+                               28,
+                               0x0102,
+                               (uint16_t)(result.timestamp.tm_year + 1900),
+                               (uint16_t)(result.timestamp.tm_mon + 1),
+                               (uint16_t)result.timestamp.tm_mday,
+                               (uint16_t)result.timestamp.tm_hour,
+                               (uint16_t)result.timestamp.tm_min,
+                               (uint16_t)result.timestamp.tm_sec,
+                               (uint16_t)(result.timestamp.tm_year + 1900),
+                               (uint16_t)(result.timestamp.tm_mon + 1),
+                               (uint16_t)result.timestamp.tm_mday,
+                               (uint16_t)result.timestamp.tm_hour,
+                               (uint16_t)result.timestamp.tm_min,
+                               (uint16_t)result.timestamp.tm_sec,
+                               (uint16_t)(4 + len),
+                               0x0206};
+    big_endian_swap16(buffer_start, COUNT(buffer_start));
+    fwrite(buffer_start, sizeof(uint16_t), COUNT(buffer_start), result.out);
+    fwrite(library_name, 1, len, result.out);
+
+    uint16_t buffer_units[] = {20, 0x0305};
+    big_endian_swap16(buffer_units, COUNT(buffer_units));
+    fwrite(buffer_units, sizeof(uint16_t), COUNT(buffer_units), result.out);
+    uint64_t units[] = {gdsii_real_from_double(precision / unit),
+                        gdsii_real_from_double(precision)};
+    big_endian_swap64(units, COUNT(units));
+    fwrite(units, sizeof(uint64_t), COUNT(units), result.out);
+    return result;
+}
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/label.html b/headers/label.html new file mode 100644 index 000000000..7bdeb01af --- /dev/null +++ b/headers/label.html @@ -0,0 +1,195 @@ + + + + + + + label.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

label.h

+
enum struct Anchor { NW = 0, N = 1, NE = 2, W = 4, O = 5, E = 6, SW = 8, S = 9, SE = 10 };
+
+struct Label {
+    Tag tag;
+    char* text;  // NULL-terminated text string
+    Vec2 origin;
+    Anchor anchor;         // Text anchor (not supported by OASIS)
+    double rotation;       // in radians (not supported by OASIS)
+    double magnification;  // (not supported by OASIS)
+    bool x_reflection;     // (not supported by OASIS)
+    Repetition repetition;
+    Property* properties;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void init(const char* text_) {
+        text = copy_string(text_, NULL);
+        magnification = 1.0;
+    }
+
+    void print();
+
+    void clear();
+
+    // This label instance must be zeroed before copy_from
+    void copy_from(const Label& label);
+
+    // Bounding box corners are returned in min and max.  Repetitions are taken
+    // into account for the calculation.
+    void bounding_box(Vec2& min, Vec2& max) const;
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and translating by origin at the end.  This is equivalent
+    // to the transformation defined by a Reference with the same arguments.
+    void transform(double mag, bool x_refl, double rot, const Vec2 orig);
+
+    // Append the copies of this label defined by its repetition to result.
+    void apply_repetition(Array<Label*>& result);
+
+    // These functions output the label in the GDSII and SVG formats.  They are
+    // not supposed to be called by the user.
+    ErrorCode to_gds(FILE* out, double scaling) const;
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision) const;
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/library.html b/headers/library.html new file mode 100644 index 000000000..4c591d5c9 --- /dev/null +++ b/headers/library.html @@ -0,0 +1,333 @@ + + + + + + + library.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

library.h

+
struct Library {
+    // NULL-terminated string with library name.  The GDSII specification
+    // allows only ASCII-encoded strings.  Gdstk does NOT enforce either rule.
+    // The name is not used in OASIS files.
+    char* name;
+
+    // Unit and precision used to define the library geometry.  Please see the
+    // discussion about these values in the accompanying HTML documentation or
+    // at https://heitzmann.github.io/gdstk/gettingstarted.html
+    double unit;
+    double precision;
+
+    // Cells should be added to (or removed from) the library using these
+    // arrays.  Each cell must have a unique name within the library, but Gdstk
+    // does NOT enforce it.
+    Array<Cell*> cell_array;
+    Array<RawCell*> rawcell_array;
+
+    Property* properties;
+
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void init(const char* name_, double unit_, double precision_) {
+        name = copy_string(name_, NULL);
+        unit = unit_;
+        precision = precision_;
+    }
+
+    void print(bool all) const;
+
+    void clear() {
+        if (name) free_allocation(name);
+        name = NULL;
+        cell_array.clear();
+        rawcell_array.clear();
+        properties_clear(properties);
+    }
+
+    // Clear and free the memory of the whole library (this should be used with
+    // caution, it assumes all the memory is allocated dynamically and frees
+    // it).  It does not touch rawcells in rawcell_array, but it frees all cell
+    // contents from cell_array.
+    void free_all() {
+        for (uint64_t i = 0; i < cell_array.count; i++) {
+            cell_array[i]->free_all();
+            free_allocation(cell_array[i]);
+        }
+        clear();
+    }
+
+    // This library instance must be zeroed before copy_from.
+    // If deep_copy == true, new cells are allocated and deep copied from the
+    // source.  Otherwise, the same cell pointers are used.
+    void copy_from(const Library& library, bool deep_copy);
+
+    // Append all polygons/paths or labels tags found in this library's cells
+    // to result (rawcells are not included).
+    void get_shape_tags(Set<Tag>& result) const;
+    void get_label_tags(Set<Tag>& result) const;
+
+    // Append the top level cells (and raw cells) to the respective arrays.
+    // Top level cells are those that do not appear as dependencies of other
+    // cells in the library.
+    void top_level(Array<Cell*>& top_cells, Array<RawCell*>& top_rawcells) const;
+
+    // Find cell or rawcell by name. Return NULL if not found.
+    Cell* get_cell(const char* name) const;
+    RawCell* get_rawcell(const char* name) const;
+
+    // Rename a cell in the library, updating any references that use the old
+    // name with the new one.  Note: these assume cell names are dynamically
+    // allocated in cells and references throughout the library.
+    void rename_cell(const char* old_name, const char* new_name);
+    void rename_cell(Cell* cell, const char* new_name);
+
+    // Replace a library cell updating references to the old cell with
+    // references to the new one.  If old_cell is not present in the library,
+    // new_cell is not inserted either, but references are updated anyway.
+    void replace_cell(Cell* old_cell, Cell* new_cell);
+    void replace_cell(RawCell* old_cell, Cell* new_cell);
+    void replace_cell(Cell* old_cell, RawCell* new_cell);
+    void replace_cell(RawCell* old_cell, RawCell* new_cell);
+
+    // Change the tags of all elements in this library.  Map keys are the
+    // current element tags and map values are the desired new tags.
+    void remap_tags(const TagMap& map) {
+        for (uint64_t i = 0; i < cell_array.count; i++) cell_array[i]->remap_tags(map);
+    };
+
+    // Output this library to a GDSII file.  All polygons are fractured to
+    // max_points before saving (but the originals are kept) if max_points > 4.
+    // GDSII files include a timestamp, which can be specified by the caller or
+    // left NULL, in which case the current time will be used.
+    ErrorCode write_gds(const char* filename, uint64_t max_points, tm* timestamp) const;
+
+    // Output this library to an OASIS file.  The OASIS specification includes
+    // support for a few special shapes, which can significantly decrease the
+    // file size.  Circle detection is enabled by setting circle_tolerance > 0.
+    // Rectangles and trapezoids are enabled via config_flags.  Further size
+    // reduction can be achieved by setting deflate_level > 0 (up to 9, for
+    // maximal compression).  Finally, config_flags is a bit-field value
+    // obtained by or-ing OASIS_CONFIG_* constants, defined in oasis.h
+    ErrorCode write_oas(const char* filename, double circle_tolerance, uint8_t deflate_level,
+                        uint16_t config_flags);
+};
+
+// Struct used to get information from a library file without loading the
+// complete library.
+struct LibraryInfo {
+    Array<char*> cell_names;
+    Set<Tag> shape_tags;
+    Set<Tag> label_tags;
+    uint64_t num_polygons;
+    uint64_t num_paths;
+    uint64_t num_references;
+    uint64_t num_labels;
+    double unit;
+    double precision;
+
+    void clear() {
+        for (uint64_t i = 0; i < cell_names.count; i++) {
+            free_allocation(cell_names[i]);
+            cell_names[i] = NULL;
+        }
+        cell_names.clear();
+        shape_tags.clear();
+        label_tags.clear();
+        num_polygons = 0;
+        num_paths = 0;
+        num_references = 0;
+        num_labels = 0;
+        unit = 0;
+        precision = 0;
+    }
+};
+
+// Read the contents of a GDSII file into a new library.  If unit is not zero,
+// the units in the file are converted (all elements are properly scaled to the
+// desired unit).  The value of tolerance is used as the default tolerance for
+// paths in the library.  If shape_tags is not empty, only shapes in those
+// tags will be imported.  If not NULL, any errors will be reported through
+// error_code.
+Library read_gds(const char* filename, double unit, double tolerance, const Set<Tag>* shape_tags,
+                 ErrorCode* error_code);
+
+// Read the contents of an OASIS file into a new library.  If unit is not zero,
+// the units in the file are converted (all elements are properly scaled to the
+// desired unit).  The value of tolerance is used as the default tolerance for
+// paths in the library and for the creation of circles.  If shape_tags is not
+// empty, only shapes in those tags will be imported.  If not NULL, any errors
+// will be reported through error_code.
+Library read_oas(const char* filename, double unit,
+                 double tolerance,  // TODO: const Set<Tag>* shape_tags,
+                 ErrorCode* error_code);
+
+// Read the unit and precision of a GDSII file and return in the respective
+// arguments.
+ErrorCode gds_units(const char* filename, double& unit, double& precision);
+
+// Get/set the timestamps in the GDSII file.  If timestamp is not NULL, set the
+// timestamps of the file.  The main library timestamp before any modification
+// is returned.
+tm gds_timestamp(const char* filename, const tm* new_timestamp, ErrorCode* error_code);
+
+// Gather information about the GDSII file. Return argument info must be
+// properly initialized.
+ErrorCode gds_info(const char* filename, LibraryInfo& info);
+
+// Read the precision of an OASIS file (unit is always 1e-6) and return in the
+// precision argument.
+ErrorCode oas_precision(const char* filename, double& precision);
+
+// Return true if the file signature checks or if the file has no validation
+// data.  If signature is provided, the calculated signature is stored there.
+// If not NULL, any errors will be reported through error_code.  If the file
+// has no checksum data, signature will be set to zero and error_code to
+// ErrorCode::ChecksumError if they are not NULL.
+bool oas_validate(const char* filename, uint32_t* signature, ErrorCode* error_code);
+
+// TODO: Gather information about file
+// ErrorCode oas_info(const char* filename, LibraryInfo& info);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/map.html b/headers/map.html new file mode 100644 index 000000000..e5c340417 --- /dev/null +++ b/headers/map.html @@ -0,0 +1,314 @@ + + + + + + + map.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

map.h

+
template <class T>
+struct MapItem {
+    char* key;
+    T value;
+};
+
+// Hash map indexed by NULL-terminated strings
+template <class T>
+struct Map {
+    uint64_t capacity;  // allocated capacity
+    uint64_t count;     // number of items in the map
+    MapItem<T>* items;  // array with length capacity
+
+    void print(bool all, void (*value_print)(const T&)) const {
+        printf("Map <%p>, count %" PRIu64 "/%" PRIu64 ", items <%p>\n", this, count, capacity,
+               items);
+        if (all) {
+            MapItem<T>* item = items;
+            if (value_print) {
+                for (uint64_t i = 0; i < capacity; i++, item++) {
+                    printf("Item %" PRIu64 " <%p>, key %p (%s): ", i, item, item->key,
+                           item->key ? item->key : "");
+                    value_print(item->value);
+                }
+            } else {
+                for (uint64_t i = 0; i < capacity; i++, item++) {
+                    printf("Item %" PRIu64 " <%p>, key %p (%s): value <%p>\n", i, item, item->key,
+                           item->key ? item->key : "", item->value);
+                }
+            }
+        }
+    }
+
+    // The instance should be zeroed before using copy_from
+    void copy_from(const Map<T>& map) {
+        count = 0;
+        capacity = map.capacity;
+        items = (MapItem<T>*)allocate_clear(capacity * sizeof(MapItem<T>));
+        for (MapItem<T>* item = map.next(NULL); item; item = map.next(item)) {
+            set(item->key, item->value);
+        }
+    }
+
+    void resize(uint64_t new_capacity) {
+        Map<T> new_map;
+        new_map.count = 0;
+        new_map.capacity = new_capacity;
+        new_map.items = (MapItem<T>*)allocate_clear(new_capacity * sizeof(MapItem<T>));
+        const MapItem<T>* limit = items + capacity;
+        for (MapItem<T>* it = items; it != limit; it++) {
+            if (it->key) new_map.set(it->key, it->value);
+        }
+        clear();
+        capacity = new_map.capacity;
+        count = new_map.count;
+        items = new_map.items;
+    }
+
+    // Function to iterate over all values in the map:
+    // for (MapItem<T>* item = map.next(NULL); item; item = map.next(item)) {…}
+    MapItem<T>* next(const MapItem<T>* current) const {
+        MapItem<T>* next_ = current ? (MapItem<T>*)(current + 1) : items;
+        const MapItem<T>* limit = items + capacity;
+        while (next_ < limit) {
+            if (next_->key) return next_;
+            next_++;
+        }
+        return NULL;
+    }
+
+    void to_array(Array<T>& result) const {
+        result.ensure_slots(count);
+        const MapItem<T>* limit = items + capacity;
+        for (MapItem<T>* it = items; it != limit; it++) {
+            if (it->key) result.append_unsafe(it->value);
+        }
+    }
+
+    void clear() {
+        if (items) {
+            MapItem<T>* item = items;
+            for (uint64_t i = 0; i < capacity; i++, item++) {
+                if (item->key) {
+                    free_allocation(item->key);
+                    item->key = NULL;
+                }
+            }
+            free_allocation(items);
+            items = NULL;
+        }
+        capacity = 0;
+        count = 0;
+    }
+
+    MapItem<T>* get_slot(const char* key) const {
+        assert(capacity > 0);
+        assert(count < capacity);
+        uint64_t h = hash(key) % capacity;
+        MapItem<T>* item = items + h;
+        while (item->key != NULL && strcmp(item->key, key) != 0) {
+            item++;
+            if (item == items + capacity) item = items;
+        }
+        // DEBUG_PRINT("get_slot %s [%" PRIu64 "] -> [%" PRIu64 "]\n", key, h, item - items);
+        return item;
+    }
+
+    // Key is internally allocated and copied; value is simply assigned
+    void set(const char* key, T value) {
+        // Equality is important for capacity == 0
+        if (count * 10 >= capacity * GDSTK_MAP_CAPACITY_THRESHOLD)
+            resize(capacity >= GDSTK_INITIAL_MAP_CAPACITY ? capacity * GDSTK_MAP_GROWTH_FACTOR
+                                                          : GDSTK_INITIAL_MAP_CAPACITY);
+        MapItem<T>* item = get_slot(key);
+        if (item->key == NULL) {
+            item->key = copy_string(key, NULL);
+            count++;
+        }
+        item->value = value;
+    }
+
+    bool has_key(const char* key) const {
+        if (count == 0) return false;
+        const MapItem<T>* item = get_slot(key);
+        return item->key != NULL;
+    }
+
+    // If the desired key is not found, returns T{}
+    T get(const char* key) const {
+        if (count == 0) return T{};
+        const MapItem<T>* item = get_slot(key);
+        return item->key == NULL ? T{} : item->value;
+    }
+
+    // Return true if the key existed, false otherwise
+    bool del(const char* key) {
+        if (count == 0) return false;
+        MapItem<T>* item = get_slot(key);
+        if (item->key == NULL) return false;
+
+        // DEBUG_PRINT("DEL [%" PRIu64 "] %s\n", item - items, item->key);
+        free_allocation(item->key);
+        item->key = NULL;
+        count--;
+
+        // Re-insert this block to fill any undesired gaps
+        while (true) {
+            item++;
+            if (item == items + capacity) item = items;
+            if (item->key == NULL) return true;
+            char* temp_key = item->key;
+            item->key = NULL;
+            MapItem<T>* new_item = get_slot(temp_key);
+            new_item->key = temp_key;
+            new_item->value = item->value;
+            // if (new_item != item) {
+            //     DEBUG_PRINT("MOVE %s [%" PRIu64 "] -> [%" PRIu64 "]\n", new_item->key,
+            //                 item - items, new_item - items);
+            // }
+        }
+        assert(false);
+        return true;
+    }
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/oasis.html b/headers/oasis.html new file mode 100644 index 000000000..6f02965f6 --- /dev/null +++ b/headers/oasis.html @@ -0,0 +1,353 @@ + + + + + + + oasis.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

oasis.h

+
// Configuration flags for Library.write_oas
+#define OASIS_CONFIG_PROPERTY_MAX_COUNTS 0x0001
+#define OASIS_CONFIG_PROPERTY_TOP_LEVEL 0x0002
+#define OASIS_CONFIG_PROPERTY_BOUNDING_BOX 0x0004
+#define OASIS_CONFIG_PROPERTY_CELL_OFFSET 0x0008
+
+#define OASIS_CONFIG_DETECT_RECTANGLES 0x0010
+#define OASIS_CONFIG_DETECT_TRAPEZOIDS 0x0020
+
+#define OASIS_CONFIG_INCLUDE_CRC32 0x0040
+#define OASIS_CONFIG_INCLUDE_CHECKSUM32 0x0080
+
+#define OASIS_CONFIG_STANDARD_PROPERTIES                                  \
+    (OASIS_CONFIG_PROPERTY_MAX_COUNTS | OASIS_CONFIG_PROPERTY_TOP_LEVEL | \
+     OASIS_CONFIG_PROPERTY_BOUNDING_BOX | OASIS_CONFIG_PROPERTY_CELL_OFFSET)
+#define OASIS_CONFIG_DETECT_ALL (OASIS_CONFIG_DETECT_RECTANGLES | OASIS_CONFIG_DETECT_TRAPEZOIDS)
+
+// Types and functions in this header are not meant to be used by the end user
+// of the library.  They are for internal use only.
+
+extern const char s_max_int_size_property_name[];
+extern const char s_max_uint_size_property_name[];
+extern const char s_max_string_size_property_name[];
+extern const char s_max_polygon_property_name[];
+extern const char s_max_path_property_name[];
+extern const char s_top_level_property_name[];
+extern const char s_bounding_box_available_property_name[];
+extern const char s_bounding_box_property_name[];
+extern const char s_cell_offset_property_name[];
+extern const char s_gds_property_name[];
+
+enum struct OasisDataType : uint8_t {
+    RealPositiveInteger = 0,
+    RealNegativeInteger = 1,
+    RealPositiveReciprocal = 2,
+    RealNegativeReciprocal = 3,
+    RealPositiveRatio = 4,
+    RealNegativeRatio = 5,
+    RealFloat = 6,
+    RealDouble = 7,
+    UnsignedInteger = 8,
+    SignedInteger = 9,
+    AString = 10,  // printable characters + space (0x20 through 0x7e)
+    BString = 11,  // any bytes
+    NString = 12,  // printable characters (0x21 through 0x7e), count > 0
+    ReferenceA = 13,
+    ReferenceB = 14,
+    ReferenceN = 15
+};
+
+enum struct OasisRepetition : uint8_t {
+    Previous = 0,
+    Rectangular = 1,
+    RectangularX = 2,
+    RectangularY = 3,
+    ExplicitX = 4,
+    ExplicitXGrid = 5,
+    ExplicitY = 6,
+    ExplicitYGrid = 7,
+    Regular = 8,
+    Linear = 9,
+    Explicit = 10,
+    ExplicitGrid = 11
+};
+
+enum struct OasisPointList : uint8_t {
+    ManhattanHorizontalFirst = 0,
+    ManhattanVerticalFirst = 1,
+    Manhattan = 2,
+    Octangular = 3,
+    General = 4,
+    Relative = 5
+};
+
+enum struct OasisValidation : uint8_t { None = 0, Crc32 = 1, CheckSum = 2 };
+
+enum struct OasisInterval : uint8_t {
+    AllValues = 0,
+    UpperBound = 1,
+    LowerBound = 2,
+    SingleValue = 3,
+    Bounded = 4
+};
+
+enum struct OasisDirection : uint8_t { E = 0, N = 1, W = 2, S = 3, NE = 4, NW = 5, SW = 6, SE = 7 };
+
+enum struct OasisRecord : uint8_t {
+    PAD = 0,
+    START = 1,
+    END = 2,
+    CELLNAME_IMPLICIT = 3,
+    CELLNAME = 4,
+    TEXTSTRING_IMPLICIT = 5,
+    TEXTSTRING = 6,
+    PROPNAME_IMPLICIT = 7,
+    PROPNAME = 8,
+    PROPSTRING_IMPLICIT = 9,
+    PROPSTRING = 10,
+    LAYERNAME_DATA = 11,
+    LAYERNAME_TEXT = 12,
+    CELL_REF_NUM = 13,
+    CELL = 14,
+    XYABSOLUTE = 15,
+    XYRELATIVE = 16,
+    PLACEMENT = 17,
+    PLACEMENT_TRANSFORM = 18,
+    TEXT = 19,
+    RECTANGLE = 20,
+    POLYGON = 21,
+    PATH = 22,
+    TRAPEZOID_AB = 23,
+    TRAPEZOID_A = 24,
+    TRAPEZOID_B = 25,
+    CTRAPEZOID = 26,
+    CIRCLE = 27,
+    PROPERTY = 28,
+    LAST_PROPERTY = 29,
+    XNAME_IMPLICIT = 30,
+    XNAME = 31,
+    XELEMENT = 32,
+    XGEOMETRY = 33,
+    CBLOCK = 34
+};
+
+struct OasisStream {
+    FILE* file;
+    uint8_t* data;
+    uint8_t* cursor;
+    uint64_t data_size;
+    uint32_t signature;
+    bool crc32;
+    bool checksum32;
+    ErrorCode error_code;
+};
+
+struct OasisState {
+    double scaling;
+    double circle_tolerance;
+    Map<uint64_t> property_name_map;
+    Array<PropertyValue*> property_value_array;
+    uint16_t config_flags;
+};
+
+ErrorCode oasis_read(void* buffer, size_t size, size_t count, OasisStream& in);
+
+size_t oasis_write(const void* buffer, size_t size, size_t count, OasisStream& out);
+
+int oasis_putc(int c, OasisStream& out);
+
+uint8_t* oasis_read_string(OasisStream& in, bool append_terminating_null, uint64_t& len);
+
+uint64_t oasis_read_unsigned_integer(OasisStream& in);
+
+int64_t oasis_read_integer(OasisStream& in);
+
+inline int64_t oasis_read_1delta(OasisStream& in) { return oasis_read_integer(in); };
+
+void oasis_read_2delta(OasisStream& in, int64_t& x, int64_t& y);
+
+void oasis_read_3delta(OasisStream& in, int64_t& x, int64_t& y);
+
+void oasis_read_gdelta(OasisStream& in, int64_t& x, int64_t& y);
+
+double oasis_read_real_by_type(OasisStream& in, OasisDataType type);
+
+inline double oasis_read_real(OasisStream& in) {
+    OasisDataType type;
+    if (oasis_read(&type, 1, 1, in) != ErrorCode::NoError) return 0;
+    return oasis_read_real_by_type(in, type);
+}
+
+// result must have at least 1 point in it, which will be used as reference for the relative deltas.
+// polygon indicates whether this is supposed to be a polygon point list (in which case there will
+// be an implicit extra delta for Manhattan types).
+uint64_t oasis_read_point_list(OasisStream& in, double scaling, bool closed, Array<Vec2>& result);
+
+void oasis_read_repetition(OasisStream& in, double scaling, Repetition& repetition);
+
+void oasis_write_unsigned_integer(OasisStream& out, uint64_t value);
+
+void oasis_write_integer(OasisStream& out, int64_t value);
+
+inline void oasis_write_1delta(OasisStream& out, int64_t value) {
+    oasis_write_integer(out, value);
+};
+
+void oasis_write_2delta(OasisStream& out, int64_t x, int64_t y);
+
+void oasis_write_3delta(OasisStream& out, int64_t x, int64_t y);
+
+void oasis_write_gdelta(OasisStream& out, int64_t x, int64_t y);
+
+void oasis_write_real(OasisStream& out, double value);
+
+// Uses first point as reference, does not output it.  Deltas between neighboring points
+// will be calculated in-place: points[i] = points[i] - points[i - 1] (i = 1...count - 1)
+void oasis_write_point_list(OasisStream& out, Array<IntVec2>& points, bool closed);
+// Uses first point as reference, does not output it.
+void oasis_write_point_list(OasisStream& out, const Array<Vec2> points, double scaling,
+                            bool closed);
+
+// This should only be called with repetition.get_count() > 1
+void oasis_write_repetition(OasisStream& out, const Repetition repetition, double scaling);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/pathcommon.html b/headers/pathcommon.html new file mode 100644 index 000000000..2273bff5c --- /dev/null +++ b/headers/pathcommon.html @@ -0,0 +1,221 @@ + + + + + + + pathcommon.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pathcommon.h

+
enum struct EndType {
+    Flush = 0,
+    Round,
+    HalfWidth,
+    Extended,  // Use end_extensions
+    Smooth,    // Becomes Round if simple_path
+    Function,  // Use end_function(…)
+};
+
+enum struct JoinType {
+    Natural = 0,  // Only bevel acute joins
+    Miter,
+    Bevel,
+    Round,
+    Smooth,    // Becomes Round if simple_path
+    Function,  // Use join_function(…)
+};
+
+enum struct BendType {
+    None = 0,
+    Circular,  // Use bend_radius
+    Function,  // Use bend_function(…)
+};
+
+inline const char* end_type_name(EndType end_type) {
+    switch (end_type) {
+        case EndType::Flush:
+            return "flush";
+        case EndType::Round:
+            return "round";
+        case EndType::HalfWidth:
+            return "half-width";
+        case EndType::Extended:
+            return "extended";
+        case EndType::Smooth:
+            return "smooth";
+        case EndType::Function:
+            return "function";
+    }
+    return "unknown";
+}
+
+inline const char* join_type_name(JoinType join_type) {
+    switch (join_type) {
+        case JoinType::Natural:
+            return "natural";
+        case JoinType::Miter:
+            return "miter";
+        case JoinType::Bevel:
+            return "bevel";
+        case JoinType::Round:
+            return "round";
+        case JoinType::Smooth:
+            return "smooth";
+        case JoinType::Function:
+            return "function";
+    }
+    return "unknown";
+}
+
+inline const char* bend_type_name(BendType bend_type) {
+    switch (bend_type) {
+        case BendType::None:
+            return "none";
+        case BendType::Circular:
+            return "circular";
+        case BendType::Function:
+            return "function";
+    }
+    return "unknown";
+}
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/polygon.html b/headers/polygon.html new file mode 100644 index 000000000..25db360a1 --- /dev/null +++ b/headers/polygon.html @@ -0,0 +1,261 @@ + + + + + + + polygon.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

polygon.h

+
struct Polygon {
+    Tag tag;
+    Array<Vec2> point_array;
+    Repetition repetition;
+    Property* properties;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void print(bool all) const;
+
+    void clear();
+
+    // This polygon instance must be zeroed before copy_from
+    void copy_from(const Polygon& polygon);
+
+    // Total polygon area including any repetitions
+    double area() const;
+
+    // Polygon area excluding repetitions with sign indicating orientation
+    // (positive for counter clockwise)
+    double signed_area() const;
+    
+    // Total polygon perimeter including any repetitions
+    double perimeter() const;
+
+    // Check if the points are inside this polygon (points lying on the edges
+    // or coinciding with a vertex of the polygon are considered inside).
+    bool contain(const Vec2 point) const;
+    bool contain_all(const Array<Vec2>& points) const;
+    bool contain_any(const Array<Vec2>& points) const;
+
+    // Bounding box corners are returned in min and max.  If the polygons has
+    // no vertices, return min.x > max.x.  Repetitions are taken into account
+    // for the calculation.
+    void bounding_box(Vec2& min, Vec2& max) const;
+
+    void translate(const Vec2 v);
+    void scale(const Vec2 scale, const Vec2 center);
+    void mirror(const Vec2 p0, const Vec2 p1);
+    void rotate(double angle, const Vec2 center);
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and translating by origin at the end.  This is equivalent
+    // to the transformation defined by a Reference with the same arguments.
+    void transform(double magnification, bool x_reflection, double rotation, const Vec2 origin);
+
+    // Round the corners of this polygon.  Argument radii can include one
+    // radius value for each polygon corner or less, in which case it will be
+    // cycled.  If the desired fillet radius for a given corner is larger than
+    // half the shortest edge adjacent to that corner, it is reduced to that
+    // size.  The number of vertices used to approximate the circular arcs is
+    // defined by tolerance.
+    void fillet(const Array<double> radii, double tolerance);
+
+    // Fracture the polygon horizontally and vertically until all pieces have
+    // at most max_points vertices.  If max_points < 5, it doesn't do anything.
+    // Resulting pieces are appended to result.
+    void fracture(uint64_t max_points, double precision, Array<Polygon*>& result) const;
+
+    // Append the copies of this polygon defined by its repetition to result.
+    void apply_repetition(Array<Polygon*>& result);
+
+    // These functions output the polygon in the GDSII, OASIS and SVG formats.
+    // They are not supposed to be called by the user.
+    ErrorCode to_gds(FILE* out, double scaling) const;
+    ErrorCode to_oas(OasisStream& out, OasisState& state) const;
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision) const;
+};
+
+Polygon rectangle(const Vec2 corner1, const Vec2 corner2, Tag tag);
+
+Polygon cross(const Vec2 center, double full_size, double arm_width, Tag tag);
+
+// The polygon is created with a horizontal lower edge when rotation is 0.
+Polygon regular_polygon(const Vec2 center, double side_length, uint64_t sides, double rotation,
+                        Tag tag);
+
+// Create circles, ellipses, rings, or sections of those.  The number of points
+// used to approximate the arcs is such that the approximation error is less
+// than tolerance.
+Polygon ellipse(const Vec2 center, double radius_x, double radius_y, double inner_radius_x,
+                double inner_radius_y, double initial_angle, double final_angle, double tolerance,
+                Tag tag);
+
+Polygon racetrack(const Vec2 center, double straight_length, double radius, double inner_radius,
+                  bool vertical, double tolerance, Tag tag);
+
+// Create a polygonal text form NULL-terminated string s.  Argument size
+// defines the full height of the glyphs.  Polygons are appended to result.
+// The character aspect ratio is 1:2.  For horizontal text, spacings between
+// characters and between lines are 9/16 and 5/4 times the full height size,
+// respectively.  For vertical text, characters and columns are respectively
+// spaced by 9/8 and 1 times size.
+void text(const char* s, double size, const Vec2 position, bool vertical, Tag tag,
+          Array<Polygon*>& result);
+
+// Create polyogns based on the 2-d array data (in row-major orderr, with rows
+// * cols elements) by drawing the isolines at level.  Scaling is used in the
+// boolean composition of resulting shapes to connect any holes and set the
+// overall precision.  Resulting polygons are appended to result.  Their length
+// scale is one data element, i.e., the data array has size cols × rows.
+ErrorCode contour(const double* data, uint64_t rows, uint64_t cols, double level, double scaling,
+                  Array<Polygon*>& result);
+
+// Check if the points are inside a set of polygons (points lying on the edges
+// or coinciding with a vertex of the polygons are considered inside).  Result
+// must be an array with size for at least points.count bools.
+void inside(const Array<Vec2>& points, const Array<Polygon*>& polygons, bool* result);
+bool all_inside(const Array<Vec2>& points, const Array<Polygon*>& polygons);
+bool any_inside(const Array<Vec2>& points, const Array<Polygon*>& polygons);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/property.html b/headers/property.html new file mode 100644 index 000000000..176a4460a --- /dev/null +++ b/headers/property.html @@ -0,0 +1,219 @@ + + + + + + + property.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

property.h

+
struct OasisStream;
+struct OasisState;
+
+// Properties (and their members) are assumed to always be allocated through
+// allocate, allocate_clear, or reallocate.
+
+enum struct PropertyType { UnsignedInteger, Integer, Real, String };
+
+// Each property can hold a series of values, which are represented by a
+// NULL-terminated linked list of PropertyValue
+struct PropertyValue {
+    PropertyType type;
+    union {
+        uint64_t unsigned_integer;
+        int64_t integer;
+        double real;
+        struct {
+            uint64_t count;
+            uint8_t* bytes;
+        };
+    };
+    PropertyValue* next;
+};
+
+// Properties are stored as a NULL-terminated linked list.  Their name is a
+// NULL-terminated string.  Property names in the OASIS should be strings of
+// characters within the range 0x21 and 0x7E with at least 1 character.
+struct Property {
+    char* name;
+    PropertyValue* value;
+    Property* next;
+};
+
+void properties_print(Property* properties);
+void properties_clear(Property*& properties);
+Property* properties_copy(const Property* properties);
+
+// property_values_copy is used in the OASIS reader; it is not intended to be
+// used elsewhere.
+PropertyValue* property_values_copy(const PropertyValue* values);
+
+// The set_property functions add values to the first existing property with
+// the given name.  A new one is created if none exists or create_new == true.
+// New values are added to the start of the value list, so in the OASIS file,
+// they will appear in reverse of the insertion order (last added will appear
+// first).  The NULL byte at the end of string is NOT included in the property
+// value.
+void set_property(Property*& properties, const char* name, uint64_t unsigned_integer,
+                  bool create_new);
+void set_property(Property*& properties, const char* name, int64_t integer, bool create_new);
+void set_property(Property*& properties, const char* name, double real, bool create_new);
+void set_property(Property*& properties, const char* name, const char* string, bool create_new);
+void set_property(Property*& properties, const char* name, const uint8_t* bytes, uint64_t count,
+                  bool create_new);
+
+// Overwrite properties with the same attribute number. The NULL byte is
+// included in the property value.
+void set_gds_property(Property*& properties, uint16_t attribute, const char* value);
+
+uint64_t remove_property(Property*& properties, const char* name, bool all_occurences);
+bool remove_gds_property(Property*& properties, uint16_t attribute);
+
+PropertyValue* get_property(Property* properties, const char* name);
+PropertyValue* get_gds_property(Property* properties, uint16_t attribute);
+
+// These functions output the properties in the GDSII and OASIS formats.  They
+// are not supposed to be called by the user.
+ErrorCode properties_to_gds(const Property* properties, FILE* out);
+ErrorCode properties_to_oas(const Property* properties, OasisStream& out, OasisState& state);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/rawcell.html b/headers/rawcell.html new file mode 100644 index 000000000..264d4a71c --- /dev/null +++ b/headers/rawcell.html @@ -0,0 +1,199 @@ + + + + + + + rawcell.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

rawcell.h

+
struct RawSource {
+    FILE* file;
+    uint32_t uses;
+
+    // Read num_bytes into buffer from fd starting at offset
+    int64_t offset_read(void* buffer, uint64_t num_bytes, uint64_t offset) const {
+#ifdef _WIN32
+        // The POSIX version (pread) does not change the file cursor, this
+        // does.  Furthermore, this is not thread-safe!
+        FSEEK64(file, offset, SEEK_SET);
+        return fread(buffer, 1, num_bytes, file);
+#else
+        return pread(fileno(file), buffer, num_bytes, offset);
+#endif
+    };
+};
+
+// Rawcells are not meant to be created except through read_rawcells.  They are
+// not explicitly loaded in memory until used, so the GDSII file where they are
+// loaded from, remains open until it is no longer needed.  That is done by
+// reference counting.
+struct RawCell {
+    char* name;
+    RawSource* source;
+    union {
+        uint8_t* data;
+        uint64_t offset;
+    };
+    uint64_t size;
+    Array<RawCell*> dependencies;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void print(bool all) const;
+
+    void clear();
+
+    // Append dependencies of this cell to result.  If recursive is true, also
+    // includes dependencies of any dependencies recursively.
+    void get_dependencies(bool recursive, Map<RawCell*>& result) const;
+
+    // This function outputs the rawcell in the GDSII.  It is not supposed to
+    // be called by the user.
+    ErrorCode to_gds(FILE* out);
+};
+
+// Load a GDSII file and extract its cells as RawCell.
+Map<RawCell*> read_rawcells(const char* filename, ErrorCode* error_code);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/reference.html b/headers/reference.html new file mode 100644 index 000000000..129c4a0c9 --- /dev/null +++ b/headers/reference.html @@ -0,0 +1,246 @@ + + + + + + + reference.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

reference.h

+
struct Cell;
+struct RawCell;
+struct GeometryInfo;
+
+enum struct ReferenceType { Cell = 0, RawCell, Name };
+
+struct Reference {
+    ReferenceType type;
+    // References by name or rawcell are limited in their use.  Most cell
+    // functions will not work on them.
+    union {
+        Cell* cell;
+        RawCell* rawcell;
+        char* name;
+    };
+    Vec2 origin;
+    double rotation;  // in radians
+    double magnification;
+    bool x_reflection;
+    Repetition repetition;
+    Property* properties;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    void init(Cell* cell_) {
+        type = ReferenceType::Cell;
+        cell = cell_;
+        magnification = 1.0;
+    }
+
+    void init(RawCell* rawcell_) {
+        type = ReferenceType::RawCell;
+        rawcell = rawcell_;
+        magnification = 1.0;
+    }
+
+    void init(const char* name_) {
+        type = ReferenceType::Name;
+        name = copy_string(name_, NULL);
+        magnification = 1.0;
+    }
+
+    void print() const;
+
+    void clear();
+
+    // This reference instance must be zeroed before copy_from
+    void copy_from(const Reference& reference);
+
+    // Calculate the bounding box of this reference and return the lower left
+    // and upper right corners in min and max, respectively.  If the bounding
+    // box cannot be calculated, return min.x > max.x.  The cached version can
+    // be used to retain the cache for latter use, but it is the user
+    // responsibility to invalidate the cache if any geometry changes.
+    void bounding_box(Vec2& min, Vec2& max) const;
+    void bounding_box(Vec2& min, Vec2& max, Map<GeometryInfo>& cache) const;
+
+    // Append the convex hull of this reference to result.  The cached version
+    // follows the same rules explained for bounding_box.
+    void convex_hull(Array<Vec2>& result) const;
+    void convex_hull(Array<Vec2>& result, Map<GeometryInfo>& cache) const;
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and translating by origin at the end.  This is equivalent
+    // to the transformation defined by a Reference with the same arguments.
+    void transform(double mag, bool x_refl, double rot, const Vec2 orig);
+
+    // Append the copies of this reference defined by its repetition to result.
+    void apply_repetition(Array<Reference*>& result);
+
+    // Applies the transformation and repetition defined by this reference to
+    // the points in point_array, appending the results to the same array.
+    void repeat_and_transform(Array<Vec2>& point_array) const;
+
+    // These functions create and append the elements that are created by this
+    // reference to the result array.  Argument depth controls how many levels
+    // of references should be included (references of references); if it is
+    // negative, all levels are included.  If include_paths is true, the
+    // polygonal representation of paths are also included in polygons.  If
+    // filter is true, only polygons in the indicated layer and data type are
+    // created.
+    void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth, bool filter,
+                      Tag tag, Array<Polygon*>& result) const;
+    void get_flexpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                       Array<FlexPath*>& result) const;
+    void get_robustpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                         Array<RobustPath*>& result) const;
+    void get_labels(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
+                    Array<Label*>& result) const;
+
+    // These functions output the reference in the GDSII and SVG formats.  They
+    // are not supposed to be called by the user.
+    ErrorCode to_gds(FILE* out, double scaling) const;
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision) const;
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/repetition.html b/headers/repetition.html new file mode 100644 index 000000000..57df74679 --- /dev/null +++ b/headers/repetition.html @@ -0,0 +1,202 @@ + + + + + + + repetition.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

repetition.h

+
enum struct RepetitionType {
+    None = 0,     // No repetition
+    Rectangular,  // columns × rows matrix of copies spaced by spacing
+    Regular,      // columns × rows matrix along directions v1 and v2
+    Explicit,     // explicit repetition at offsets
+    ExplicitX,    // explicit repetitions along the x axis at coords
+    ExplicitY,    // explicit repetitions along the y axis at coords
+};
+
+struct Repetition {
+    RepetitionType type;
+    union {
+        struct {               // Rectangular and Regular
+            uint64_t columns;  // Along x or v1
+            uint64_t rows;     // Along y or v2
+            union {
+                Vec2 spacing;  // Rectangular spacing
+                struct {
+                    Vec2 v1;  // Regular axis 1
+                    Vec2 v2;  // Regular axis 2
+                };
+            };
+        };
+        // The original element should not be explicitly included, i.e., (0, 0)
+        Array<Vec2> offsets;   // Explicit
+        Array<double> coords;  // ExplicitX and ExplicitY
+    };
+
+    void print() const;
+
+    void clear();
+
+    // This repetition instance must be zeroed before copy_from
+    void copy_from(const Repetition repetition);
+
+    // Return the number of repetitions created by this object, including the
+    // original
+    uint64_t get_count() const;
+
+    // Append the offsets generated by this repetition, including the original,
+    // (0, 0), as first element, to result.
+    void get_offsets(Array<Vec2>& result) const;
+
+    // Append the extrema offsets generated by this repetition, including the
+    // original, to result.
+    void get_extrema(Array<Vec2>& result) const;
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and rotating at the end.  This is equivalent to the
+    // transformation defined by a Reference with the same arguments.
+    void transform(double magnification, bool x_reflection, double rotation);
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/robustpath.html b/headers/robustpath.html new file mode 100644 index 000000000..48a28015d --- /dev/null +++ b/headers/robustpath.html @@ -0,0 +1,441 @@ + + + + + + + robustpath.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

robustpath.h

+
// Robustpaths are similar to flexpaths in that they only hold a spine, that
+// represents the main shape of the desired path, plus any number of elements
+// that add widths and offsets on top of that spine to build the actual paths.
+// The main difference from flexpaths is that, unlike those, the spine for
+// robustpaths is represented by an array of parametric curves (subpaths),
+// instead of an open polygonal curve.  Similarly, width and offset changes
+// along the path are represented parametrically by interpolation functions.
+// These properties make the process of finding the polygonal representation of
+// robustpaths more numerically robust, but also more computationally
+// intensive.
+
+enum struct InterpolationType {
+    Constant = 0,  // Step-change in join region
+    Linear,        // LERP from past value to new
+    Smooth,        // SERP from past value to new
+    Parametric     // Uses function(…)
+};
+
+struct Interpolation {
+    InterpolationType type;
+    union {
+        double value;  // Constant
+        struct {       // Linear or smooth interpolation
+            double initial_value;
+            double final_value;
+        };
+        struct {
+            ParametricDouble function;  // Parametric
+            void* data;                 // User data
+        };
+    };
+};
+
+enum struct SubPathType {
+    Segment,    // straight line segment
+    Arc,        // elliptical arc
+    Bezier,     // general Bézier
+    Bezier2,    // quadratic Bézier
+    Bezier3,    // cubic Bézier
+    Parametric  // general parametric function
+};
+
+// Subpaths are not supposed to be created directly by the user, but through
+// the construction functions of the RobustPath class instead.
+struct SubPath {
+    SubPathType type;
+    union {
+        struct {  // Segment
+            Vec2 begin;
+            Vec2 end;
+        };
+        struct {  // Arc
+            // x = path.radius_x * cos(path.angle_i);
+            // y = path.radius_y * sin(path.angle_i);
+            // center = arc_start - Vec2{x * cos_rot - y * sin_rot, x * sin_rot + y * cos_rot};
+            Vec2 center;
+            double radius_x;
+            double radius_y;
+            double angle_i;  // initial_angle - rotation;
+            double angle_f;  // final_angle - rotation;
+            double cos_rot;
+            double sin_rot;
+        };
+        struct {  // Bezier2, Bezier3
+            Vec2 p0;
+            Vec2 p1;
+            Vec2 p2;
+            Vec2 p3;  // Not used for Bezier2
+        };
+        Array<Vec2> ctrl;  // Bezier
+        struct {           // Parametric
+            ParametricVec2 path_function;
+            ParametricVec2 path_gradient;
+            Vec2 reference;
+            void* func_data;
+            union {
+                void* grad_data;
+                double step;
+            };
+        };
+    };
+
+    void print() const;
+    Vec2 gradient(double u, const double* trafo) const;
+    Vec2 eval(double u, const double* trafo) const;
+};
+
+struct RobustPathElement {
+    Tag tag;
+
+    // These arrays should have the same count as subpath_array
+    Array<Interpolation> width_array;
+    Array<Interpolation> offset_array;
+
+    // Both end_width and end_offset should be initialized to the initial path
+    // width and offset.  After that they will hold the last values used in the
+    // construction functions.
+    double end_width;
+    double end_offset;
+
+    EndType end_type;
+    Vec2 end_extensions;
+    EndFunction end_function;
+    void* end_function_data;  // User data for end_function
+};
+
+struct RobustPath {
+    // Last point on the path.  It should be initialized to the path origin on
+    // the creation of a new path.
+    Vec2 end_point;
+
+    Array<SubPath> subpath_array;  // Path spine
+
+    RobustPathElement* elements;  // Array with count num_elements
+    uint64_t num_elements;
+
+    // Numeric tolerance for intersection finding and curve approximation
+    double tolerance;
+
+    uint64_t max_evals;   // Maximal number of evaluations per function
+    double width_scale;   // Width scale accumulated from path transforms
+    double offset_scale;  // Offset scale accumulated from path transforms
+
+    // Transformation matrix for this path.  It should be initialized to the
+    // identity {1, 0, 0, 0, 1, 0}, unless you have a reason not to.  It
+    // transforms a point (x, y) to (xt, yt) with:
+    //   xt = x * trafo[0] + y * trafo[1] + trafo[2]
+    //   yt = x * trafo[3] + y * trafo[4] + trafo[5]
+    double trafo[6];
+
+    // If simple_path is true, all elements will be treated as if they have
+    // constant widths (using the first elements in their respective
+    // half_width_and_offset arrays) and saved as paths, not polygonal
+    // boundaries.
+    bool simple_path;
+
+    // Flag indicating whether the width of the path elements should be scaled
+    // when scaling the path (manually or through references).
+    bool scale_width;
+
+    Repetition repetition;
+    Property* properties;
+    // Used by the python interface to store the associated PyObject* (if any).
+    // No functions in gdstk namespace should touch this value!
+    void* owner;
+
+    // These are initialization routines to facilitate the creation of new
+    // robustpaths.  In versions with argument num_elements_, the elements
+    // array will be dynamically allocated (and num_elements properly set).
+    // Otherwise, num_elements and elements are expected to be already
+    // allocated and set.  Arguments width, offset and tag can be single values
+    // (which are applied to all elements) or arrays with count num_elements,
+    // one value for each path element.  Argument separation is the desired
+    // distance between adjacent elements.
+    void init(const Vec2 initial_position, double width, double offset, double tolerance_,
+              uint64_t max_evals_, Tag tag);
+    void init(const Vec2 initial_position, const double* width, const double* offset,
+              double tolerance_, uint64_t max_evals_, const Tag* tag);
+    void init(const Vec2 initial_position, uint64_t num_elements_, double width, double separation,
+              double tolerance_, uint64_t max_evals_, Tag tag);
+    void init(const Vec2 initial_position, uint64_t num_elements_, const double* width,
+              const double* offset, double tolerance_, uint64_t max_evals_, const Tag* tag);
+
+    void print(bool all) const;
+
+    void clear();
+
+    // This path instance must be zeroed before copy_from
+    void copy_from(const RobustPath& path);
+
+    void translate(const Vec2 v);
+    void scale(double scale, const Vec2 center);
+    void mirror(const Vec2 p0, const Vec2 p1);
+    void rotate(double angle, const Vec2 center);
+
+    // Transformations are applied in the order of arguments, starting with
+    // magnification and translating by origin at the end.  This is equivalent
+    // to the transformation defined by a Reference with the same arguments.
+    void transform(double magnification, bool x_reflection, double rotation, const Vec2 origin);
+
+    // Append the copies of this path defined by its repetition to result.
+    void apply_repetition(Array<RobustPath*>& result);
+
+    // These functions are equivalent to those for curves (curve.h), with the
+    // addition of width and offset, which can be NULL (no width or offset
+    // changes) or arrays with count num_elements.
+    void horizontal(double coord_x, const Interpolation* width, const Interpolation* offset,
+                    bool relative);
+    void vertical(double coord_y, const Interpolation* width, const Interpolation* offset,
+                  bool relative);
+    void segment(const Vec2 end_point, const Interpolation* width, const Interpolation* offset,
+                 bool relative);
+    void cubic(const Vec2 point1, const Vec2 point2, const Vec2 point3, const Interpolation* width,
+               const Interpolation* offset, bool relative);
+    void cubic_smooth(const Vec2 point2, const Vec2 point3, const Interpolation* width,
+                      const Interpolation* offset, bool relative);
+    void quadratic(const Vec2 point1, const Vec2 point2, const Interpolation* width,
+                   const Interpolation* offset, bool relative);
+    void quadratic_smooth(const Vec2 point2, const Interpolation* width,
+                          const Interpolation* offset, bool relative);
+    void bezier(const Array<Vec2> point_array, const Interpolation* width,
+                const Interpolation* offset, bool relative);
+    void interpolation(const Array<Vec2> point_array, double* angles, bool* angle_constraints,
+                       Vec2* tension, double initial_curl, double final_curl, bool cycle,
+                       const Interpolation* width, const Interpolation* offset, bool relative);
+    void arc(double radius_x, double radius_y, double initial_angle, double final_angle,
+             double rotation, const Interpolation* width, const Interpolation* offset);
+    void turn(double radius, double angle, const Interpolation* width, const Interpolation* offset);
+    void parametric(ParametricVec2 curve_function, void* func_data, ParametricVec2 curve_gradient,
+                    void* grad_data, const Interpolation* width, const Interpolation* offset,
+                    bool relative);
+    uint64_t commands(const CurveInstruction* items, uint64_t count);
+
+    // These functions retrieve the position and gradient of the path spine at
+    // parametric value u, in which 0 <= u <= path.subpath_array.count.  For
+    // integer values of u, uses the end position of the previous subpath or
+    // the initial position of the next depending on whether from_below is true
+    // or false, respectively.  Note that this functions does not calculate
+    // intersections, it evaluates a single subpath.
+    Vec2 position(double u, bool from_below) const;
+    Vec2 gradient(double u, bool from_below) const;
+
+    // These functions are similar to the ones above, except they retrieve the
+    // width and offset of all path elements at the desired parametric value.
+    // The results are written to the result array, which must have count at
+    // least path.num_elements.
+    void width(double u, bool from_below, double* result) const;
+    void offset(double u, bool from_below, double* result) const;
+
+    // Calculate the polygonal spine of this path and append the resulting
+    // curve to result.
+    ErrorCode spine(Array<Vec2>& result) const;
+
+    // Calculate the center of an element of this path and append the resulting
+    // curve to result.
+    ErrorCode element_center(const RobustPathElement* el, Array<Vec2>& result) const;
+
+    // Append the polygonal representation of this path to result.  If filter
+    // is true, only elements with the indicated tag are processed.
+    // Overlapping points are removed from the path before any processing is
+    // executed.
+    ErrorCode to_polygons(bool filter, Tag tag, Array<Polygon*>& result) const;
+
+    // These functions output the polygon in the GDSII, OASIS and SVG formats.
+    // They are not supposed to be called by the user.  Because fracturing
+    // occurs at cell_to_gds, the polygons must be checked there and, if
+    // needed, fractured.  Therefore, to_gds should be used only when
+    // simple_path == true to produce true GDSII path elements.  The same is
+    // valid for to_oas, even though no fracturing ever occurs for OASIS files.
+    ErrorCode to_gds(FILE* out, double scaling) const;
+    ErrorCode to_oas(OasisStream& out, OasisState& state) const;
+    ErrorCode to_svg(FILE* out, double scaling, uint32_t precision) const;
+
+   private:
+    void simple_scale(double scale);
+    void simple_rotate(double angle);
+    void x_reflection();
+    void fill_widths_and_offsets(const Interpolation* width, const Interpolation* offset);
+    ErrorCode spine_intersection(const SubPath& sub0, const SubPath& sub1, double& u0,
+                                 double& u1) const;
+    ErrorCode center_intersection(const SubPath& sub0, const Interpolation& offset0,
+                                  const SubPath& sub1, const Interpolation& offset1, double& u0,
+                                  double& u1) const;
+    ErrorCode left_intersection(const SubPath& sub0, const Interpolation& offset0,
+                                const Interpolation& width0, const SubPath& sub1,
+                                const Interpolation& offset1, const Interpolation& width1,
+                                double& u0, double& u1) const;
+    ErrorCode right_intersection(const SubPath& sub0, const Interpolation& offset0,
+                                 const Interpolation& width0, const SubPath& sub1,
+                                 const Interpolation& offset1, const Interpolation& width1,
+                                 double& u0, double& u1) const;
+    Vec2 spine_position(const SubPath& subpath, double u) const;
+    Vec2 spine_gradient(const SubPath& subpath, double u) const;
+    Vec2 center_position(const SubPath& subpath, const Interpolation& offset, double u) const;
+    Vec2 center_gradient(const SubPath& subpath, const Interpolation& offset, double u) const;
+    Vec2 left_position(const SubPath& subpath, const Interpolation& offset,
+                       const Interpolation& width, double u) const;
+    Vec2 left_gradient(const SubPath& subpath, const Interpolation& offset,
+                       const Interpolation& width, double u) const;
+    Vec2 right_position(const SubPath& subpath, const Interpolation& offset,
+                        const Interpolation& width, double u) const;
+    Vec2 right_gradient(const SubPath& subpath, const Interpolation& offset,
+                        const Interpolation& width, double u) const;
+    void spine_points(const SubPath& subpath, double u0, double u1, Array<Vec2>& result) const;
+    void center_points(const SubPath& subpath, const Interpolation& offset, double u0, double u1,
+                       Array<Vec2>& result) const;
+    void left_points(const SubPath& subpath, const Interpolation& offset,
+                     const Interpolation& width, double u0, double u1, Array<Vec2>& result) const;
+    void right_points(const SubPath& subpath, const Interpolation& offset,
+                      const Interpolation& width, double u0, double u1, Array<Vec2>& result) const;
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/style.html b/headers/style.html new file mode 100644 index 000000000..fab10f727 --- /dev/null +++ b/headers/style.html @@ -0,0 +1,185 @@ + + + + + + + style.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

style.h

+
// Style used in SVG output. Value is the SVG style to be applied to elements
+// with the given tag, e.g., "stroke: #D04030; fill: #D89080;"
+struct Style {
+    Tag tag;
+    char* value;
+};
+
+// Hash map of styles indexed by tag
+struct StyleMap {
+    uint64_t capacity;  // allocated capacity
+    uint64_t count;     // number of items in the map
+    Style* items;       // array with length capacity
+
+    void print(bool all) const;
+
+    // Deallocates the whole map, including its contents
+    void clear();
+
+    // The instance should be zeroed before using copy_from
+    void copy_from(const StyleMap& map);
+
+    // Internal use
+    void resize(uint64_t new_capacity);
+    Style* get_slot(Tag tag) const;
+
+    // Value is internally allocated and copied
+    void set(Tag tag, const char* value);
+    const char* get(Tag tag) const;
+    bool del(Tag tag);
+
+    // Function to iterate over all values in the map:
+    // for (Style* style = style_map.next(NULL); style;
+    //      style = style_map.next(style)) {…}
+    Style* next(const Style* current) const;
+};
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/utils.html b/headers/utils.html new file mode 100644 index 000000000..2e871b5ed --- /dev/null +++ b/headers/utils.html @@ -0,0 +1,315 @@ + + + + + + + utils.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

utils.h

+
// Error codes
+enum struct ErrorCode {
+    NoError = 0,
+    // Warnings
+    BooleanError,
+    IntersectionNotFound,
+    MissingReference,
+    UnsupportedRecord,
+    UnofficialSpecification,
+    InvalidRepetition,
+    Overflow,
+    // Errors
+    ChecksumError,
+    OutputFileOpenError,
+    InputFileOpenError,
+    InputFileError,
+    FileError,
+    InvalidFile,
+    InsufficientMemory,
+    ZlibError,
+};
+
+// Tag encapsulates layer and data (text) type.  The implementation details
+// might change in the future.  The only guarantee is that a zeroed Tag
+// indicates layer 0 and type 0.
+typedef uint64_t Tag;
+inline Tag make_tag(uint32_t layer, uint32_t type) {
+    return ((uint64_t)type << 32) | (uint64_t)layer;
+};
+inline uint32_t get_layer(Tag tag) { return (uint32_t)tag; };
+inline uint32_t get_type(Tag tag) { return (uint32_t)(tag >> 32); };
+inline void set_layer(Tag& tag, uint32_t layer) { tag = make_tag(layer, get_type(tag)); };
+inline void set_type(Tag& tag, uint32_t type) { tag = make_tag(get_layer(tag), type); };
+
+// Argument between 0 and 1, plus user data
+typedef double (*ParametricDouble)(double, void*);
+
+// Argument between 0 and 1, plus user data
+typedef Vec2 (*ParametricVec2)(double, void*);
+
+// Arguments: first_point, first_direction, second_point, second_direction,
+// user data
+typedef Array<Vec2> (*EndFunction)(const Vec2, const Vec2, const Vec2, const Vec2, void*);
+
+// Arguments: first_point, first_direction, second_point, second_direction,
+// center, width, user data
+typedef Array<Vec2> (*JoinFunction)(const Vec2, const Vec2, const Vec2, const Vec2, const Vec2,
+                                    double, void*);
+
+// Arguments: radius, initial_angle, final_angle, center, user data
+typedef Array<Vec2> (*BendFunction)(double, double, double, const Vec2, void*);
+
+// Returns new dynamically allocated memory.  If len if not NULL, it is set to
+// the length of the string (including the null termination).
+char* copy_string(const char* str, uint64_t* len);
+
+// If true, m is set to the multiplicative factor, i.e., angle = 0.5 * M_PI * m
+bool is_multiple_of_pi_over_2(double angle, int64_t& m);
+
+// Number of points needed to approximate an arc within some tolerance
+uint64_t arc_num_points(double angle, double radius, double tolerance);
+
+double elliptical_angle_transform(double angle, double radius_x, double radius_y);
+
+// Distance squared from p to the line defined by p1 and p2
+double distance_to_line_sq(const Vec2 p, const Vec2 p1, const Vec2 p2);
+
+// Distance from p to the line defined by p1 and p2
+double distance_to_line(const Vec2 p, const Vec2 p1, const Vec2 p2);
+
+// Finds the intersection between lines defined by point p0 and direction ut0
+// (unit vector along the line) and by point p1 and direction ut1.  Scalars u0
+// and u1 can be used to determine the intersection point:
+// p = p0 + u0 * ut0 == p1 + u1 * ut1
+void segments_intersection(const Vec2 p0, const Vec2 ut0, const Vec2 p1, const Vec2 ut1, double& u0,
+                           double& u1);
+
+void scale_and_round_array(const Array<Vec2> points, double scaling, Array<IntVec2>& scaled_points);
+
+// Swap to big-endian (do nothing if the host is big-endian)
+void big_endian_swap16(uint16_t* buffer, uint64_t n);
+void big_endian_swap32(uint32_t* buffer, uint64_t n);
+void big_endian_swap64(uint64_t* buffer, uint64_t n);
+
+// Swap to little-endian (do nothing if the host is little-endian)
+void little_endian_swap16(uint16_t* buffer, uint64_t n);
+void little_endian_swap32(uint32_t* buffer, uint64_t n);
+void little_endian_swap64(uint64_t* buffer, uint64_t n);
+
+// Update the checksum32 of checksum with count values from bytes
+uint32_t checksum32(uint32_t checksum, const uint8_t* bytes, uint64_t count);
+
+Vec2 eval_line(double t, const Vec2 p0, const Vec2 p1);
+
+// Quadratic Bézier defined by control points p0, p1 and p2 at 0 ≤ t ≤ 1
+Vec2 eval_bezier2(double t, const Vec2 p0, const Vec2 p1, const Vec2 p2);
+
+// Cubic Bézier defined by control points p0 through p3 at 0 ≤ t ≤ 1
+Vec2 eval_bezier3(double t, const Vec2 p0, const Vec2 p1, const Vec2 p2, const Vec2 p3);
+
+// Evaluate a Bézier curve defined by count control points at 0 ≤ t ≤ 1
+Vec2 eval_bezier(double t, const Vec2* ctrl, uint64_t count);
+
+// Calculates the control points for a smooth cubic Bézier interpolation
+// following:
+//
+// John D. Hobby. “Smooth, easy to compute interpolating splines.” Discrete
+// Comput. Geom., 1:123–140, 1986.
+//
+// Calculated control points ca and cb are stored in points, which must have
+// the appropriate count and layout:
+//
+// points[3 * count] = {p[0], ca[0], cb[0],
+//                      p[1], ca[1], cb[1],
+//                      …,
+//                      p[count - 1], ca[count - 1], cb[count - 1]};
+//
+// The last controls are only present if cycle == true.  Parameter angles can
+// be used to constrain the angle at any interpolation point by setting the
+// respective angle_constraints to true.  Defaults for tension (at each
+// interpolation point) and curl should be 1.
+void hobby_interpolation(uint64_t count, Vec2* points, double* angles, bool* angle_constraints,
+                         Vec2* tension, double initial_curl, double final_curl, bool cycle);
+
+// Stores the convex hull of points into result
+void convex_hull(const Array<Vec2> points, Array<Vec2>& result);
+
+// Return a global buffer with the representation of the value in fixed format
+// with a maximal precision set.  This function is meant for internal use only.
+char* double_print(double value, uint32_t precision, char* buffer, size_t buffer_size);
+
+// Returns the default SVG style for a given tag.  The return value points to a
+// statically allocated buffer that is overwritten in future calls to this
+// function.
+const char* default_svg_shape_style(Tag tag);
+const char* default_svg_label_style(Tag tag);
+
+// Thread-safe version of localtime.
+tm* get_now(tm& result);
+
+// FNV-1a hash function (64 bits)
+#define HASH_FNV_PRIME 0x00000100000001b3
+#define HASH_FNV_OFFSET 0xcbf29ce484222325
+template <class T>
+inline uint64_t hash(T key) {
+    uint64_t result = HASH_FNV_OFFSET;
+    uint8_t* byte = (uint8_t*)(&key);
+    for (unsigned i = sizeof(T); i > 0; i--) {
+        result ^= *byte++;
+        result *= HASH_FNV_PRIME;
+    }
+    return result;
+}
+
+inline uint64_t hash(const char* key) {
+    uint64_t result = HASH_FNV_OFFSET;
+    for (const char* c = key; *c; c++) {
+        result ^= (uint64_t)(*c);
+        result *= HASH_FNV_PRIME;
+    }
+    return result;
+}
+
+extern FILE* error_logger;
+void set_error_logger(FILE* log);
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/headers/vec.html b/headers/vec.html new file mode 100644 index 000000000..442de4aa2 --- /dev/null +++ b/headers/vec.html @@ -0,0 +1,389 @@ + + + + + + + vec.h — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vec.h

+
// Basic 2d coordinate used to describe polygon vertices and points in general
+// throughout the library
+struct Vec2 {
+    union {
+        struct {
+            double x, y;
+        };
+        struct {
+            double u, v;
+        };
+        struct {
+            double re, im;
+        };
+        double e[2];
+    };
+
+    bool operator==(const Vec2& vec) const { return e[0] == vec.e[0] && e[1] == vec.e[1]; }
+
+    bool operator!=(const Vec2& vec) const { return e[0] != vec.e[0] || e[1] != vec.e[1]; }
+
+    bool operator<(const Vec2& vec) const {
+        return e[0] < vec.e[0] || (e[0] == vec.e[0] && (e[1] < vec.e[1]));
+    }
+
+    bool operator>(const Vec2& vec) const {
+        return e[0] > vec.e[0] || (e[0] == vec.e[0] && (e[1] > vec.e[1]));
+    }
+
+    bool operator<=(const Vec2& vec) const {
+        return e[0] <= vec.e[0] || (e[0] == vec.e[0] && (e[1] <= vec.e[1]));
+    }
+
+    bool operator>=(const Vec2& vec) const {
+        return e[0] >= vec.e[0] || (e[0] == vec.e[0] && (e[1] >= vec.e[1]));
+    }
+
+    Vec2& operator+=(const Vec2& vec) {
+        e[0] += vec.e[0];
+        e[1] += vec.e[1];
+        return *this;
+    }
+
+    Vec2& operator+=(const double s) {
+        e[0] += s;
+        e[1] += s;
+        return *this;
+    }
+
+    Vec2& operator-=(const Vec2& vec) {
+        e[0] -= vec.e[0];
+        e[1] -= vec.e[1];
+        return *this;
+    }
+
+    Vec2& operator-=(const double s) {
+        e[0] -= s;
+        e[1] -= s;
+        return *this;
+    }
+
+    Vec2& operator*=(const Vec2& vec) {
+        e[0] *= vec.e[0];
+        e[1] *= vec.e[1];
+        return *this;
+    }
+
+    Vec2& operator*=(const double s) {
+        e[0] *= s;
+        e[1] *= s;
+        return *this;
+    }
+
+    Vec2& operator/=(const Vec2& vec) {
+        e[0] /= vec.e[0];
+        e[1] /= vec.e[1];
+        return *this;
+    }
+
+    Vec2& operator/=(const double s) {
+        e[0] /= s;
+        e[1] /= s;
+        return *this;
+    }
+
+    double inner(const Vec2& vec) const { return e[0] * vec.e[0] + e[1] * vec.e[1]; }
+
+    double length_sq() const { return inner(*this); }
+
+    double length() const { return (double)sqrt(length_sq()); }
+
+    double normalize() {
+        double len = length();
+        if (len > 0) {
+            e[0] /= len;
+            e[1] /= len;
+        }
+        return len;
+    }
+
+    double cross(const Vec2& vec) const { return x * vec.y - y * vec.x; }
+
+    double angle() const { return atan2(y, x); }
+
+    double angle(const Vec2& vec) const { return atan2(cross(vec), inner(vec)); }
+
+    Vec2 ortho() const { return Vec2{-e[1], e[0]}; }
+};
+
+inline Vec2 operator-(const Vec2& vec) { return Vec2{-vec.e[0], -vec.e[1]}; }
+
+inline Vec2 operator+(const Vec2& v1, const Vec2& v2) {
+    return Vec2{v1.e[0] + v2.e[0], v1.e[1] + v2.e[1]};
+}
+
+inline Vec2 operator+(const Vec2& vec, const double s) { return Vec2{vec.e[0] + s, vec.e[1] + s}; }
+
+inline Vec2 operator+(const double s, const Vec2& vec) { return Vec2{s + vec.e[0], s + vec.e[1]}; }
+
+inline Vec2 operator-(const Vec2& v1, const Vec2& v2) {
+    return Vec2{v1.e[0] - v2.e[0], v1.e[1] - v2.e[1]};
+}
+
+inline Vec2 operator-(const Vec2& vec, const double s) { return Vec2{vec.e[0] - s, vec.e[1] - s}; }
+
+inline Vec2 operator-(const double s, const Vec2& vec) { return Vec2{s - vec.e[0], s - vec.e[1]}; }
+
+inline Vec2 operator*(const Vec2& v1, const Vec2& v2) {
+    return Vec2{v1.e[0] * v2.e[0], v1.e[1] * v2.e[1]};
+}
+
+inline Vec2 operator*(const Vec2& vec, const double s) { return Vec2{vec.e[0] * s, vec.e[1] * s}; }
+
+inline Vec2 operator*(const double s, const Vec2& vec) { return Vec2{s * vec.e[0], s * vec.e[1]}; }
+
+inline Vec2 operator/(const Vec2& v1, const Vec2& v2) {
+    return Vec2{v1.e[0] / v2.e[0], v1.e[1] / v2.e[1]};
+}
+
+inline Vec2 operator/(const Vec2& vec, const double s) { return Vec2{vec.e[0] / s, vec.e[1] / s}; }
+
+inline Vec2 operator/(const double s, const Vec2& vec) { return Vec2{s / vec.e[0], s / vec.e[1]}; }
+
+inline Vec2 cplx_conj(const Vec2& z) { return Vec2{z.re, -z.im}; }
+
+inline Vec2 cplx_mul(const Vec2& z1, const Vec2& z2) {
+    return Vec2{z1.re * z2.re - z1.im * z2.im, z1.re * z2.im + z1.im * z2.re};
+}
+
+inline Vec2 cplx_inv(const Vec2& z) { return cplx_conj(z) / z.length_sq(); }
+
+inline Vec2 cplx_div(const Vec2& z1, const Vec2& z2) {
+    return cplx_mul(z1, cplx_conj(z2)) / z2.length_sq();
+}
+
+inline Vec2 cplx_from_angle(double angle) { return Vec2{cos(angle), sin(angle)}; }
+
+// Integer version of Vec2 used internally when reading of writing OASIS files
+struct IntVec2 {
+    union {
+        struct {
+            int64_t x, y;
+        };
+        struct {
+            int64_t u, v;
+        };
+        struct {
+            int64_t re, im;
+        };
+        int64_t e[2];
+    };
+
+    bool operator==(const IntVec2& vec) const { return e[0] == vec.e[0] && e[1] == vec.e[1]; }
+
+    bool operator!=(const IntVec2& vec) const { return e[0] != vec.e[0] || e[1] != vec.e[1]; }
+
+    bool operator<(const IntVec2& vec) const {
+        return e[0] < vec.e[0] || (e[0] == vec.e[0] && (e[1] < vec.e[1]));
+    }
+
+    bool operator>(const IntVec2& vec) const {
+        return e[0] > vec.e[0] || (e[0] == vec.e[0] && (e[1] > vec.e[1]));
+    }
+
+    bool operator<=(const IntVec2& vec) const {
+        return e[0] <= vec.e[0] || (e[0] == vec.e[0] && (e[1] <= vec.e[1]));
+    }
+
+    bool operator>=(const IntVec2& vec) const {
+        return e[0] >= vec.e[0] || (e[0] == vec.e[0] && (e[1] >= vec.e[1]));
+    }
+
+    IntVec2& operator+=(const IntVec2& vec) {
+        e[0] += vec.e[0];
+        e[1] += vec.e[1];
+        return *this;
+    }
+
+    IntVec2& operator+=(const int64_t s) {
+        e[0] += s;
+        e[1] += s;
+        return *this;
+    }
+
+    IntVec2& operator-=(const IntVec2& vec) {
+        e[0] -= vec.e[0];
+        e[1] -= vec.e[1];
+        return *this;
+    }
+
+    IntVec2& operator-=(const int64_t s) {
+        e[0] -= s;
+        e[1] -= s;
+        return *this;
+    }
+};
+
+inline IntVec2 operator-(const IntVec2& vec) { return IntVec2{-vec.e[0], -vec.e[1]}; }
+
+inline IntVec2 operator+(const IntVec2& v1, const IntVec2& v2) {
+    return IntVec2{v1.e[0] + v2.e[0], v1.e[1] + v2.e[1]};
+}
+
+inline IntVec2 operator+(const IntVec2& vec, const int64_t s) {
+    return IntVec2{vec.e[0] + s, vec.e[1] + s};
+}
+
+inline IntVec2 operator+(const int64_t s, const IntVec2& vec) {
+    return IntVec2{s + vec.e[0], s + vec.e[1]};
+}
+
+inline IntVec2 operator-(const IntVec2& v1, const IntVec2& v2) {
+    return IntVec2{v1.e[0] - v2.e[0], v1.e[1] - v2.e[1]};
+}
+
+inline IntVec2 operator-(const IntVec2& vec, const int64_t s) {
+    return IntVec2{vec.e[0] - s, vec.e[1] - s};
+}
+
+inline IntVec2 operator-(const int64_t s, const IntVec2& vec) {
+    return IntVec2{s - vec.e[0], s - vec.e[1]};
+}
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/how-tos.html b/how-tos.html new file mode 100644 index 000000000..19e27cb54 --- /dev/null +++ b/how-tos.html @@ -0,0 +1,1827 @@ + + + + + + + How-Tos — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +
+

How-Tos

+

These are a few examples of use of the Gdstk library that go beyond basic +geometry building. They should serve as reference for more complex tasks.

+
+

Parametric Cell

+

A parametric cell is a concept present in a few layout editors to facilitate +the creation of geometries based on user-defined parameters. Gdstk does not +have a parameterized cell class, but since we are building the layout from a +programming language, the full flexibility of the language can be used.

+

In this example we define a function that returns a grating coupler based on +user-defined parameters.

+
+
+
def grating(
+    period, fill_frac=0.5, length=20, width=25, layer=0, datatype=0, cell_name="Grating"
+):
+    """
+    Straight grating:
+
+    Args:
+        period: Grating period.
+        fill_frac: Filling fraction of the teeth (wrt period).
+        length: Length of the grating.
+        width: Width of the grating.
+        layer: GDSII layer number
+        datatype: GDSII data type number
+
+    Return:
+        gdstk.Cell
+    """
+    result = gdstk.Cell(cell_name)
+    x = width / 2
+    w = period * fill_frac
+    result.add(
+        gdstk.rectangle(
+            (-x, y * period), (x, y * period + w), layer=layer, datatype=datatype
+        )
+        for y in range(int(length / period))
+    )
+    return result
+
+
+

This function can be used in the following manner:

+
if __name__ == "__main__":
+    lib = gdstk.Library()
+
+    length = 20
+    grat1 = grating(3.5, length=length, layer=1, cell_name="Grating 1")
+    grat2 = grating(3.0, length=length, layer=1, cell_name="Grating 2")
+    lib.add(grat1, grat2)
+
+    main = lib.new_cell("Main")
+    main.add(gdstk.rectangle((0, -10), (150, 10)))
+    main.add(gdstk.Reference(grat1, (length, 0), rotation=numpy.pi / 2))
+    main.add(gdstk.Reference(grat2, (150 - length, 0), rotation=-numpy.pi / 2))
+
+    path = pathlib.Path(__file__).parent.absolute()
+    lib.write_gds(path / "pcell.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+Cell* grating(double period, double fill_frac, double length, double width, Tag tag,
+              const char* name) {
+    double x = width / 2;
+    double w = period * fill_frac;
+    int64_t num = (int64_t)(length / period);
+
+    Cell* result = (Cell*)allocate_clear(sizeof(Cell));
+    result->name = copy_string(name, NULL);
+    result->polygon_array.ensure_slots(num);
+    for (int64_t i = 0; i < num; i++) {
+        double y = i * period;
+        Polygon* rect = (Polygon*)allocate(sizeof(Polygon));
+        *rect = rectangle(Vec2{-x, y}, Vec2{x, y + w}, tag);
+        result->polygon_array.append(rect);
+    }
+
+    return result;
+}
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("library", 1e-6, 1e-9);
+
+    double length = 20;
+
+    Cell* grat1 = grating(3.5, 0.5, length, 25, make_tag(1, 0), "Grating 1");
+    lib.cell_array.append(grat1);
+
+    Cell* grat2 = grating(3.0, 0.5, length, 25, make_tag(1, 0), "Grating 2");
+    lib.cell_array.append(grat2);
+
+    Cell* main_cell = (Cell*)allocate_clear(sizeof(Cell));
+    main_cell->name = copy_string("Main", NULL);
+    lib.cell_array.append(main_cell);
+
+    Polygon* rect = (Polygon*)allocate(sizeof(Polygon));
+    *rect = rectangle(Vec2{0, -10}, Vec2{150, 10}, 0);
+    main_cell->polygon_array.append(rect);
+
+    Reference* ref1 = (Reference*)allocate_clear(sizeof(Reference));
+    ref1->init(grat1);
+    ref1->origin = Vec2{length, 0};
+    ref1->rotation = M_PI / 2;
+    main_cell->reference_array.append(ref1);
+
+    Reference* ref2 = (Reference*)allocate_clear(sizeof(Reference));
+    ref2->type = ReferenceType::Cell, ref2->cell = grat2, ref2->origin = Vec2{150 - length, 0},
+    ref2->rotation = -M_PI / 2, ref2->magnification = 1, main_cell->reference_array.append(ref2);
+
+    lib.write_gds("pcell.gds", 0, NULL);
+
+    lib.free_all();
+    return 0;
+}
+
+
+
+
+_images/parametric_cell.svg +
+
+

Parts Library

+
+

Creating a Library

+

A GDSII parts library can be used when there are several devices that are often +used in different layouts. It can be a personal library of devices, or part of +a process design kit (PDK) offered by the company responsible for fabrication.

+

Here we create a simple personal library with 3 components: an alignment mark, +a directional coupler and a Mach-Zehnder interferometer. All parts are added +to a GDSII file and saved for later. Note that the interferometer already uses +the directional coupler as a subcomponent.

+
+
+
import pathlib
+import numpy
+import gdstk
+
+
+def alignment_mark(lib):
+    cross = gdstk.cross((0, 0), 50, 3, layer=1)
+    lib.new_cell("Alignment Mark").add(cross)
+
+
+def directional_coupler(lib):
+    path = gdstk.RobustPath((0, 0), [0.5, 0.5], 2, simple_path=True, layer=1)
+    path.segment((0.1, 0), relative=True)
+    path.segment((2.2, 0), offset=(0.6, "smooth"), relative=True)
+    path.segment((0.4, 0), relative=True)
+    path.segment((2.2, 0), offset=(2, "smooth"), relative=True)
+    path.segment((0.1, 0), relative=True)
+    lib.new_cell("Directinal Coupler").add(path)
+
+
+def mach_zehnder_interferometer(lib):
+    cell = lib.new_cell("MZI")
+    cell.add(gdstk.Reference("Directinal Coupler", (0, 0)))
+    cell.add(gdstk.Reference("Directinal Coupler", (75, 0)))
+
+    points = numpy.array([(5, 1), (25, 1), (25, 40), (55, 40), (55, 1), (75, 1)])
+    arm1 = gdstk.FlexPath(points, 0.5, bend_radius=15, simple_path=True, layer=1)
+    points[:, 1] *= -1
+    arm2 = gdstk.FlexPath(points, 0.5, bend_radius=15, simple_path=True, layer=1)
+    points = numpy.array([(25, 20), (25, 40), (55, 40), (55, 20)])
+    heater1 = gdstk.FlexPath(points, 2, bend_radius=15, simple_path=True, layer=10)
+    points[:, 1] *= -1
+    heater2 = gdstk.FlexPath(points, 2, bend_radius=15, simple_path=True, layer=10)
+    cell.add(arm1, arm2, heater1, heater2)
+
+
+if __name__ == "__main__":
+    lib = gdstk.Library("Photonics")
+
+    alignment_mark(lib)
+    directional_coupler(lib)
+    mach_zehnder_interferometer(lib)
+
+    path = pathlib.Path(__file__).parent.absolute()
+    lib.write_gds(path / "photonics.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+Cell* alignment_mark() {
+    Cell* cell = (Cell*)allocate_clear(sizeof(Cell));
+    cell->name = copy_string("Alignment Mark", NULL);
+
+    Polygon* cross_ = (Polygon*)allocate(sizeof(Polygon));
+    *cross_ = cross(Vec2{0, 0}, 50, 3, make_tag(1, 0));
+    cell->polygon_array.append(cross_);
+
+    return cell;
+}
+
+Cell* directional_coupler() {
+    Cell* cell = (Cell*)allocate_clear(sizeof(Cell));
+    cell->name = copy_string("Directional Coupler", NULL);
+
+    double widths[] = {0.5, 0.5};
+    double offsets[] = {-1, 1};
+    Tag tags[] = {make_tag(1, 0), make_tag(1, 0)};
+    RobustPath* path = (RobustPath*)allocate_clear(sizeof(RobustPath));
+    path->init(Vec2{0, 0}, 2, widths, offsets, 0.01, 1000, tags);
+
+    Interpolation offset[4];
+    offset[0].type = InterpolationType::Smooth;
+    offset[0].initial_value = -1;
+    offset[0].final_value = -0.3;
+    offset[1].type = InterpolationType::Smooth;
+    offset[1].initial_value = 1;
+    offset[1].final_value = 0.3;
+    offset[2].type = InterpolationType::Smooth;
+    offset[2].initial_value = -0.3;
+    offset[2].final_value = -1;
+    offset[3].type = InterpolationType::Smooth;
+    offset[3].initial_value = 0.3;
+    offset[3].final_value = 1;
+
+    path->segment(Vec2{0.1, 0}, NULL, NULL, true);
+    path->segment(Vec2{2.2, 0}, NULL, offset, true);
+    path->segment(Vec2{0.4, 0}, NULL, NULL, true);
+    path->segment(Vec2{2.2, 0}, NULL, offset + 2, true);
+    path->segment(Vec2{0.1, 0}, NULL, NULL, true);
+    cell->robustpath_array.append(path);
+
+    return cell;
+}
+
+Cell* mach_zenhder_interferometer(Cell* directional_coupler_cell) {
+    Cell* cell = (Cell*)allocate_clear(sizeof(Cell));
+    cell->name = copy_string("MZI", NULL);
+
+    Reference* ref = (Reference*)allocate_clear(sizeof(Reference));
+    ref->init(directional_coupler_cell);
+    cell->reference_array.append(ref);
+
+    ref = (Reference*)allocate_clear(sizeof(Reference));
+    ref->init(directional_coupler_cell);
+    ref->origin.x = 75;
+    cell->reference_array.append(ref);
+
+    const Vec2 starting_points[] = {{5, 1}, {5, -1}, {25, 20}, {25, -20}};
+    FlexPath* path[4];
+    for (int64_t i = 0; i < COUNT(path); i++) {
+        path[i] = (FlexPath*)allocate_clear(sizeof(FlexPath));
+        path[i]->simple_path = true;
+        path[i]->init(starting_points[i], 1, i < 2 ? 0.5 : 2, 0, 0.01, make_tag(i < 2 ? 1 : 10, 0));
+        path[i]->elements[0].bend_type = BendType::Circular;
+        path[i]->elements[0].bend_radius = 15;
+    }
+
+    Vec2 arm_points[] = {{25, 1}, {25, 40}, {55, 40}, {55, 1}, {75, 1}};
+    path[0]->segment({.capacity = 0, .count = COUNT(arm_points), .items = arm_points}, NULL, NULL,
+                     false);
+
+    for (int64_t i = 0; i < COUNT(arm_points); i++) arm_points[i].y = -arm_points[i].y;
+    path[1]->segment({.capacity = 0, .count = COUNT(arm_points), .items = arm_points}, NULL, NULL,
+                     false);
+
+    Vec2 heater_points[] = {{25, 40}, {55, 40}, {55, 20}};
+    path[2]->segment({.capacity = 0, .count = COUNT(heater_points), .items = heater_points}, NULL,
+                     NULL, false);
+
+    for (int64_t i = 0; i < COUNT(heater_points); i++) heater_points[i].y = -heater_points[i].y;
+    path[3]->segment({.capacity = 0, .count = COUNT(heater_points), .items = heater_points}, NULL,
+                     NULL, false);
+
+    cell->flexpath_array.extend({.capacity = 0, .count = COUNT(path), .items = path});
+
+    return cell;
+}
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("Photonics", 1e-6, 1e-9);
+    lib.cell_array.append(alignment_mark());
+    Cell* directional_coupler_cell = directional_coupler();
+    lib.cell_array.append(directional_coupler_cell);
+    lib.cell_array.append(mach_zenhder_interferometer(directional_coupler_cell));
+    lib.write_gds("photonics.gds", 0, NULL);
+    lib.free_all();
+    return 0;
+}
+
+
+
+
+
+
+

Using a Library

+

The library “photonics.gds” created above is used in the design of a larger +layout. It is imported through gdstk.read_rawcells() so that is uses as +little memory and processing power as possible.

+
+

Important

+

Using gdstk.RawCell will only work properly when both the library and the +current layout use the same unit and precision.

+
+

Another option for creating libraries is to store them as python modules. The +grating example in Parametric Cell can be saved in a file “photonics.py” +and imported as a Python module, as long as it can be found in the Python path +(leaving it in the current working directory is sufficient).

+
+
+
import pathlib
+import numpy
+import gdstk
+import pcell
+
+
+if __name__ == "__main__":
+    path = pathlib.Path(__file__).parent.absolute()
+
+    # Check library units. In this case it is using the default units.
+    units = gdstk.gds_units(path / "photonics.gds")
+    print(f"Using unit = {units[0]}, precision = {units[1]}")
+
+    # Load the library as a dictionary of RawCell
+    pdk = gdstk.read_rawcells(path / "photonics.gds")
+
+    # Cell holding a single device (MZI)
+    dev_cell = gdstk.Cell("Device")
+    dev_cell.add(gdstk.Reference(pdk["MZI"], (-40, 0)))
+
+    # Create a grating coupler using the function imported from the
+    # pcell module (pcell.py) created earlier.
+    grating = pcell.grating(0.62, layer=2)
+    # Add 4 grating couplers to the device cell: one for each port.
+    dev_cell.add(
+        gdstk.Reference(
+            grating, (-200, -150), rotation=numpy.pi / 2, columns=2, spacing=(300, 0)
+        ),
+        gdstk.Reference(
+            grating, (200, 150), rotation=-numpy.pi / 2, columns=2, spacing=(300, 0)
+        ),
+    )
+
+    # Create a waveguide connecting a grating to a MZI port.
+    waveguide = gdstk.FlexPath((-220, -150), 20, bend_radius=15, layer=1)
+    # Grating background
+    waveguide.segment((20, 0), relative=True)
+    # Linear taper
+    waveguide.segment((-100, -150), 0.5)
+    # Connection to MZI
+    waveguide.segment([(-70, -150), (-70, -1), (-40, -1)])
+    # Since the device is symmetrical, we can create a cell with the
+    # waveguide geometry and reuse it for all 4 ports.
+    wg_cell = gdstk.Cell("Waveguide")
+    wg_cell.add(waveguide)
+
+    dev_cell.add(gdstk.Reference(wg_cell))
+    dev_cell.add(gdstk.Reference(wg_cell, x_reflection=True))
+    dev_cell.add(gdstk.Reference(wg_cell, rotation=numpy.pi))
+    dev_cell.add(gdstk.Reference(wg_cell, rotation=numpy.pi, x_reflection=True))
+
+    # Main cell with 2 devices and lithography alignment marks
+    main = gdstk.Cell("Main")
+    main.add(
+        gdstk.Reference(dev_cell, (250, 250)),
+        gdstk.Reference(dev_cell, (250, 750)),
+        gdstk.Reference(pdk["Alignment Mark"], columns=2, rows=3, spacing=(500, 500)),
+    )
+
+    lib = gdstk.Library()
+    lib.add(main, *main.dependencies(True))
+    lib.write_gds(path / "layout.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+// We redefine the grating function from pcell.cpp here instead of including
+// the file because it contains a main function already.  In practice, the
+// library source would only contain the relevant functions, but no main.
+Cell* grating(double period, double fill_frac, double length, double width, Tag tag,
+              const char* name) {
+    double x = width / 2;
+    double w = period * fill_frac;
+    int64_t num = (int64_t)(length / period);
+
+    Cell* result = (Cell*)allocate_clear(sizeof(Cell));
+    result->name = copy_string(name, NULL);
+    result->polygon_array.ensure_slots(num);
+    for (int64_t i = 0; i < num; i++) {
+        double y = i * period;
+        Polygon* rect = (Polygon*)allocate(sizeof(Polygon));
+        *rect = rectangle(Vec2{-x, y}, Vec2{x, y + w}, tag);
+        result->polygon_array.append(rect);
+    }
+
+    return result;
+}
+
+int main(int argc, char* argv[]) {
+    double unit = 0;
+    double precision = 0;
+
+    ErrorCode error_code = gds_units("photonics.gds", unit, precision);
+    if (error_code != ErrorCode::NoError) exit(EXIT_FAILURE);
+
+    printf("Using unit = %.3g, precision = %.3g\n", unit, precision);
+
+    Map<RawCell*> pdk = read_rawcells("photonics.gds", NULL);
+
+    Cell* dev_cell = (Cell*)allocate_clear(sizeof(Cell));
+    dev_cell->name = copy_string("Device", NULL);
+
+    Reference* mzi_ref = (Reference*)allocate_clear(sizeof(Reference));
+    mzi_ref->init(pdk.get("MZI"));
+    mzi_ref->origin = Vec2{-40, 0};
+    dev_cell->reference_array.append(mzi_ref);
+
+    Cell* grating_cell = grating(0.62, 0.5, 20, 25, make_tag(2, 0), "Grating");
+
+    // We set type of these references to Regular so that we can apply the
+    // rotation to the translation vectors v1 and v2 of the repetition. This
+    // way, the GDSII writer will create and AREF element instead of multiple
+    // SREFs. If x_reflection was set to true, that would also have to be
+    // applied to v2 for an AREF to be created.
+    Reference* grating_ref1 = (Reference*)allocate_clear(sizeof(Reference));
+    grating_ref1->init(grating_cell);
+    grating_ref1->origin = Vec2{-200, -150};
+    grating_ref1->rotation = M_PI / 2;
+    grating_ref1->repetition.type = RepetitionType::Regular;
+    grating_ref1->repetition.columns = 2;
+    grating_ref1->repetition.rows = 1;
+    grating_ref1->repetition.v1 = Vec2{0, 300};
+    grating_ref1->repetition.v2 = Vec2{1, 0};
+    dev_cell->reference_array.append(grating_ref1);
+
+    Reference* grating_ref2 = (Reference*)allocate_clear(sizeof(Reference));
+    grating_ref2->init(grating_cell);
+    grating_ref2->origin = Vec2{200, 150};
+    grating_ref2->rotation = -M_PI / 2;
+    grating_ref2->repetition.type = RepetitionType::Regular;
+    grating_ref2->repetition.columns = 2;
+    grating_ref2->repetition.rows = 1;
+    grating_ref2->repetition.v1 = Vec2{0, -300};
+    grating_ref2->repetition.v2 = Vec2{1, 0};
+
+    dev_cell->reference_array.append(grating_ref2);
+
+    FlexPath* waveguide = (FlexPath*)allocate_clear(sizeof(FlexPath));
+    waveguide->init(Vec2{-220, -150}, 1, 20, 0, 0.01, make_tag(1, 0));
+    waveguide->elements[0].bend_type = BendType::Circular;
+    waveguide->elements[0].bend_radius = 15;
+
+    waveguide->segment(Vec2{20, 0}, NULL, NULL, true);
+
+    const double w = 0.5;
+    waveguide->segment(Vec2{-100, -150}, &w, NULL, false);
+
+    Vec2 p[] = {{-70, -150}, {-70, -1}, {-40, -1}};
+    waveguide->segment({.capacity = 0, .count = COUNT(p), .items = p}, NULL, NULL, false);
+
+    Cell* wg_cell = (Cell*)allocate_clear(sizeof(Cell));
+    wg_cell->name = copy_string("Waveguide", NULL);
+    wg_cell->flexpath_array.append(waveguide);
+
+    for (uint64_t i = 0; i < 4; i++) {
+        Reference* wg_ref = (Reference*)allocate_clear(sizeof(Reference));
+        wg_ref->init(wg_cell);
+        if (i == 1) {
+            wg_ref->x_reflection = true;
+        } else if (i == 2) {
+            wg_ref->rotation = M_PI;
+        } else if (i == 3) {
+            wg_ref->rotation = M_PI;
+            wg_ref->x_reflection = true;
+        }
+        dev_cell->reference_array.append(wg_ref);
+    }
+
+    Cell* main_cell = (Cell*)allocate_clear(sizeof(Cell));
+    main_cell->name = copy_string("Main", NULL);
+
+    for (uint64_t i = 0; i < 2; i++) {
+        Reference* dev_ref = (Reference*)allocate_clear(sizeof(Reference));
+        dev_ref->init(dev_cell);
+        dev_ref->origin = i == 0 ? Vec2{250, 250} : Vec2{250, 750};
+        main_cell->reference_array.append(dev_ref);
+    }
+
+    Reference* align_ref = (Reference*)allocate_clear(sizeof(Reference));
+    align_ref->init(pdk.get("Alignment Mark"));
+    align_ref->repetition = {RepetitionType::Rectangular, 2, 3, Vec2{500, 500}};
+    main_cell->reference_array.append(align_ref);
+
+    Library lib = {};
+    lib.init("library", unit, precision);
+    lib.cell_array.append(main_cell);
+
+    Map<Cell*> dependencies = {};
+    main_cell->get_dependencies(true, dependencies);
+    dependencies.to_array(lib.cell_array);
+    dependencies.clear();
+
+    Map<RawCell*> raw_dependencies = {};
+    main_cell->get_raw_dependencies(true, raw_dependencies);
+    raw_dependencies.to_array(lib.rawcell_array);
+    raw_dependencies.clear();
+
+    lib.write_gds("layout.gds", 0, NULL);
+
+    lib.free_all();
+
+    // Library::free_all does not free RawCells
+    for (MapItem<RawCell*>* item = pdk.next(NULL); item; item = pdk.next(item)) {
+        item->value->clear();
+        free_allocation(item->value);
+    }
+    pdk.clear();
+
+    return 0;
+}
+
+
+
+
+_images/layout.svg +
+
+
+

Merging Libraries

+

Merging two or more libraries is only a matter of adding all the cells from one +into the other. Extra cells can be latter added, of course, to create new top +level cells with references from both originals. In this example, we only +merge two GDSII files into a new one—which will end up with 2 top level +cells—and take care of renaming all cells so that they don’t collide.

+
+
+
import pathlib
+import gdstk
+
+
+def make_first_lib(filename):
+    lib = gdstk.Library("First")
+    main = lib.new_cell("Main")
+    main.add(*gdstk.text("First library", 10, (0, 0)))
+    ref1 = lib.new_cell("Square")
+    ref1.add(gdstk.rectangle((-15, 0), (-5, 10)))
+    main.add(gdstk.Reference(ref1))
+    ref2 = lib.new_cell("Circle")
+    ref2.add(gdstk.ellipse((0, 0), 4))
+    ref1.add(gdstk.Reference(ref2, (-10, 5)))
+    lib.write_gds(filename)
+
+
+def make_second_lib(filename):
+    lib = gdstk.Library("Second")
+    main = lib.new_cell("Main")
+    main.add(*gdstk.text("Second library", 10, (0, 0)))
+    ref = lib.new_cell("Circle")
+    ref.add(gdstk.ellipse((-10, 5), 5))
+    main.add(gdstk.Reference(ref))
+    lib.write_gds(filename)
+
+
+if __name__ == "__main__":
+    path = pathlib.Path(__file__).parent.absolute()
+
+    # First we create the two libraries we'll be merging
+    make_first_lib(path / "lib1.gds")
+    make_second_lib(path / "lib2.gds")
+
+    # Now we load the existing libraries
+    lib1 = gdstk.read_gds(path / "lib1.gds")
+    lib2 = gdstk.read_gds(path / "lib2.gds")
+
+    # We add all cells from the second library to the first
+    lib1_cell_names = {c.name for c in lib1.cells}
+    for cell in lib2.cells:
+        # We must check that all names are unique within the merged library
+        if cell.name in lib1_cell_names:
+            cell.name += "-lib2"
+            assert cell.name not in lib1_cell_names
+        # Now we add the cell and update the set of names
+        lib1.add(cell)
+        lib1_cell_names.add(cell.name)
+
+    lib1.write_gds(path / "merging.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+void make_first_lib(const char* filename) {
+    char lib_name[] = "First";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    char main_cell_name[] = "Main";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    Array<Polygon*> allocated_polygons = {};
+    text("First library", 10, Vec2{0, 0}, false, 0, allocated_polygons);
+    main_cell.polygon_array.extend(allocated_polygons);
+
+    char square_cell_name[] = "Square";
+    Cell square_cell = {.name = square_cell_name};
+    lib.cell_array.append(&square_cell);
+
+    Polygon square = rectangle(Vec2{-15, 0}, Vec2{-5, 10}, 0);
+    square_cell.polygon_array.append(&square);
+
+    Reference square_referece = {
+        .type = ReferenceType::Cell,
+        .cell = &square_cell,
+        .magnification = 1,
+    };
+    main_cell.reference_array.append(&square_referece);
+
+    char circle_cell_name[] = "Circle";
+    Cell circle_cell = {.name = circle_cell_name};
+    lib.cell_array.append(&circle_cell);
+
+    Polygon circle = ellipse(Vec2{0, 0}, 4, 4, 0, 0, 0, 0, 0.01, 0);
+    circle_cell.polygon_array.append(&circle);
+
+    Reference circle_referece = {
+        .type = ReferenceType::Cell,
+        .cell = &circle_cell,
+        .origin = {-10, 5},
+        .magnification = 1,
+    };
+    square_cell.reference_array.append(&circle_referece);
+
+    lib.write_gds(filename, 0, NULL);
+
+    lib.cell_array.clear();
+    main_cell.polygon_array.clear();
+    main_cell.reference_array.clear();
+    square_cell.polygon_array.clear();
+    square_cell.reference_array.clear();
+    circle_cell.polygon_array.clear();
+    square.clear();
+    circle.clear();
+    for (uint64_t i = 0; i < allocated_polygons.count; i++) {
+        allocated_polygons[i]->clear();
+        free_allocation(allocated_polygons[i]);
+    }
+    allocated_polygons.clear();
+}
+
+void make_second_lib(const char* filename) {
+    char lib_name[] = "Second";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    char main_cell_name[] = "Main";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    Array<Polygon*> allocated_polygons = {};
+    text("Second library", 10, Vec2{0, 0}, false, 0, allocated_polygons);
+    main_cell.polygon_array.extend(allocated_polygons);
+
+    char circle_cell_name[] = "Circle";
+    Cell circle_cell = {.name = circle_cell_name};
+    lib.cell_array.append(&circle_cell);
+
+    Polygon circle = ellipse(Vec2{-10, 5}, 5, 5, 0, 0, 0, 0, 0.01, 0);
+    circle_cell.polygon_array.append(&circle);
+
+    Reference circle_referece = {
+        .type = ReferenceType::Cell,
+        .cell = &circle_cell,
+        .magnification = 1,
+    };
+    main_cell.reference_array.append(&circle_referece);
+
+    lib.write_gds(filename, 0, NULL);
+
+    lib.cell_array.clear();
+    main_cell.polygon_array.clear();
+    main_cell.reference_array.clear();
+    circle_cell.polygon_array.clear();
+    circle.clear();
+    for (uint64_t i = 0; i < allocated_polygons.count; i++) {
+        allocated_polygons[i]->clear();
+        free_allocation(allocated_polygons[i]);
+    }
+    allocated_polygons.clear();
+}
+
+int main(int argc, char* argv[]) {
+    make_first_lib("lib1.gds");
+    make_second_lib("lib2.gds");
+
+    Library lib1 = read_gds("lib1.gds", 0, 1e-2, NULL, NULL);
+    Library lib2 = read_gds("lib2.gds", 0, 1e-2, NULL, NULL);
+
+    // We could use a hash table to make this more efficient, but we're aiming
+    // for simplicity.
+    for (uint64_t i = 0; i < lib2.cell_array.count; i++) {
+        Cell* cell = lib2.cell_array[i];
+        for (uint64_t j = 0; j < lib1.cell_array.count; j++) {
+            if (strcmp(cell->name, lib1.cell_array[j]->name) == 0) {
+                uint64_t len = strlen(cell->name);
+                cell->name = (char*)reallocate(cell->name, len + 6);
+                strcpy(cell->name + len, "-lib2");
+                // We should make sure the new name is also unique, but we are
+                // skipping that.
+                break;
+            }
+        }
+        lib1.cell_array.append(cell);
+    }
+
+    lib1.write_gds("merging.gds", 0, NULL);
+
+    // Avoid double-freeing cells from lib2
+    lib2.cell_array.clear();
+    lib2.free_all();
+    lib1.free_all();
+
+    return 0;
+}
+
+
+
+
+
+
+

Transformations

+

Geometry transformations can be accomplished in several ways. Individual +polygons or paths can be transformed by their respective methods +(gdstk.Polygon.scale(), gdstk.FlexPath.rotate(), +gdstk.RobustPath.translate(), etc.).

+

In order to transform an entire gdstk.Cell, we can use a +gdstk.Reference with the desired transformation or create a +transformed copy with gdstk.Cell.copy(). The former has the advantage of +using less memory, because it does not create actual copies of the geometry or +labels, so it is generally preferable. The latter is particularly useful when +changes to the transformed cell contents are needed and the original should not +be modified.

+
+
+
import numpy
+import gdstk
+
+
+if __name__ == "__main__":
+    n = 3  # Number of unit cells around defect
+    d = 0.2  # Unit cell size
+    r = 0.05  # Circle radius
+    s = 1.5  # Scaling factor
+
+    # Create a simple unit cell
+    unit_cell = gdstk.Cell("Unit Cell")
+    unit_cell.add(gdstk.ellipse((0, 0), r, tolerance=1e-3))
+
+    # Build a resonator from a unit cell grid with a defect inside
+    ressonator = gdstk.Cell("Resonator")
+    patches = [
+        gdstk.Reference(
+            unit_cell, (-n * d, -n * d), columns=2 * n + 1, rows=n, spacing=(d, d)
+        ),
+        gdstk.Reference(
+            unit_cell, (-n * d, d), columns=2 * n + 1, rows=n, spacing=(d, d)
+        ),
+        gdstk.Reference(unit_cell, (-n * d, 0), columns=n, rows=1, spacing=(d, d)),
+        gdstk.Reference(unit_cell, (d, 0), columns=n, rows=1, spacing=(d, d)),
+    ]
+    # Defect
+    rect = gdstk.rectangle((-r / 2, -r / 2), (r / 2, r / 2))
+    # Path for illustration
+    path = gdstk.FlexPath(
+        [(-n * d, 0), (n * d, 0)],
+        r,
+        ends=(r, r),
+        simple_path=True,
+        scale_width=False,
+        layer=1,
+    )
+    ressonator.add(rect, path, *patches)
+
+    # Main output cell with the original resonator,…
+    main = gdstk.Cell("Main")
+    main.add(gdstk.Reference(ressonator))
+    main.add(*gdstk.text("Original", d, ((n + 1) * d, -d / 2)))
+
+    # … a copy created by scaling a reference to the original resonator,…
+    main.add(gdstk.Reference(ressonator, (0, (1 + s) * (n + 1) * d), magnification=s))
+    main.add(
+        *gdstk.text("Reference\nscaling", d, (s * (n + 1) * d, (1 + s) * (n + 1) * d))
+    )
+
+    # … and another copy created by copying and scaling the Cell itself.
+    ressonator_copy = ressonator.copy("Resonator Copy", magnification=s)
+    main.add(gdstk.Reference(ressonator_copy, (0, (1 + 3 * s) * (n + 1) * d)))
+    main.add(
+        *gdstk.text(
+            "Cell copy\nscaling", d, (s * (n + 1) * d, (1 + 3 * s) * (n + 1) * d)
+        )
+    )
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    char lib_name[] = "library";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    int64_t n = 3;    // Unit cells around defect
+    double d = 0.2;   // Unit cell size
+    double r = 0.05;  // Circle radius
+    double s = 1.5;   // Scaling factor
+
+    char unit_cell_name[] = "Unit Cell";
+    Cell unit_cell = {.name = unit_cell_name};
+    lib.cell_array.append(&unit_cell);
+
+    Polygon circle = ellipse(Vec2{0, 0}, r, r, 0, 0, 0, 0, 1e-3, 0);
+    unit_cell.polygon_array.append(&circle);
+
+    char resonator_cell_name[] = "Resonator";
+    Cell resonator_cell = {.name = resonator_cell_name};
+    lib.cell_array.append(&resonator_cell);
+
+    Reference unit_refs[] = {
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .origin = Vec2{-n * d, -n * d},
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, (uint16_t)(2 * n + 1), (uint16_t)n,
+                           Vec2{d, d}},
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .origin = Vec2{-n * d, d},
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, (uint16_t)(2 * n + 1), (uint16_t)n,
+                           Vec2{d, d}},
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .origin = Vec2{-n * d, 0},
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, (uint16_t)n, 1, Vec2{d, d}},
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .origin = Vec2{d, 0},
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, (uint16_t)n, 1, Vec2{d, d}},
+        },
+    };
+    Reference* unit_refs_p[] = {unit_refs, unit_refs + 1, unit_refs + 2, unit_refs + 3};
+    resonator_cell.reference_array.extend({.capacity = 0, .count = 4, .items = unit_refs_p});
+
+    Polygon rect = rectangle(Vec2{-r / 2, -r / 2}, Vec2{r / 2, r / 2}, 0);
+    resonator_cell.polygon_array.append(&rect);
+
+    FlexPath path = {
+        .simple_path = true,
+        .scale_width = false,
+    };
+    path.init(Vec2{-n * d, 0}, 1, r, 0, 0.01, make_tag(1, 0));
+    path.elements[0].end_type = EndType::Extended;
+    path.elements[0].end_extensions = Vec2{r, r};
+    path.segment(Vec2{n * d, 0}, NULL, NULL, false);
+    resonator_cell.flexpath_array.append(&path);
+
+    char main_cell_name[] = "Main";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    Cell resonator_cell_copy = {};
+    lib.cell_array.append(&resonator_cell_copy);
+    resonator_cell_copy.copy_from(resonator_cell, "Resonator Copy", true);
+    for (int64_t i = 0; i < resonator_cell_copy.polygon_array.count; i++) {
+        Polygon* p = resonator_cell_copy.polygon_array[i];
+        p->scale(Vec2{s, s}, Vec2{0, 0});
+    }
+    for (int64_t i = 0; i < resonator_cell_copy.flexpath_array.count; i++) {
+        FlexPath* fp = resonator_cell_copy.flexpath_array[i];
+        fp->scale(s, Vec2{0, 0});
+    }
+    for (int64_t i = 0; i < resonator_cell_copy.robustpath_array.count; i++) {
+        RobustPath* rp = resonator_cell_copy.robustpath_array[i];
+        rp->scale(s, Vec2{0, 0});
+    }
+    for (int64_t i = 0; i < resonator_cell_copy.reference_array.count; i++) {
+        Reference* ref = resonator_cell_copy.reference_array[i];
+        ref->transform(s, false, 0, Vec2{0, 0});
+        ref->repetition.transform(s, false, 0);
+    }
+
+    Reference resonator_refs[] = {
+        {
+            .type = ReferenceType::Cell,
+            .cell = &resonator_cell,
+            .magnification = 1,
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &resonator_cell,
+            .origin = Vec2{0, (1 + s) * (n + 1) * d},
+            .magnification = s,
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &resonator_cell_copy,
+            .origin = Vec2{0, (1 + 3 * s) * (n + 1) * d},
+            .magnification = 1,
+        },
+    };
+    Reference* resonator_refs_p[] = {resonator_refs, resonator_refs + 1, resonator_refs + 2};
+    main_cell.reference_array.extend({.capacity = 0, .count = 3, .items = resonator_refs_p});
+
+    Array<Polygon*> all_text = {};
+    text("Original", d, Vec2{(n + 1) * d, -d / 2}, false, 0, all_text);
+    text("Reference\nscaling", d, Vec2{s * (n + 1) * d, (1 + s) * (n + 1) * d}, false, 0, all_text);
+    text("Cell copy\nscaling", d, Vec2{s * (n + 1) * d, (1 + 3 * s) * (n + 1) * d}, false, 0,
+         all_text);
+    main_cell.polygon_array.extend(all_text);
+
+    lib.write_gds("transforms.gds", 0, NULL);
+
+    for (uint16_t i = 0; i < all_text.count; i++) {
+        all_text[i]->clear();
+        free_allocation(all_text[i]);
+    }
+    all_text.clear();
+    circle.clear();
+    rect.clear();
+    path.clear();
+    unit_cell.polygon_array.clear();
+    resonator_cell.reference_array.clear();
+    resonator_cell.polygon_array.clear();
+    resonator_cell.flexpath_array.clear();
+    resonator_cell_copy.free_all();
+    main_cell.reference_array.clear();
+    main_cell.polygon_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/transforms.svg +
+

Note

+

The SVG output does not support the scale_width attribute of paths, that +is why the width of the path in the referencer-scaled version of the +geometry is wider that the original. When using gdstk.Cell.copy(), +the attribute is respected. This is also a problem for some GDSII viewers +and editors.

+
+
+
+

Repetitions

+

References can be effectively used to instantiate repetitive geometry across a +layout. Repetition is an extension of that idea which allows the +reuse of any element without the need for creating a gdstk.Cell. In +fact, the creation of a gdstk.Reference as an array is only a shortcut +to the creation of a single reference with a rectangular (or regular) +repetition. The following example demonstrates the use of different forms of +repetition to avoid creating all objects in memory (the final GDSII file will +contain all copies).

+
+
+
import numpy
+import gdstk
+
+
+if __name__ == "__main__":
+    # Rectangular repetition
+    square = gdstk.regular_polygon((0, 0), 0.2, 4)
+    square.repetition = gdstk.Repetition(3, 2, spacing=(1, 1))
+
+    # Regular repetition
+    triangle = gdstk.regular_polygon((0, 2.5), 0.2, 3)
+    triangle.repetition = gdstk.Repetition(3, 5, v1=(0.4, -0.3), v2=(0.4, 0.2))
+
+    # Explicit repetition
+    circle = gdstk.ellipse((3.5, 0), 0.1)
+    circle.repetition = gdstk.Repetition(offsets=[(0.5, 1), (2, 0), (1.5, 0.5)])
+
+    # X-explicit repetition
+    vline = gdstk.FlexPath([(3, 2), (3, 3.5)], 0.1, simple_path=True)
+    vline.repetition = gdstk.Repetition(x_offsets=[0.2, 0.6, 1.4, 3.0])
+
+    # Y-explicit repetition
+    hline = gdstk.RobustPath((3, 2), 0.05, simple_path=True)
+    hline.segment((6, 2))
+    hline.repetition = gdstk.Repetition(y_offsets=[0.1, 0.3, 0.7, 1.5])
+
+    main = gdstk.Cell("Main")
+    main.add(square, triangle, circle, vline, hline)
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    char lib_name[] = "library";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    char main_cell_name[] = "Main";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    Polygon square = regular_polygon(Vec2{0, 0}, 0.2, 4, 0, 0);
+    square.repetition = {RepetitionType::Rectangular, 3, 2, Vec2{1, 1}};
+    main_cell.polygon_array.append(&square);
+
+    Polygon triangle = regular_polygon(Vec2{0, 2.5}, 0.2, 3, 0, 0);
+    triangle.repetition.type = RepetitionType::Regular;
+    triangle.repetition.columns = 3;
+    triangle.repetition.rows = 5;
+    triangle.repetition.v1 = Vec2{0.4, -0.3};
+    triangle.repetition.v2 = Vec2{0.4, 0.2};
+    main_cell.polygon_array.append(&triangle);
+
+    Polygon circle = ellipse(Vec2{3.5, 0}, 0.1, 0.1, 0, 0, 0, 0, 0.01, 0);
+    Vec2 offsets[] = {{0.5, 1}, {2, 0}, {1.5, 0.5}};
+    circle.repetition.type = RepetitionType::Explicit;
+    circle.repetition.offsets.extend({.capacity = 0, .count = COUNT(offsets), .items = offsets});
+    main_cell.polygon_array.append(&circle);
+
+    FlexPath vline = {};
+    vline.init(Vec2{3, 2}, 1, 0.1, 0, 0.01, 0);
+    vline.simple_path = true;
+    vline.segment(Vec2{3, 3.5}, NULL, NULL, false);
+    double vcoords[] = {0.2, 0.6, 1.4, 3.0};
+    vline.repetition.type = RepetitionType::ExplicitX;
+    vline.repetition.coords.extend({.capacity = 0, .count = COUNT(vcoords), .items = vcoords});
+    main_cell.flexpath_array.append(&vline);
+
+    RobustPath hline = {};
+    hline.init(Vec2{3, 2}, 1, 0.05, 0, 0.01, 1000, 0);
+    hline.simple_path = true;
+    hline.segment(Vec2{6, 2}, NULL, NULL, false);
+    double hcoords[] = {0.1, 0.3, 0.7, 1.5};
+    hline.repetition.type = RepetitionType::ExplicitY;
+    hline.repetition.coords.extend({.capacity = 0, .count = COUNT(hcoords), .items = hcoords});
+    main_cell.robustpath_array.append(&hline);
+
+    lib.write_gds("repetitions.gds", 0, NULL);
+
+    square.clear();
+    triangle.clear();
+    circle.clear();
+    vline.clear();
+    hline.clear();
+    main_cell.polygon_array.clear();
+    main_cell.flexpath_array.clear();
+    main_cell.robustpath_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/repetitions.svg +

When geometry operations are applied to elements with repetitions, they are not +automatically applied. If desired the repetition can be manually applied +before executing the desired operation. The following example demonstrates +this use:

+
+
+
import numpy
+import gdstk
+
+
+if __name__ == "__main__":
+    # X-explicit repetition
+    vline = gdstk.FlexPath([(3, 2), (3, 3.5)], 0.1, simple_path=True)
+    vline.repetition = gdstk.Repetition(x_offsets=[0.2, 0.6, 1.4, 3.0])
+
+    # Y-explicit repetition
+    hline = gdstk.RobustPath((3, 2), 0.05, simple_path=True)
+    hline.segment((6, 2))
+    hline.repetition = gdstk.Repetition(y_offsets=[0.1, 0.3, 0.7, 1.5])
+
+    # Create all copies
+    vlines = vline.apply_repetition()
+    hlines = hline.apply_repetition()
+
+    # Include original elements for boolean operation
+    vlines.append(vline)
+    hlines.append(hline)
+
+    result = gdstk.boolean(vlines, hlines, "or")
+
+    main = gdstk.Cell("Main")
+    main.add(*result)
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("library", 1e-6, 1e-9);
+
+    Cell main_cell = {};
+    main_cell.name = copy_string("Main", NULL);
+    lib.cell_array.append(&main_cell);
+
+    FlexPath vline = {};
+    vline.init(Vec2{3, 2}, 1, 0.1, 0, 0.01, 0);
+    vline.simple_path = true;
+    vline.segment(Vec2{3, 3.5}, NULL, NULL, false);
+    double vcoords[] = {0.2, 0.6, 1.4, 3.0};
+    vline.repetition.type = RepetitionType::ExplicitX;
+    vline.repetition.coords.extend({.capacity = 0, .count = COUNT(vcoords), .items = vcoords});
+
+    Array<Polygon*> vlines = {};
+    vline.to_polygons(false, 0, vlines);
+    vline.clear();
+
+    // Because we know there is only a single resulting polygon we dont need to
+    // loop here.
+    vlines[0]->apply_repetition(vlines);
+
+    RobustPath hline = {};
+    hline.init(Vec2{3, 2}, 1, 0.05, 0, 0.01, 1000, 0);
+    hline.simple_path = true;
+    hline.segment(Vec2{6, 2}, NULL, NULL, false);
+    double hcoords[] = {0.1, 0.3, 0.7, 1.5};
+    hline.repetition.type = RepetitionType::ExplicitY;
+    hline.repetition.coords.extend({.capacity = 0, .count = COUNT(hcoords), .items = hcoords});
+
+    Array<Polygon*> hlines = {};
+    hline.to_polygons(false, 0, hlines);
+    hline.clear();
+
+    // Once again, no loop needed.
+    hlines[0]->apply_repetition(vlines);
+
+    Array<Polygon*> result = {};
+    boolean(vlines, hlines, Operation::Or, 1000, result);
+    for (uint64_t i = 0; i < vlines.count; i++) {
+        vlines[i]->clear();
+        free_allocation(vlines[i]);
+    }
+    vlines.clear();
+    for (uint64_t i = 0; i < hlines.count; i++) {
+        hlines[i]->clear();
+        free_allocation(hlines[i]);
+    }
+    hlines.clear();
+
+    main_cell.polygon_array.extend(result);
+    result.clear();
+
+    lib.write_gds("apply_repetition.gds", 0, NULL);
+
+    lib.clear();
+    main_cell.free_all();
+    return 0;
+}
+
+
+
+
+_images/apply_repetition.svg +
+
+

Geometry Filtering

+

Filtering the geometry of a loaded library requires only iterating over the +desired cells and objects, testing and removing those not wanted. In this +example we load the layout created in Using a Library and remove the +polygons in layer 2 (grating teeth) and paths in layer 10 (in the MZI).

+
+
+
import pathlib
+import gdstk
+
+
+if __name__ == "__main__":
+    path = pathlib.Path(__file__).parent.absolute()
+
+    # Load existing library
+    lib = gdstk.read_gds(path / "layout.gds")
+
+    for cell in lib.cells:
+        # Remove any polygons in layer 2
+        cell.filter([(2, 0)], paths=False, labels=False)
+        # Remove any paths in layer 10
+        cell.filter([(10, 0)], polygons=False, labels=False)
+
+    lib.write_gds(path / "filtered-layout.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    ErrorCode error_code = ErrorCode::NoError;
+    Library lib = read_gds("layout.gds", 0, 1e-2, NULL, &error_code);
+    if (error_code != ErrorCode::NoError) exit(EXIT_FAILURE);
+
+    for (int64_t i = 0; i < lib.cell_array.count; i++) {
+        Cell* cell = lib.cell_array[i];
+        for (int64_t j = 0; j < cell->polygon_array.count; j++) {
+            Polygon* poly = cell->polygon_array[j];
+            // Decrement j so that we don't skip over the next polygon.
+            if (get_layer(poly->tag) == 2) {
+                cell->polygon_array.remove(j--);
+                poly->clear();
+                free_allocation(poly);
+            }
+        }
+        // Loaded libraries have no RobustPath elements
+        for (int64_t j = 0; j < cell->flexpath_array.count; j++) {
+            FlexPath* fp = cell->flexpath_array[j];
+            // All paths in loaded libraries have only 1 element.
+            // Decrement j so that we don't skip over the next path.
+            if (get_layer(fp->elements[0].tag) == 10) {
+                cell->flexpath_array.remove(j--);
+                fp->clear();
+                free_allocation(fp);
+            }
+        }
+    }
+
+    lib.write_gds("filtered-layout.gds", 0, NULL);
+    lib.free_all();
+    return 0;
+}
+
+
+
+
+_images/filtering.svg +

Another common use of filtering is to remove geometry in a particular region. +In this example we create a periodic background and remove all elements that +overlap a particular shape using gdstk.inside() to test.

+
+
+
import pathlib
+import gdstk
+
+
+if __name__ == "__main__":
+    path = pathlib.Path(__file__).parent.absolute()
+
+    unit = gdstk.Cell("Unit")
+    unit.add(gdstk.cross((0, 0), 1, 0.2))
+
+    main = gdstk.Cell("Main")
+
+    # Create repeating pattern using references
+    d = 2
+    ref1 = gdstk.Reference(unit, columns=11, rows=6, spacing=(d, d * 3**0.5))
+    ref2 = gdstk.Reference(
+        unit, (d / 2, d * 3**0.5 / 2), columns=10, rows=5, spacing=(d, d * 3**0.5)
+    )
+    main.add(ref1, ref2)
+    main.flatten()
+
+    hole = gdstk.text("PY", 8 * d, (0.5 * d, 0), layer=1)
+    for pol in main.polygons:
+        if gdstk.any_inside(pol.points, hole):
+            main.remove(pol)
+
+    main.add(*hole)
+
+    gdstk.Library().add(main).write_gds(path / "pos_filtering.gds")
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    char lib_name[] = "library";
+    Library lib = {.name = lib_name, .unit = 1e-6, .precision = 1e-9};
+
+    char unit_cell_name[] = "Unit";
+    Cell unit_cell = {.name = unit_cell_name};
+
+    Polygon cross_ = cross(Vec2{0, 0}, 1, 0.2, 0);
+    unit_cell.polygon_array.append(&cross_);
+
+    char main_cell_name[] = "Main";
+    Cell main_cell = {.name = main_cell_name};
+    lib.cell_array.append(&main_cell);
+
+    double d = 2;
+    Reference unit_refs[] = {
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, 11, 6, Vec2{d, d * sqrt(3)}},
+        },
+        {
+            .type = ReferenceType::Cell,
+            .cell = &unit_cell,
+            .origin = Vec2{d / 2, d * sqrt(3) / 2},
+            .magnification = 1,
+            .repetition = {RepetitionType::Rectangular, 10, 5, Vec2{d, d * sqrt(3)}},
+        },
+    };
+    main_cell.reference_array.append(unit_refs);
+    main_cell.reference_array.append(unit_refs + 1);
+
+    Array<Reference*> removed_references = {};
+    main_cell.flatten(true, removed_references);
+    removed_references.clear();
+
+    Array<Polygon*> txt = {};
+    text("PY", 8 * d, Vec2{0.5 * d, 0}, false, make_tag(1, 0), txt);
+    for (uint64_t i = 0; i < main_cell.polygon_array.count; i++) {
+        Polygon* poly = main_cell.polygon_array[i];
+        if (any_inside(poly->point_array, txt)) {
+            poly->clear();
+            free_allocation(poly);
+            main_cell.polygon_array.remove(i--);
+        }
+    }
+
+    main_cell.polygon_array.extend(txt);
+    txt.clear();
+
+    lib.write_gds("pos_filtering.gds", 0, NULL);
+
+    cross_.clear();
+    for (uint64_t i = 0; i < main_cell.polygon_array.count; i++) {
+        main_cell.polygon_array[i]->clear();
+        free_allocation(main_cell.polygon_array[i]);
+    }
+    main_cell.reference_array.clear();
+    main_cell.polygon_array.clear();
+    unit_cell.polygon_array.clear();
+    lib.cell_array.clear();
+    return 0;
+}
+
+
+
+
+_images/pos_filtering.svg +

Finally, gdstk.read_gds() provides a way to only load specific layers and +data types from a GDSII file, and methods gdstk.Cell.get_polygons(), +gdstk.Cell.get_paths(), gdstk.Cell.get_labels() can also be used to +gather elements only from specific layers and types.

+
+
+

Points Along a Path

+

The following example shows how to add markers along a +gdstk.RobustPath. It uses the original parameterization of the path +to locate the markers, following the construction sections. Markers positioned +at a fixed distance must be calculated for each section independently.

+
+
+
import numpy
+import gdstk
+
+
+if __name__ == "__main__":
+    main = gdstk.Cell("Main")
+
+    # Create a path
+    path = gdstk.RobustPath((0, 0), 0.5)
+    path.segment((8, 0))
+    path.interpolation(
+        [(2, -4), (-2, -6), (-5, -8), (-4, -12)],
+        angles=[0, None, None, None, -numpy.pi / 4],
+        relative=True,
+    )
+    path.segment((3, -3), relative=True)
+    main.add(path)
+
+    # Major and minor markers
+    major = gdstk.regular_polygon((0, 0), 0.5, 6, layer=1)
+    minor = gdstk.rectangle((-0.1, -0.5), (0.1, 0.5), layer=1)
+    for s in range(path.size):
+        # A major marker is added at the start of each path section
+        m = major.copy()
+        m.translate(path.position(s))
+        main.add(m)
+        for u in numpy.linspace(0, 1, 5)[1:-1]:
+            # Each section receives 3 equally-spaced minor markers
+            # rotated to be aligned to the path direction
+            m = minor.copy()
+            grad = path.gradient(s + u)
+            m.rotate(numpy.arctan2(grad[1], grad[0]))
+            m.translate(path.position(s + u))
+            main.add(m)
+    # Add a major marker at the end of the path
+    major.translate(path.position(path.size))
+    main.add(major)
+
+
+
+
+
#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("library", 1e-6, 1e-9);
+
+    Cell* main_cell = (Cell*)allocate_clear(sizeof(Cell));
+    main_cell->name = copy_string("Main", NULL);
+    lib.cell_array.append(main_cell);
+
+    RobustPath* path = (RobustPath*)allocate_clear(sizeof(RobustPath));
+    path->init(Vec2{0, 0}, 1, 0.5, 0, 0.01, 1000, 0);
+    path->segment(Vec2{8, 0}, NULL, NULL, false);
+
+    Vec2 points[] = {{2, -4}, {-2, -6}, {-5, -8}, {-4, -12}};
+    double angles[] = {0, 0, 0, 0, -M_PI / 4};
+    bool angle_constraints[] = {true, false, false, false, true};
+    Vec2 tension[] = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}};
+    path->interpolation({.capacity = 0, .count = COUNT(points), .items = points}, angles,
+                        angle_constraints, tension, 1, 1, false, NULL, NULL, true);
+
+    path->segment(Vec2{3, -3}, NULL, NULL, true);
+    main_cell->robustpath_array.append(path);
+
+    Polygon* major = (Polygon*)allocate_clear(sizeof(Polygon));
+    *major = regular_polygon(Vec2{0, 0}, 0.5, 6, 0, make_tag(1, 0));
+    Polygon minor = rectangle(Vec2{-0.1, -0.5}, Vec2{0.1, 0.5}, make_tag(1, 0));
+
+    // Reserve space for all markers in the main cell
+    int64_t count = path->subpath_array.count;
+    main_cell->polygon_array.ensure_slots(1 + 4 * count);
+
+    for (int64_t i = 0; i < count; i++) {
+        Polygon* poly = (Polygon*)allocate_clear(sizeof(Polygon));
+        poly->copy_from(*major);
+        poly->translate(path->position(i, true));
+        main_cell->polygon_array.append(poly);
+        for (int64_t j = 1; j < 4; j++) {
+            poly = (Polygon*)allocate_clear(sizeof(Polygon));
+            poly->copy_from(minor);
+            double u = i + j / 4.0;
+            poly->rotate(path->gradient(u, true).angle(), Vec2{0, 0});
+            poly->translate(path->position(u, true));
+            main_cell->polygon_array.append(poly);
+        }
+    }
+
+    // Last marker: we use the original major marker
+    major->translate(path->end_point);
+    main_cell->polygon_array.append(major);
+    minor.clear();
+
+    lib.write_gds("path_markers.gds", 0, NULL);
+
+    lib.free_all();
+    return 0;
+}
+
+
+
+
+_images/path_markers.svg +
+
+

Connection Pads

+

In this example, a custom end function is used to provide connection pads for +electrical traces. For simplicity, it assumes that the path width does not +change in the first and last segments, which also must be long enough to +support the pad shapes, and that the pad diameter is larger than the path +width. The point where the pad connects to the trace can, optionally, be +filleted.

+
+
+
import numpy
+import gdstk
+
+
+if __name__ == "__main__":
+
+    def filleted_pad(pad_radius, fillet_radius=0, tolerance=0.01):
+        def _f(p0, v0, p1, v1):
+            p0 = numpy.array(p0)
+            v0 = numpy.array(v0)
+            p1 = numpy.array(p1)
+            v1 = numpy.array(v1)
+
+            half_trace_width = 0.5 * numpy.sqrt(numpy.sum((p0 - p1) ** 2))
+            a = half_trace_width + fillet_radius
+            c = pad_radius + fillet_radius
+            b = (c**2 - a**2) ** 0.5
+            alpha = numpy.arccos(a / c)
+            gamma = numpy.arctan2(v0[1], v0[0]) + 0.5 * numpy.pi
+
+            curve = gdstk.Curve(p0 - v0 * b, tolerance=tolerance)
+            if fillet_radius > 0:
+                curve.arc(fillet_radius, gamma, gamma - alpha)
+            curve.arc(pad_radius, gamma - numpy.pi - alpha, gamma + alpha)
+            if fillet_radius > 0:
+                curve.arc(fillet_radius, gamma - numpy.pi + alpha, gamma - numpy.pi)
+
+            return curve.points()
+
+        return _f
+
+    main = gdstk.Cell("Main")
+
+    # Create a bus with 4 traces
+    bus = gdstk.FlexPath(
+        [(0, 0), (10, 5)], [3] * 4, offset=15, joins="round", ends=filleted_pad(5, 3)
+    )
+    bus.segment((20, 10), offset=6)
+    bus.segment([(40, 20), (40, 50), (80, 50)])
+    bus.segment((100, 50), offset=12)
+    main.add(bus)
+
+
+
+
+
#include <math.h>
+#include <stdio.h>
+
+#include <gdstk/gdstk.hpp>
+
+using namespace gdstk;
+
+struct FilletedPadData {
+    double pad_radius;
+    double fillet_radius;
+    double tolerance;
+};
+
+Array<Vec2> filleted_pad(const Vec2 p0, const Vec2 v0, const Vec2 p1, const Vec2 v1, void* data) {
+    FilletedPadData* pad_data = (FilletedPadData*)data;
+    double pad_radius = pad_data->pad_radius;
+    double fillet_radius = pad_data->fillet_radius;
+
+    Vec2 dp = p0 - p1;
+    double half_trace_width = 0.5 * sqrt(dp.x * dp.x + dp.y * dp.y);
+    double a = half_trace_width + fillet_radius;
+    double c = pad_radius + fillet_radius;
+    double b = sqrt(c * c + a * a);
+    double alpha = acos(a / c);
+    double gamma = atan2(v0.y, v0.x) + 0.5 * M_PI;
+
+    Curve curve = {};
+    curve.init(p0 - b * v0, pad_data->tolerance);
+    if (fillet_radius > 0) {
+        curve.arc(fillet_radius, fillet_radius, gamma, gamma - alpha, 0);
+    }
+    curve.arc(pad_radius, pad_radius, gamma - M_PI - alpha, gamma + alpha, 0);
+    if (fillet_radius > 0) {
+        curve.arc(fillet_radius, fillet_radius, gamma - M_PI + alpha, gamma - M_PI, 0);
+    }
+
+    return curve.point_array;
+}
+
+int main(int argc, char* argv[]) {
+    Library lib = {};
+    lib.init("library", 1e-6, 1e-9);
+
+    Cell* main_cell = (Cell*)allocate_clear(sizeof(Cell));
+    main_cell->name = copy_string("Main", NULL);
+    lib.cell_array.append(main_cell);
+
+    FlexPath* bus = (FlexPath*)allocate_clear(sizeof(FlexPath));
+    bus->init(Vec2{0, 0}, 4, 3, 15, 0.01, 0);
+    FilletedPadData data = {5, 3, 0.01};
+    for (int64_t i = 0; i < 4; i++) {
+        bus->elements[i].join_type = JoinType::Round;
+        bus->elements[i].end_type = EndType::Function;
+        bus->elements[i].end_function = filleted_pad;
+        bus->elements[i].end_function_data = (void*)&data;
+    }
+    bus->segment(Vec2{10, 5}, NULL, NULL, false);
+    double offsets1[] = {-9, -3, 3, 9};
+    bus->segment(Vec2{20, 10}, NULL, offsets1, false);
+    Vec2 points[] = {{40, 20}, {40, 50}, {80, 50}};
+    const Array<Vec2> point_array = {.capacity = 0, .count = COUNT(points), .items = points};
+    bus->segment(point_array, NULL, NULL, false);
+    double offsets2[] = {-18, -6, 6, 18};
+    bus->segment(Vec2{100, 50}, NULL, offsets2, false);
+
+    main_cell->flexpath_array.append(bus);
+
+    lib.write_gds("pads.gds", 0, NULL);
+
+    lib.free_all();
+    return 0;
+}
+
+
+
+
+_images/pads.svg +
+
+

System Fonts

+

This example uses matplotlib to render text using +any typeface present in the system. The glyph paths are then transformed into +polygon arrays that can be used to create gdstk.Polygon objects.

+
import gdstk
+from matplotlib.font_manager import FontProperties
+from matplotlib.textpath import TextPath
+
+
+def render_text(text, size=None, position=(0, 0), font_prop=None, tolerance=0.1):
+    precision = 0.1 * tolerance
+    path = TextPath(position, text, size=size, prop=font_prop)
+    polys = []
+    xmax = position[0]
+    for points, code in path.iter_segments():
+        if code == path.MOVETO:
+            c = gdstk.Curve(points, tolerance=tolerance)
+        elif code == path.LINETO:
+            c.segment(points.reshape(points.size // 2, 2))
+        elif code == path.CURVE3:
+            c.quadratic(points.reshape(points.size // 2, 2))
+        elif code == path.CURVE4:
+            c.cubic(points.reshape(points.size // 2, 2))
+        elif code == path.CLOSEPOLY:
+            pts = c.points()
+            if pts.size > 0:
+                poly = gdstk.Polygon(pts)
+                if pts[:, 0].min() < xmax:
+                    i = len(polys) - 1
+                    while i >= 0:
+                        if polys[i].contain_any(*poly.points):
+                            p = polys.pop(i)
+                            poly = gdstk.boolean(p, poly, "xor", precision)[0]
+                            break
+                        elif poly.contain_any(*polys[i].points):
+                            p = polys.pop(i)
+                            poly = gdstk.boolean(p, poly, "xor", precision)[0]
+                        i -= 1
+                xmax = max(xmax, poly.points[:, 0].max())
+                polys.append(poly)
+    return polys
+
+
+if __name__ == "__main__":
+    cell = gdstk.Cell("fonts")
+    fp = FontProperties(family="serif", style="italic")
+    polygons = render_text("Text rendering", 10, font_prop=fp)
+    cell.add(*polygons)
+
+
+_images/fonts.svg +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..24b625c04 --- /dev/null +++ b/index.html @@ -0,0 +1,195 @@ + + + + + + + Gdstk Documentation — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +
+

Gdstk Documentation

+

Gdstk (GDSII Tool Kit) is a C++ library for creation and manipulation of GDSII +and OASIS files. It is also available as a Python module meant to be a +successor to Gdspy.

+

Key features for the creation of complex CAD layouts are included:

+
    +
  • Boolean operations on polygons (AND, OR, NOT, XOR) based on clipping +algorithm

  • +
  • Polygon offset (inward and outward rescaling of polygons)

  • +
  • Efficient point-in-polygon solutions for large array sets

  • +
+

Typical applications of Gdstk are in the fields of electronic chip design, +planar lightwave circuit design, and mechanical engineering.

+

For installation instructions and other information, please check out the +GitHub repository or the README file +included with the source.

+ +
+

Support

+

Help support the development of Gdstk by donating:

+PayPal +
+
+

License

+

Boost Software License - Version 1.0 - August 17th, 2003

+

Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the “Software”) to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following:

+

The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.Cell.html b/library/gdstk.Cell.html new file mode 100644 index 000000000..9a72feba4 --- /dev/null +++ b/library/gdstk.Cell.html @@ -0,0 +1,736 @@ + + + + + + + gdstk.Cell — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Cell

+
+
+class gdstk.Cell(name)
+

Cell structure.

+

A cell is a fundamental structure in the layout. It stores the +geometry, labels and references that make up the final layout. A single +library can contain any number of independent cells, which can, +themselves, contain references to other cells in the form of +gdstk.Reference.

+
+
Parameters:
+

name (str) – Cell name. It must be ASCII encoded and unique within a +library.

+
+
+

Methods

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

add(*elements)

Add polygons, paths, labels and references to this cell.

area([by_spec])

Calculate the area of this cell.

bounding_box()

Calculate the cell bounding box.

convex_hull()

Calculate the convex hull of the cell.

copy(name[, translation, rotation, ...])

Create a copy of this cell.

delete_property(name)

Delete the first property of this element matching a name.

dependencies([recursive])

List of cells and raw cells that are referenced by this cell.

filter(spec[, remove, polygons, paths, labels])

Remove elements from this cell based on their layer and data/text type.

flatten([apply_repetitions])

Transform all references into polygons, paths and labels.

get_labels([apply_repetitions, depth, ...])

Return a copy of all labels in the cell.

get_paths([apply_repetitions, depth, layer, ...])

Return a copy of all paths in the cell.

get_polygons([apply_repetitions, ...])

Return a copy of all polygons in the cell.

get_property(name)

Return the values of the first property of this element matching a name.

remap(layer_type_map)

Remap layers and data/text types for all elements in this cell.

remove(*elements)

Remove polygons, paths, labels and references from this cell.

set_property(name, value)

Set a property for this element.

write_svg(outfile[, scaling, precision, ...])

Export this cell to an SVG image file.

+

Attributes

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

labels

List of cell labels.

name

Cell name.

paths

List of cell paths.

polygons

List of cell polygons.

properties

Properties of this element.

references

List of cell references.

+
+
+add(*elements) self
+

Add polygons, paths, labels and references to this cell.

+
+ +
+
+area(by_spec=False) float or dictionary
+

Calculate the area of this cell.

+
+
Parameters:
+

by_spec – If True, return a dictionary with keys +(layer, datatype).

+
+
Returns:
+

Area of the geometry in this cell, optionally indexed by layer and +data type.

+
+
+
+

Notes

+

This operation can be slow because all paths and references are +included in the computation.

+
+
+ +
+
+bounding_box() tuple or None
+

Calculate the cell bounding box.

+
+
Returns:
+

The lower-left and upper-right corners of the bounding box of the +cell: ((min_x, min_y), (max_x, max_y)).

+
+
+

Examples

+
>>> polygons = gdstk.text("F", 10, (0, 0))
+>>> f_cell = gdstk.Cell("F_CELL")
+>>> f_cell.add(*polygons)
+>>> ang = numpy.pi / 4
+>>> array_ref = gdstk.Reference(f_cell, rotation=ang)
+>>> array_ref.repetition = gdstk.Repetition(columns=3, rows=2,
+...     v1=8 * numpy.exp(1j * ang), v2=10j * numpy.exp(1j * ang))
+>>> path = gdstk.FlexPath([(-5, 0), (0, -5), (5, 0)], 1,
+...                       simple_path=True)
+>>> main_cell = gdstk.Cell("MAIN")
+>>> main_cell.add(array_ref, path)
+>>> bbox = main_cell.bounding_box()
+>>> print(bbox)
+((-12.816310409006173, -5.707106781186548),
+ (11.313708498984761, 27.66555281392367))
+>>> polygon_bb = gdstk.rectangle(*bbox, datatype=1)
+
+
+../_images/bounding_box1.svg +
+

Notes

+

This operation can be slow because all paths and references are +included in the computation.

+
+
+ +
+
+convex_hull() numpy.ndarray
+

Calculate the convex hull of the cell.

+

The convex hull is the smallest convex polygon that contains all +elements of the cell.

+
+
Returns:
+

Vertices of the convex hull.

+
+
+

Examples

+
>>> polygons = gdstk.text("F", 10, (0, 0))
+>>> f_cell = gdstk.Cell("F_CELL")
+>>> f_cell.add(*polygons)
+>>> ang = numpy.pi / 4
+>>> array_ref = gdstk.Reference(f_cell, rotation=ang)
+>>> array_ref.repetition = gdstk.Repetition(columns=3, rows=2,
+...     v1=8 * numpy.exp(1j * ang), v2=10j * numpy.exp(1j * ang))
+>>> path = gdstk.FlexPath([(-5, 0), (0, -5), (5, 0)], 1,
+...                       simple_path=True)
+>>> main_cell = gdstk.Cell("MAIN")
+>>> main_cell.add(array_ref, path)
+>>> hull = main_cell.convex_hull()
+>>> polygon_hull = gdstk.Polygon(hull, datatype=1)
+
+
+../_images/convex_hull.svg +
+

Notes

+

This operation can be slow because all paths and references are +included in the computation.

+
+
+ +
+
+copy(name, translation=(0, 0), rotation=0, magnification=1, x_reflection=False, deep_copy=True) gdstk.Cell
+

Create a copy of this cell.

+

A transformation can be applied to the contents of the new cell. They +follow the same order as reference transformations.

+
+
Parameters:
+
    +
  • name (str) – Name of the new cell.

  • +
  • translation (coordinate pair or complex) – Amount to translate the +cell contents.

  • +
  • rotation – Rotation angle (in radians).

  • +
  • magnification – Scaling factor.

  • +
  • x_reflection – If True, the geometry is reflected across the +horizontal axis before rotation.

  • +
  • deep_copy – If True, new elements (polygons, paths, references, +and labels) are also created for the copied cell. If any +transformation is applied, this value is always True.

  • +
+
+
Returns:
+

Copy of this cell.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+dependencies(recursive=True) list
+

List of cells and raw cells that are referenced by this cell.

+
+
Parameters:
+

recursive – If True, includes all dependencies recursively.

+
+
+
+ +
+
+filter(spec, remove=True, polygons=True, paths=True, labels=True) self
+

Remove elements from this cell based on their layer and data/text type.

+
+
Parameters:
+
    +
  • spec (iterable of tuples) – Tuples of (layer, data/text type) to +remove or to keep in the cell.

  • +
  • remove – If True, shapes whose layer and type specification are in +spec will be removed from the cell. If False, only those +shapes will be kept, while others will be removed.

  • +
  • polygons – Whether to filter the cell’s polygons.

  • +
  • paths – Whether to filter the cell’s paths.

  • +
  • labels – Whether to filter the cell’s labels.

  • +
+
+
+

Examples

+
>>> # Remove all elements in layer 3, type 10:
+>>> cell.filter([(3, 10)], True)
+>>> # Remove all elements except for those on layer 5, type 2:
+>>> cell.filter([(5, 2)], False)
+
+
+
+ +
+
+flatten(apply_repetitions=True) self
+

Transform all references into polygons, paths and labels.

+
+
Parameters:
+

apply_repetitions – Define whether repetitions should be flattened +for polygons, paths and labels (reference repetitions are always +applied).

+
+
+

Examples

+
>>> poly1 = gdstk.Polygon([(0, 0), (1, 0), (0.5, 1)])
+>>> cell1 = gdstk.Cell('CELL_1')
+>>> cell1.add(poly1)
+>>> poly2 = gdstk.Polygon([(1, 0), (1.5, 1), (0.5, 1)], layer=1)
+>>> ref = gdstk.Reference(cell1)
+>>> ref.repetition = gdstk.Repetition(columns=2, rows=2,
+...                                   spacing=(1, 1))
+>>> cell2 = gdstk.Cell('CELL_2')
+>>> cell2.add(poly2, ref)
+>>> print(len(cell2.polygons), len(cell2.references),
+...       len(cell2.dependencies(True)))
+1 1 1
+>>> cell2.flatten()
+>>> print(len(cell2.polygons), len(cell2.references),
+...       len(cell2.dependencies(True)))
+5 0 0
+
+
+../_images/flatten.svg +
+ +
+
+get_labels(apply_repetitions=True, depth=None, layer=None, texttype=None) list
+

Return a copy of all labels in the cell.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created labels.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only labels in the defined layer and text type are +returned.

  • +
  • texttype – If set, only labels in the defined layer and text type +are returned.

  • +
+
+
+
+

Notes

+

Arguments layer and texttype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_paths(apply_repetitions=True, depth=None, layer=None, datatype=None) list
+

Return a copy of all paths in the cell.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created paths.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only paths in the defined layer and data type are +returned.

  • +
  • datatype – If set, only paths in the defined layer and data type are +returned.

  • +
+
+
+
+

Notes

+

Arguments layer and datatype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_polygons(apply_repetitions=True, include_paths=True, depth=None, layer=None, datatype=None) list
+

Return a copy of all polygons in the cell.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created polygons.

  • +
  • include_paths – If True, polygonal representation of paths are +also included in the result.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only polygons in the defined layer and data type are +returned.

  • +
  • datatype – If set, only polygons in the defined layer and data type +are returned.

  • +
+
+
+
+

Notes

+

Arguments layer and datatype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+labels
+

List of cell labels.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+name
+

Cell name.

+
+ +
+
+paths
+

List of cell paths.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+polygons
+

List of cell polygons.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+references
+

List of cell references.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+remap(layer_type_map) self
+

Remap layers and data/text types for all elements in this cell.

+
+
Parameters:
+

layer_type_map – Dictionary mapping existing (layer, type) tuples to +desired (layer, type) tuples.

+
+
+
+

Notes

+

References in this cell are not affected. To remap those, loop +over them with get_dependencies. To remap a whole libarry, use +Library.remap.

+
+
+ +
+
+remove(*elements) self
+

Remove polygons, paths, labels and references from this cell.

+

Examples

+
>>> polygons = gdstk.text("Filter dots\nin i and j!", 8, (0, 0))
+>>> cell = gdstk.Cell("FILTERED")
+>>> cell.add(*polygons)
+>>> dots = [poly for poly in cell.polygons if poly.area() < 2]
+>>> cell.remove(*dots)
+
+
+../_images/remove.svg +
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+write_svg(outfile, scaling=10, precision=6, shape_style=None, label_style=None, background='#222222', pad='5%', sort_function=None) self
+

Export this cell to an SVG image file. Colors and attributes must follow +SVG specification.

+
+
Parameters:
+
    +
  • outfile (str or pathlib.Path) – Name of the output file.

  • +
  • scaling – Scaling factor for the whole geometry.

  • +
  • precision (positive integer) – Maximum number of digits for +coordinates after scaling.

  • +
  • shape_style (dict) – SVG attributes for each layer and data type.

  • +
  • label_style (dict) – SVG attributes for each layer and text type.

  • +
  • background (str) – Image background color.

  • +
  • pad (number, str) – Viewport margin around the image content. It can +be specified as an absolute dimension or a percentage of the +largest image dimension.

  • +
  • sort_function (callable) – If set, the polygons on each cell will be +sorted according to this function. It must accept 2 polygons and +return True if the first one is below the second.

  • +
+
+
+
+

Notes

+

Labels in referenced cells will be affected by the the reference +transformation, including magnification.

+
+

Examples

+
>>> # (layer, datatype) = (0, 1)
+>>> poly1 = gdstk.ellipse((0, 0), (13, 10), datatype=1)
+>>> # (layer, datatype) = (1, 0)
+>>> poly2 = gdstk.ellipse((0, 0), (10, 7), layer=1)
+>>> (layer, texttype) = (3, 2)
+>>> label = gdstk.Label("Example", (0, 0), layer=3, texttype=2)
+>>> cell = gdstk.Cell("SVG")
+>>> cell.add(poly1, poly2, label)
+>>> cell.write_svg(
+...     "example.svg",
+...     background="none",
+...     shape_style={(0, 1): {"fill": "none",
+...                           "stroke": "black",
+...                           "stroke-dasharray": "8,8"}},
+...     label_style={(3, 2): {"fill": "none",
+...                           "stroke": "red",
+...                           "font-size": "32px"}},
+...     pad="5%",
+...     sort_function=lambda p1, p2: p1.layer < p2.layer,
+... )
+
+
+../_images/write_svg.svg +
+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.GdsWriter.html b/library/gdstk.GdsWriter.html new file mode 100644 index 000000000..d7c649e3b --- /dev/null +++ b/library/gdstk.GdsWriter.html @@ -0,0 +1,207 @@ + + + + + + + gdstk.GdsWriter — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.GdsWriter

+
+
+class gdstk.GdsWriter(outfile, name='library', unit=1e-6, precision=1e-9, max_points=199, timestamp=None)
+

Multi-step GDSII stream file writer.

+

When a design is too large to be completely created in memory, it is not +possible to create a gdstk.Library to save it as a GDSII file. +In such cases, it might be possible to still create the desired design +creating, saving and deleting one cell at a time. Saving one cell at a +time can be done thru this class.

+
+
Parameters:
+
    +
  • outfile (str or pathlib.Path) – Name of the output file.

  • +
  • unit – User units in meters.

  • +
  • precision – Desired precision to store the units once written to a +GDSII file.

  • +
  • max_points – Maximal number of vertices per polygon. Polygons with +more vertices that this are automatically fractured.

  • +
  • timestamp (datetime object) – Timestamp to be stored in the GDSII +file. If None, the current time is used.

  • +
+
+
+
+
Eaxmples:
>>> writer = gdstk.GdsWriter()
+>>> cell1 = some_function_that_creates_a_huge_cell()
+>>> writer.write(cell1)
+>>> del cell1
+>>> cell2 = some_function_that_creates_a_huge_cell()
+>>> writer.write(cell2)
+>>> del cell2
+>>> writer.close()
+
+
+
+
+ +

Methods

+ + + + + + + + + +

close()

Finish writing the output file and close it.

write(*cells)

Write cells to the output file.

+
+
+close() None
+

Finish writing the output file and close it.

+
+ +
+
+write(*cells) self
+

Write cells to the output file.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.Label.html b/library/gdstk.Label.html new file mode 100644 index 000000000..3ace4508c --- /dev/null +++ b/library/gdstk.Label.html @@ -0,0 +1,451 @@ + + + + + + + gdstk.Label — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Label

+
+
+class gdstk.Label(text, origin, anchor='o', rotation=0, magnification=1, x_reflection=False, layer=0, texttype=0)
+

Text objects with out geometrical information.

+

Labels do not create any new geometry in the layout. They can be used to +add descriptions, flags, or comments to the design. For polygonal text, +gdstk.text() should be used instead.

+
+
Parameters:
+
    +
  • text (str) – Text string.

  • +
  • origin (coordinate pair or complex) – Label position.

  • +
  • anchor (str) – Origin position with respect to the label text. One of +“n”, “s”, “e”, “w”, “o”, “ne”, “nw”, “se”, or “sw”.

  • +
  • rotation – Rotation angle (in radians).

  • +
  • magnification – Scaling factor.

  • +
  • x_reflection – If True, the label is reflected across the +horizontal axis before rotation.

  • +
  • layer – layer number assigned to this label.

  • +
  • texttype – text type number assigned to this label.

  • +
+
+
+

Examples

+
>>> frame = gdstk.rectangle((-2, -1), (2, 1), datatype=1)
+>>> label_o = gdstk.Label("Center", (0, 0), rotation=numpy.pi / 6)
+>>> label_n = gdstk.Label("North", (0, 1), "n")
+>>> label_s = gdstk.Label("South", (0, -1), "s")
+>>> label_e = gdstk.Label("East", (2, 0), "e")
+>>> label_w = gdstk.Label("West", (-2, 0), "w")
+>>> label_ne = gdstk.Label("Northeast", (2, 1), "ne")
+>>> label_se = gdstk.Label("Southeast", (2, -1), "se")
+>>> label_nw = gdstk.Label("Northwest", (-2, 1), "nw")
+>>> label_sw = gdstk.Label("Southwest", (-2, -1), "sw")
+
+
+../_images/init4.svg +

Note that this example can only be correctly displayed in browsers +with good support for text alignment in SVG images.

+
+

Notes

+

Label anchor and transformations (rotation, magnification and +reflection) are not supported by the OASIS format.

+
+

Methods

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

apply_repetition()

Create new labels based on this object's repetition attribute.

copy()

Create a copy this label.

delete_gds_property(attr)

Delete a GDSII property of this element.

delete_property(name)

Delete the first property of this element matching a name.

get_gds_property(attr)

Return a GDSII property of this element.

get_property(name)

Return the values of the first property of this element matching a name.

set_gds_property(attr, value)

Set a GDSII property for this element.

set_property(name, value)

Set a property for this element.

+

Attributes

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

anchor

Label anchor.

layer

Label layer.

magnification

Label scaling factor.

origin

Label origin.

properties

Properties of this element.

repetition

Repetition associated with this element.

rotation

Label rotation angle.

text

Label text.

texttype

Label text type.

x_reflection

Label reflection across the x axis.

+
+
+anchor
+

Label anchor.

+
+ +
+
+apply_repetition() list
+

Create new labels based on this object’s repetition attribute.

+

After the repetition is applied, the original attribute is set to +None.

+
+
Returns:
+

Newly created objects.

+
+
+
+ +
+
+copy() gdstk.Label
+

Create a copy this label.

+
+
Returns:
+

Copy of this label.

+
+
+
+ +
+
+delete_gds_property(attr) self
+

Delete a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+get_gds_property(attr) str
+

Return a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
Returns:
+

Property value. If the property number does not exist, +None is returned.

+
+
Return type:
+

str or None

+
+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+layer
+

Label layer.

+
+ +
+
+magnification
+

Label scaling factor.

+
+ +
+
+origin
+

Label origin.

+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+repetition
+

Repetition associated with this element.

+
+ +
+
+rotation
+

Label rotation angle.

+
+ +
+
+set_gds_property(attr, value) self
+

Set a GDSII property for this element.

+

GDSII properties are stored under the special name “S_GDS_PROPERTY”, as +defined by the OASIS specification.

+
+
Parameters:
+
    +
  • attr (number) – Property number.

  • +
  • value (str) – Property value.

  • +
+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+text
+

Label text.

+
+ +
+
+texttype
+

Label text type.

+
+ +
+
+x_reflection
+

Label reflection across the x axis.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.Library.html b/library/gdstk.Library.html new file mode 100644 index 000000000..ed5b7fa8b --- /dev/null +++ b/library/gdstk.Library.html @@ -0,0 +1,517 @@ + + + + + + + gdstk.Library — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Library

+
+
+class gdstk.Library(name='library', unit=1e-6, precision=1e-9)
+

GDSII/OASIS library.

+

The library is a container for multiple cells which keeps track of the +units used to generate the design.

+
+
Parameters:
+
    +
  • name – Library name.

  • +
  • unit – User units in meters.

  • +
  • precision – Desired precision to store the units once written to a +GDSII/OASIS file.

  • +
+
+
+

Examples

+
>>> lib = gdstk.read_gds("filename.gds")
+>>> num_cells = len(lib)
+>>> cell = lib["CELL_NAME"]
+
+
+
+

Notes

+

Although cells can be accessed by name this is not a cached +operation. If many queries are expected, using a cell dictionary +is more efficient, for example: +>>> cells = {c.name for c in lib.cells} +>>> cells[“CELL_NAME”]

+
+
+

See also

+

A Note About Units

+
+

Methods

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

add(*cells)

Add cells to this library.

delete_property(name)

Delete the first property of this element matching a name.

get_property(name)

Return the values of the first property of this element matching a name.

layers_and_datatypes()

Return a set of tuples with the layer and data types in the library.

layers_and_texttypes()

Return a set of tuples with the layer and text types in the library.

new_cell(name)

Create a new cell and add it to this library.

remap(layer_type_map)

Remap layers and data/text types for all elements in this library.

remove(*cells)

Remove cells from this library.

rename_cell(old_name, new_name)

Rename a cell in this library, updating any references that use the old name with the new one.

replace(*cells)

Add cells to this library, replacing any cells with the same name.

set_property(name, value)

Set a property for this element.

top_level()

Return the top-level cells in the library.

write_gds(outfile[, max_points, timestamp])

Save this library to a GDSII file.

write_oas(outfile[, compression_level, ...])

Save this library to an OASIS file.

+

Attributes

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

cells

List of library cells.

name

Library name.

precision

Library precision.

properties

Properties of this element.

unit

Library unit.

+
+
+add(*cells) self
+

Add cells to this library.

+

Examples

+
>>> polygon = gdstk.rectangle((0, 0), (1, 1))
+>>> cell = gdstk.Cell("MAIN")
+>>> cell.add(polygon)
+>>> lib = gdstk.Library()
+>>> lib.add(cell)
+
+
+
+

Notes

+

This method does not check whether cell names are duplicated in the +library. If duplicates are found in the library, the resulting file +will be invalid.

+
+ +
+ +
+
+cells
+

List of library cells.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+layers_and_datatypes() set
+

Return a set of tuples with the layer and data types in the library.

+
+ +
+
+layers_and_texttypes() set
+

Return a set of tuples with the layer and text types in the library.

+
+ +
+
+name
+

Library name.

+
+ +
+
+new_cell(name) gdstk.Cell
+

Create a new cell and add it to this library.

+
+
Parameters:
+

name (str) – Name of the new cell.

+
+
+

Examples

+
>>> lib = gdstk.Library()
+>>> cell = lib.new_cell("MAIN")
+>>> polygon = gdstk.rectangle((0, 0), (1, 1))
+>>> cell.add(polygon)
+
+
+
+ +
+
+precision
+

Library precision.

+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+remap(layer_type_map) self
+

Remap layers and data/text types for all elements in this library.

+
+
Parameters:
+

layer_type_map – Dictionary mapping existing (layer, type) tuples to +desired (layer, type) tuples.

+
+
+
+ +
+
+remove(*cells) self
+

Remove cells from this library.

+
+ +
+
+rename_cell(old_name, new_name) self
+

Rename a cell in this library, updating any references that use the old +name with the new one.

+
+
Parameters:
+
    +
  • old_name (str or Cell) – Cell or name of the cell to be renamed.

  • +
  • new_name (str) – New cell name.

  • +
+
+
+
+ +
+
+replace(*cells) self
+

Add cells to this library, replacing any cells with the same name.

+

References to any removed cells are also replaced with the new cell.

+

Examples

+
>>> polygon = gdstk.rectangle((-10, -10), (10, 10))
+>>> cell = gdstk.Cell("Alignment Mark")
+>>> cell.add(polygon)
+>>> lib = gdstk.read_gds("layout.gds")
+>>> lib.replace(cell)
+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+top_level() list
+

Return the top-level cells in the library.

+

Top-level cells are cells that do not appear as dependency of any other +cells in the library.

+
+ +
+
+unit
+

Library unit.

+
+ +
+
+write_gds(outfile, max_points=199, timestamp=None) None
+

Save this library to a GDSII file.

+
+
Parameters:
+
    +
  • outfile (str or pathlib.Path) – Name of the output file.

  • +
  • max_points – Maximal number of vertices per polygon. Polygons with +more vertices that this are automatically fractured.

  • +
  • timestamp (datetime object) – Timestamp to be stored in the GDSII +file. If None, the current time is used.

  • +
+
+
+
+

See also

+

Getting Started

+
+
+ +
+
+write_oas(outfile, compression_level=6, detect_rectangles=True, detect_trapezoids=True, circletolerance=0, standard_properties=False, validation=None) None
+

Save this library to an OASIS file.

+
+
Parameters:
+
    +
  • outfile (str or pathlib.Path) – Name of the output file.

  • +
  • compression_level – Level of compression for cells (between 0 and 9). +Setting to 0 will disable cell compression, 1 gives the best speed +and 9, the best compression.

  • +
  • detect_rectangles – Store rectangles in compressed format.

  • +
  • detect_trapezoids – Store trapezoids in compressed format.

  • +
  • circle_tolerance – Tolerance for detecting circles. If less or equal +to 0, no detection is performed. Circles are stored in compressed +format.

  • +
  • validation ("crc32", "checksum32", None) – type of validation to +include in the saved file.

  • +
  • standard_properties – Store standard OASIS properties in the file.

  • +
+
+
+
+

Notes

+

The standard OASIS options include the maximal string length and +integer size used in the file, maximal numbers of polygon and path +vertices, cell bounding boxes and cell offsets inside the file. +Some of these properties are computationally expensive to calculate. +Use only when required.

+
+
+

See also

+

Getting Started

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.RawCell.html b/library/gdstk.RawCell.html new file mode 100644 index 000000000..4c5524a1d --- /dev/null +++ b/library/gdstk.RawCell.html @@ -0,0 +1,213 @@ + + + + + + + gdstk.RawCell — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.RawCell

+
+
+class gdstk.RawCell(name)
+

A Cell structure that is stored in binary GDSII format.

+

Raw cells are not meant to be created in the same way cells are. They +come from gdstk.read_rawcells() and are used when the imported +elements will not be modified in any way. They are smaller in memory and +require almost no processing to be used, making them a preferred option +when using an external GDSII file as a parts library (such as in PDKs).

+
+

Notes

+

The units of the imported RawCell are not checked against the +current user units. It is up to the user to ensure they are equal.

+
+ +

Methods

+ + + + + + +

dependencies(recursive)

List of raw cells that are referenced by this raw cell.

+

Attributes

+ + + + + + + + + +

name

Raw cell name.

size

Raw cell size (in bytes).

+
+
+dependencies(recursive) list
+

List of raw cells that are referenced by this raw cell.

+
+
Parameters:
+

recursive – If True, includes all dependencies recursively.

+
+
+
+ +
+
+name
+

Raw cell name.

+
+

Notes

+

This attribute is read-only.

+
+
+ +
+
+size
+

Raw cell size (in bytes).

+
+

Notes

+

This attribute is read-only.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.Reference.html b/library/gdstk.Reference.html new file mode 100644 index 000000000..1f433529c --- /dev/null +++ b/library/gdstk.Reference.html @@ -0,0 +1,603 @@ + + + + + + + gdstk.Reference — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.Reference

+
+
+class gdstk.Reference(cell, origin=(0, 0), rotation=0, magnification=1, x_reflection=False, columns=1, rows=1, spacing=None)
+

Reference to another cell.

+

References are used to instance repetitive geometries across different +cells, optionally applying a transformation.

+
+
Parameters:
+
    +
  • cell (gdstk.Cell, gdstk.RawCell, str) – referenced cell.

  • +
  • origin – Insertion position of the referenced cell.

  • +
  • rotation – Cell rotation angle (in radians).

  • +
  • magnification – Geometry scaling for this reference.

  • +
  • x_reflection – If True, the geometry is reflected across the +horizontal axis before rotation.

  • +
  • columns – Number of repetitions along the first direction.

  • +
  • rows – Number of repetitions along the second direction.

  • +
  • spacing – Spacing between insertions points of repetitions.

  • +
+
+
+

Examples

+
>>> polygons = gdstk.text("F", 10, (0, 0))
+>>> f_cell = gdstk.Cell("F_CELL")
+>>> f_cell.add(*polygons)
+>>> ref = gdstk.Reference(f_cell, rotation=numpy.pi / 2)
+>>> array_ref = gdstk.Reference(f_cell, columns=3, rows=2,
+...                             spacing=(8, 10))
+
+
+../_images/init5.svg +
+

Notes

+

If cell is a str (cell name), operations on the referenced cell +are not performed, such as computing the bounding box.

+

When spacing is set, a repetition is defined according to the +rotation and x_reflection arguments.

+
+

Methods

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

apply_repetition()

Create new references based on this object's repetition attribute.

bounding_box()

Calculate the bounding box of this reference.

convex_hull()

Calculate the convex hull of this reference.

copy()

Create a copy this reference.

delete_gds_property(attr)

Delete a GDSII property of this element.

delete_property(name)

Delete the first property of this element matching a name.

get_gds_property(attr)

Return a GDSII property of this element.

get_labels([apply_repetitions, depth, ...])

Return a copy of all labels created by this reference.

get_paths([apply_repetitions, depth, layer, ...])

Return a copy of all paths created by this reference.

get_polygons([apply_repetitions, ...])

Return a copy of all polygons created by this reference.

get_property(name)

Return the values of the first property of this element matching a name.

set_gds_property(attr, value)

Set a GDSII property for this element.

set_property(name, value)

Set a property for this element.

+

Attributes

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

cell

Cell referenced by this object.

cell_name

Name of the cell referenced by this object.

magnification

Reference magnification.

origin

Reference origin.

properties

Properties of this element.

repetition

Repetition associated with this element.

rotation

Reference rotation angle (in radians).

x_reflection

Reference reflection across the x axis.

+
+
+apply_repetition() list
+

Create new references based on this object’s repetition attribute.

+

After the repetition is applied, the original attribute is set to +None.

+
+
Returns:
+

Newly created objects.

+
+
+
+ +
+
+bounding_box() tuple
+

Calculate the bounding box of this reference.

+
+
Returns:
+

The lower-left and upper-right corners of the bounding box of the +polygon: ((min_x, min_y), (max_x, max_y)).

+
+
+
+

Notes

+

This operation can be slow because the precise bounding box +calculation requires recursively querying the polygonal +representations of all shapes created by this reference.

+
+

Examples

+
>>> polygons = gdstk.text("F", 10, (0, 0))
+>>> f_cell = gdstk.Cell("F_CELL")
+>>> f_cell.add(*polygons)
+>>> ang = numpy.pi / 4
+>>> array_ref = gdstk.Reference(f_cell, rotation=ang)
+>>> array_ref.repetition = gdstk.Repetition(columns=3, rows=2,
+...     v1=8 * numpy.exp(1j * ang), v2=10j * numpy.exp(1j * ang))
+>>> array_ref = gdstk.Reference(f_cell, rotation=numpy.pi / 4)
+>>> array_ref.repetition = gdstk.Repetition(columns=3, rows=2,
+...                                         spacing=(8, 10))
+>>> bbox = array_ref.bounding_box()
+>>> print(bbox)
+((-12.816310409006173, 1.7677669529663689),
+ (11.313708498984761, 27.66555281392367))
+>>> polygon_bb = gdstk.rectangle(*bbox, datatype=1)
+
+
+../_images/bounding_box2.svg +
+ +
+
+cell
+

Cell referenced by this object.

+
+ +
+
+cell_name
+

Name of the cell referenced by this object.

+
+ +
+
+convex_hull() ndarray
+

Calculate the convex hull of this reference.

+

The convex hull is the smallest convex polygon that contains all +elements of this reference.

+
+
Returns:
+

Vertices of the convex hull.

+
+
+

Examples

+
>>> polygons = gdstk.text("F", 10, (0, 0))
+>>> f_cell = gdstk.Cell("F_CELL")
+>>> f_cell.add(*polygons)
+>>> ang = numpy.pi / 4
+>>> array_ref = gdstk.Reference(f_cell, rotation=ang)
+>>> array_ref.repetition = gdstk.Repetition(columns=3, rows=2,
+...     v1=8 * numpy.exp(1j * ang), v2=10j * numpy.exp(1j * ang))
+>>> path = gdstk.FlexPath([(-5, 0), (0, -5), (5, 0)], 1,
+...                       simple_path=True)
+>>> main_cell = gdstk.Cell("MAIN")
+>>> main_cell.add(array_ref, path)
+>>> hull = main_cell.convex_hull()
+>>> polygon_hull = gdstk.Polygon(hull, datatype=1)
+
+
+../_images/convex_hull1.svg +
+

Notes

+

This operation can be slow because all paths and references are +included in the computation.

+
+
+ +
+
+copy() gdstk.Reference
+

Create a copy this reference.

+
+
Returns:
+

Copy of this reference.

+
+
+
+ +
+
+delete_gds_property(attr) self
+

Delete a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
+
+ +
+
+delete_property(name) self
+

Delete the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
+
+ +
+
+get_gds_property(attr) str
+

Return a GDSII property of this element.

+
+
Parameters:
+

attr (number) – Property number.

+
+
Returns:
+

Property value. If the property number does not exist, +None is returned.

+
+
Return type:
+

str or None

+
+
+
+ +
+
+get_labels(apply_repetitions=True, depth=None, layer=None, texttype=None) list
+

Return a copy of all labels created by this reference.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created labels.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only labels in the defined layer and text type are +returned.

  • +
  • texttype – If set, only labels in the defined layer and text type +are returned.

  • +
+
+
+
+

Notes

+

Arguments layer and texttype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_paths(apply_repetitions=True, depth=None, layer=None, datatype=None) list
+

Return a copy of all paths created by this reference.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created paths.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only paths in the defined layer and data type are +returned.

  • +
  • datatype – If set, only paths in the defined layer and data type are +returned.

  • +
+
+
+
+

Notes

+

Arguments layer and datatype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_polygons(apply_repetitions=True, include_paths=True, depth=None, layer=None, datatype=None) list
+

Return a copy of all polygons created by this reference.

+
+
Parameters:
+
    +
  • apply_repetitions – Define whether repetitions should be applied in +the created polygons.

  • +
  • include_paths – If True, polygonal representation of paths are +also included in the result.

  • +
  • depth – If non negative, indicates the number of reference levels +processed recursively. A value of 0 will result in no references +being visited. A value of None (the default) or a negative +integer will include all reference levels below the cell.

  • +
  • layer – If set, only polygons in the defined layer and data type are +returned.

  • +
  • datatype – If set, only polygons in the defined layer and data type +are returned.

  • +
+
+
+
+

Notes

+

Arguments layer and datatype must both be set to integers +for the filtering to be executed. If either one is None they +are both ignored.

+
+
+ +
+
+get_property(name) list
+

Return the values of the first property of this element matching a name.

+
+
Parameters:
+

name (str) – Property name.

+
+
Returns:
+

List of property values. If no property is found, +None is returned.

+
+
Return type:
+

list or None

+
+
+
+ +
+
+magnification
+

Reference magnification.

+
+ +
+
+origin
+

Reference origin.

+
+ +
+
+properties
+

Properties of this element.

+

Properties are represented as a list of lists, each containing the +property name followed by its values.

+
+ +
+
+repetition
+

Repetition associated with this element.

+
+ +
+
+rotation
+

Reference rotation angle (in radians).

+
+ +
+
+set_gds_property(attr, value) self
+

Set a GDSII property for this element.

+

GDSII properties are stored under the special name “S_GDS_PROPERTY”, as +defined by the OASIS specification.

+
+
Parameters:
+
    +
  • attr (number) – Property number.

  • +
  • value (str) – Property value.

  • +
+
+
+
+ +
+
+set_property(name, value) self
+

Set a property for this element.

+

The property name does not have to be unique. Multiple properties can +have the same name.

+
+
Parameters:
+
    +
  • name (str) – Property name.

  • +
  • value (str, bytes, number, or sequence of those) – Values associated +with the property.

  • +
+
+
+
+

Notes

+

These properties can be used to associate custom metadata with an +element, but general properties are not supported by GDSII files, +only OASIS. Use the specific methods to access GDSII properties.

+
+
+ +
+
+x_reflection
+

Reference reflection across the x axis.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.gds_info.html b/library/gdstk.gds_info.html new file mode 100644 index 000000000..e57bef257 --- /dev/null +++ b/library/gdstk.gds_info.html @@ -0,0 +1,165 @@ + + + + + + + gdstk.gds_info — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.gds_info

+
+
+gdstk.gds_info(infile) dict
+

Gather information from a GDSII file without loading the geometry.

+
+
Parameters:
+

infile (str or pathlib.Path) – Name of the input file.

+
+
Returns:
+

Dictionary with library info.

+

The following keys are available in the return dictionary:

+

cell_names: list with all cell names

+

layers_and_datatypes: set of 2-tuples with layers and data +types

+

layers_and_texttypes: set of 2-tuples with layers and text +types

+

num_polygons: number of polygons in the library

+

num_paths: number of paths in the library

+

num_references: number of references in the library

+

num_labels: number of labels in the library

+

unit: library unit

+

precision library precision

+

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.gds_units.html b/library/gdstk.gds_units.html new file mode 100644 index 000000000..8c0417ba6 --- /dev/null +++ b/library/gdstk.gds_units.html @@ -0,0 +1,152 @@ + + + + + + + gdstk.gds_units — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.gds_units

+
+
+gdstk.gds_units(infile) tuple
+

Read the unit and precision of a GDSII file.

+
+
Parameters:
+

infile (str or pathlib.Path) – Name of the input file.

+
+
Returns:
+

Tuple with the unit and precision of the library in the file.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.oas_precision.html b/library/gdstk.oas_precision.html new file mode 100644 index 000000000..c6e90778c --- /dev/null +++ b/library/gdstk.oas_precision.html @@ -0,0 +1,152 @@ + + + + + + + gdstk.oas_precision — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.oas_precision

+
+
+gdstk.oas_precision(infile) float
+

Read the precision of an OASIS file.

+
+
Parameters:
+

infile (str or pathlib.Path) – Name of the input file.

+
+
Returns:
+

Precision of the library in the file.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.oas_validate.html b/library/gdstk.oas_validate.html new file mode 100644 index 000000000..895f7ad71 --- /dev/null +++ b/library/gdstk.oas_validate.html @@ -0,0 +1,153 @@ + + + + + + + gdstk.oas_validate — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.oas_validate

+
+
+gdstk.oas_validate(infile) tuple
+

Check the validation signature of an OASIS file, if any.

+
+
Parameters:
+

infile (str or pathlib.Path) – Name of the input file.

+
+
Returns:
+

Validation result (True/False) and the calculated signature. If the +file does not have a signature, returns (None, 0)

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.read_gds.html b/library/gdstk.read_gds.html new file mode 100644 index 000000000..983034f7d --- /dev/null +++ b/library/gdstk.read_gds.html @@ -0,0 +1,166 @@ + + + + + + + gdstk.read_gds — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.read_gds

+
+
+gdstk.read_gds(infile, unit=0, tolerance=0, filter=None) gdstk.Library
+

Import a library from a GDSII stream file.

+
+
Parameters:
+
    +
  • infile (str or pathlib.Path) – Name of the input file.

  • +
  • unit (number) – If greater than zero, convert the imported geometry +to the this unit.

  • +
  • tolerance (number) – Default tolerance for loaded paths. If zero or +negative, the library rounding size is used (precision / unit).

  • +
  • filter (iterable of tuples) – If not None, only shapes with +layer and data type in the iterable are read.

  • +
+
+
Returns:
+

The imported library.

+
+
+

Examples

+
>>> library = gdstk.read_gds("layout.gds")
+>>> top_cells = library.top_level()
+>>> filtered_lib = gdstk.read_gds("layout.gds", filter={(0, 1)})
+
+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.read_oas.html b/library/gdstk.read_oas.html new file mode 100644 index 000000000..fb9ab385a --- /dev/null +++ b/library/gdstk.read_oas.html @@ -0,0 +1,164 @@ + + + + + + + gdstk.read_oas — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.read_oas

+
+
+gdstk.read_oas(infile, unit=0, tolerance=0) gdstk.Library
+

Import a library from an OASIS stream file.

+
+
Parameters:
+
    +
  • infile (str or pathlib.Path) – Name of the input file.

  • +
  • unit (number) – If greater than zero, convert the imported geometry +to the this unit.

  • +
  • tolerance (number) – Default tolerance for loaded paths and round +shapes. If zero or negative, the library rounding size is used +(precision / unit).

  • +
+
+
Returns:
+

The imported library.

+
+
+

Examples

+
>>> library = gdstk.read_oas("layout.oas")
+>>> top_cells = library.top_level()
+
+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/library/gdstk.read_rawcells.html b/library/gdstk.read_rawcells.html new file mode 100644 index 000000000..40cad42f3 --- /dev/null +++ b/library/gdstk.read_rawcells.html @@ -0,0 +1,172 @@ + + + + + + + gdstk.read_rawcells — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

gdstk.read_rawcells

+
+
+gdstk.read_rawcells(infile) dict
+

Load cells form a GDSII file without decoding them.

+
+
Parameters:
+

infile (str or pathlib.Path) – Name of the input file.

+
+
Returns:
+

Dictionary of gdstk.RawCell indexed by name.

+
+
+

Examples

+
>>> cell1 = gdstk.Cell("CELL_1")
+>>> cell1.add(gdstk.rectangle((0, 0), (2, 1)))
+>>> cell2 = gdstk.Cell("CELL_2")
+>>> cell2.add(gdstk.Reference(cell1, (-1, 0)))
+>>> library = gdstk.Library()
+>>> library.add(cell1, cell2)
+>>> library.write_gds("test.gds")
+>>> raw_cells = gdstk.read_rawcells("test.gds")
+>>> print(raw_cells.keys())
+dict_keys(['CELL_2', 'CELL_1'])
+>>> print(len(raw_cells["CELL_1"].dependencies(True)))
+0
+>>> print(len(raw_cells["CELL_2"].dependencies(True)))
+1
+>>> deps = raw_cells["CELL_2"].dependencies(True)
+>>> print(deps[0] is raw_cells["CELL_1"])
+True
+
+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 000000000..943768d1b Binary files /dev/null and b/objects.inv differ diff --git a/reference_cpp.html b/reference_cpp.html new file mode 100644 index 000000000..8d47831b2 --- /dev/null +++ b/reference_cpp.html @@ -0,0 +1,238 @@ + + + + + + + C++ Reference — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +
+

C++ Reference

+

This reference covers only basic aspects of the C++ interface of Gdstk. The +user of the library is expected to go through the examples in this +documentation and to inspect the source code for further details.

+
+

Code Style

+

The library is fully contained in the gdstk namespace. Structs and enums +use PascalCase, functions and variables (including constants), +snake_case, and definitions are all UPPER_CASE. Exceptions are the +members of enums GdsiiRecord and OasisRecord, which use UPPER_CASE +to better match their specification documents.

+

The library uses only a minimal set of C++ features, namely, limited use of +templates and overloading, no constructors or destructors, no virtual functions +or inheritance, limited private members, and no use of the STL.

+
+

Important

+

The user is responsible for the consistent initialization of variables, +specially struct members. In general, zeroing the whole struct is enough, +with a few exceptions: Library.name, Cell.name, Label.text, and +Reference.cell, Reference.rawcell, or Reference.name, depending +on the reference type. Curve, FlexPath, and RobustPath require +setting up a few variables to be in a consistent state.

+

Other struct members can be zero, but probably shouldn’t: +Reference.magnification, Label.magnification, Curve.tolerance, +FlexPath.spine.tolerance, RobustPath.tolerance, +RobustPath.max_evals, RobustPath.width_scale, +RobustPath.offset_scale, and RobustPath.trafo.

+

Safe initialization of those structs and members are taken care of in their +respective init methods. The user can do it manually, of course, but +the following idiom is safe to use:

+
StructName var = {};  // zero-initialize the struct
+var.init(…);          // initialize important members
+
+
+
+
+
+

Memory Management

+

Dynamic memory management in Gdstk is realized through 4 functions:

+
    +
  • void* allocate(uint64_t size): equivalent to malloc(size)

  • +
  • void* reallocate(void* ptr, uint64_t size): equivalent to realloc(ptr, +1, size)

  • +
  • void* allocate_clear(uint64_t size): equivalent to calloc(size)

  • +
  • void free_allocation(void* ptr): equivalent to free(ptr)

  • +
+

These can be freely replaced in allocator.h and allocator.cpp +with user-defined functions. Their default implementations are just calls to +their libc equivalents.

+

The user is required to use these same functions for any structures that might +be reallocated of freed by Gdstk. In the examples in Getting Started +and How-Tos, static allocations are used when we are certain the library +will not modify those, for example, when creating a polygon that will not be +transformed in any way.

+
+
+

Thread Safety

+

Gdstk is not thread-safe. That said, the library does not use global +variables, so it is safe to use threads as long as they do not modify the same +data structures.

+
+
+

Header files

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/reference_python.html b/reference_python.html new file mode 100644 index 000000000..81d558e08 --- /dev/null +++ b/reference_python.html @@ -0,0 +1,276 @@ + + + + + + + Python API Reference — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +
+

Python API Reference

+
+

Geometry Construction

+

Classes and functions for construction and manipulation of geometric objects.

+

Classes

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

gdstk.Polygon(points[, layer, datatype])

Polygonal geometric object.

gdstk.Curve(xy[, tolerance])

Curve object for construction of complex polygons.

gdstk.FlexPath(points, width[, offset, ...])

Flexible path creation.

gdstk.RobustPath(initial_point, width[, ...])

Robust path creation.

gdstk.Repetition([columns, rows, spacing, ...])

Repetition object that creates multiple identical elements.

+

Functions

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

gdstk.rectangle(corner1, corner2[, layer, ...])

Create a rectangle.

gdstk.cross(center, full_size, arm_width[, ...])

Create a cross shape.

gdstk.regular_polygon(center, side_length, sides)

Create a regular polygon.

gdstk.ellipse(center, radius[, ...])

Create an ellipse, circle, slice or ring.

gdstk.racetrack(center, straight_length, radius)

Create a racetrack shape.

gdstk.text(text, size, position[, vertical, ...])

Create polygonal text.

gdstk.contour(data[, level, length_scale, ...])

Extract polygonal contours from 2-d array data at given level.

gdstk.offset(polygons, distance[, join, ...])

Dilate or erode polygons.

gdstk.boolean(operand1, operand2, operation)

Execute boolean (clipping) operations between polygons.

gdstk.slice(polygons, position, axis[, ...])

Slice polygons along x and y axes.

gdstk.inside(points, polygons)

Check whether each point is inside the set of polygons.

gdstk.all_inside(points, polygons)

Check whether all points are inside the set of polygons.

gdstk.any_inside(points, polygons)

Check whether any of the points are inside the set of polygons.

+
+
+

Library Organization

+

Classes and functions used to create and organize the library in a GDSII/OASIS +file.

+

Classes

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

gdstk.Label(text, origin[, anchor, ...])

Text objects with out geometrical information.

gdstk.Reference(cell[, origin, rotation, ...])

Reference to another cell.

gdstk.Cell(name)

Cell structure.

gdstk.RawCell(name)

A Cell structure that is stored in binary GDSII format.

gdstk.Library([name, unit, precision])

GDSII/OASIS library.

gdstk.GdsWriter(outfile[, name, unit, ...])

Multi-step GDSII stream file writer.

+

Functions

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

gdstk.read_gds(infile[, unit, tolerance, filter])

Import a library from a GDSII stream file.

gdstk.read_oas(infile[, unit, tolerance])

Import a library from an OASIS stream file.

gdstk.read_rawcells(infile)

Load cells form a GDSII file without decoding them.

gdstk.gds_units(infile)

Read the unit and precision of a GDSII file.

gdstk.gds_info(infile)

Gather information from a GDSII file without loading the geometry.

gdstk.oas_precision(infile)

Read the precision of an OASIS file.

gdstk.oas_validate(infile)

Check the validation signature of an OASIS file, if any.

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

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 000000000..519568445 --- /dev/null +++ b/search.html @@ -0,0 +1,127 @@ + + + + + + Search — gdstk 0.9.53 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2020, Lucas H. Gabrielli.

+
+ + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 000000000..b0e739608 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"A Note About Units": [[18, "a-note-about-units"]], "Boolean Operations": [[18, "boolean-operations"]], "C++ Reference": [[58, null]], "Circles": [[18, "circles"]], "Code Style": [[58, "code-style"]], "Connection Pads": [[43, "connection-pads"]], "Creating a Library": [[43, "creating-a-library"]], "Curves": [[18, "curves"]], "Fillet Operation": [[18, "fillet-operation"]], "First Layout": [[18, "first-layout"]], "Flexible Paths": [[18, "flexible-paths"]], "GDSII/OASIS Library": [[18, "gdsii-oasis-library"]], "Gdstk Documentation": [[44, null]], "Geometry Construction": [[59, "geometry-construction"]], "Geometry Filtering": [[43, "geometry-filtering"]], "Geometry Operations": [[18, "geometry-operations"]], "Getting Started": [[18, null]], "Header files": [[58, "header-files"]], "Holes": [[18, "holes"]], "How-Tos": [[43, null]], "Layer and Datatype": [[18, "layer-and-datatype"]], "Library Organization": [[59, "library-organization"]], "License": [[44, "license"]], "Loading a Layout File": [[18, "loading-a-layout-file"]], "Memory Management": [[58, "memory-management"]], "Merging Libraries": [[43, "merging-libraries"]], "Notes": [[0, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [1, null], [2, null], [2, null], [2, null], [2, null], [2, null], [2, null], [3, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [4, null], [7, null], [8, null], [12, null], [16, null], [17, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [45, null], [47, null], [47, null], [48, null], [48, null], [48, null], [48, null], [48, null], [49, null], [49, null], [49, null], [50, null], [50, null], [50, null], [50, null], [50, null], [50, null], [50, null]], "Offset Operation": [[18, "offset-operation"]], "Parametric Cell": [[43, "parametric-cell"]], "Parts Library": [[43, "parts-library"]], "Paths": [[18, "paths"]], "Points Along a Path": [[43, "points-along-a-path"]], "Polygons": [[18, "polygons"]], "Python API Reference": [[59, null]], "Raw Cells": [[18, "raw-cells"]], "References": [[18, "references"]], "Repetitions": [[43, "repetitions"]], "Robust Paths": [[18, "robust-paths"]], "Saving a Layout File": [[18, "saving-a-layout-file"]], "Slice Operation": [[18, "slice-operation"]], "Support": [[44, "support"]], "System Fonts": [[43, "system-fonts"]], "Table of Contents": [[44, null]], "Text": [[18, "text"]], "Thread Safety": [[58, "thread-safety"]], "Transformations": [[18, "transformations"], [43, "transformations"]], "Using a Library": [[43, "using-a-library"]], "allocator.h": [[19, null]], "array.h": [[20, null]], "cell.h": [[21, null]], "clipper_tools.h": [[22, null]], "curve.h": [[23, null]], "flexpath.h": [[24, null]], "font.h": [[25, null]], "gdsii.h": [[26, null]], "gdstk.Cell": [[45, null]], "gdstk.Curve": [[0, null]], "gdstk.FlexPath": [[1, null]], "gdstk.GdsWriter": [[46, null]], "gdstk.Label": [[47, null]], "gdstk.Library": [[48, null]], "gdstk.Polygon": [[2, null]], "gdstk.RawCell": [[49, null]], "gdstk.Reference": [[50, null]], "gdstk.Repetition": [[3, null]], "gdstk.RobustPath": [[4, null]], "gdstk.all_inside": [[5, null]], "gdstk.any_inside": [[6, null]], "gdstk.boolean": [[7, null]], "gdstk.contour": [[8, null]], "gdstk.cross": [[9, null]], "gdstk.ellipse": [[10, null]], "gdstk.gds_info": [[51, null]], "gdstk.gds_units": [[52, null]], "gdstk.h": [[27, null]], "gdstk.inside": [[11, null]], "gdstk.oas_precision": [[53, null]], "gdstk.oas_validate": [[54, null]], "gdstk.offset": [[12, null]], "gdstk.racetrack": [[13, null]], "gdstk.read_gds": [[55, null]], "gdstk.read_oas": [[56, null]], "gdstk.read_rawcells": [[57, null]], "gdstk.rectangle": [[14, null]], "gdstk.regular_polygon": [[15, null]], "gdstk.slice": [[16, null]], "gdstk.text": [[17, null]], "gdswriter.h": [[28, null]], "label.h": [[29, null]], "library.h": [[30, null]], "map.h": [[31, null]], "oasis.h": [[32, null]], "pathcommon.h": [[33, null]], "polygon.h": [[34, null]], "property.h": [[35, null]], "rawcell.h": [[36, null]], "reference.h": [[37, null]], "repetition.h": [[38, null]], "robustpath.h": [[39, null]], "style.h": [[40, null]], "utils.h": [[41, null]], "vec.h": [[42, null]]}, "docnames": ["geometry/gdstk.Curve", "geometry/gdstk.FlexPath", "geometry/gdstk.Polygon", "geometry/gdstk.Repetition", "geometry/gdstk.RobustPath", "geometry/gdstk.all_inside", "geometry/gdstk.any_inside", "geometry/gdstk.boolean", "geometry/gdstk.contour", "geometry/gdstk.cross", "geometry/gdstk.ellipse", "geometry/gdstk.inside", "geometry/gdstk.offset", "geometry/gdstk.racetrack", "geometry/gdstk.rectangle", "geometry/gdstk.regular_polygon", "geometry/gdstk.slice", "geometry/gdstk.text", "gettingstarted", "headers/allocator", "headers/array", "headers/cell", "headers/clipper_tools", "headers/curve", "headers/flexpath", "headers/font", "headers/gdsii", "headers/gdstk", "headers/gdswriter", "headers/label", "headers/library", "headers/map", "headers/oasis", "headers/pathcommon", "headers/polygon", "headers/property", "headers/rawcell", "headers/reference", "headers/repetition", "headers/robustpath", "headers/style", "headers/utils", "headers/vec", "how-tos", "index", "library/gdstk.Cell", "library/gdstk.GdsWriter", "library/gdstk.Label", "library/gdstk.Library", "library/gdstk.RawCell", "library/gdstk.Reference", "library/gdstk.gds_info", "library/gdstk.gds_units", "library/gdstk.oas_precision", "library/gdstk.oas_validate", "library/gdstk.read_gds", "library/gdstk.read_oas", "library/gdstk.read_rawcells", "reference_cpp", "reference_python"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["geometry/gdstk.Curve.rst", "geometry/gdstk.FlexPath.rst", "geometry/gdstk.Polygon.rst", "geometry/gdstk.Repetition.rst", "geometry/gdstk.RobustPath.rst", "geometry/gdstk.all_inside.rst", "geometry/gdstk.any_inside.rst", "geometry/gdstk.boolean.rst", "geometry/gdstk.contour.rst", "geometry/gdstk.cross.rst", "geometry/gdstk.ellipse.rst", "geometry/gdstk.inside.rst", "geometry/gdstk.offset.rst", "geometry/gdstk.racetrack.rst", "geometry/gdstk.rectangle.rst", "geometry/gdstk.regular_polygon.rst", "geometry/gdstk.slice.rst", "geometry/gdstk.text.rst", "gettingstarted.rst", "headers/allocator.rst", "headers/array.rst", "headers/cell.rst", "headers/clipper_tools.rst", "headers/curve.rst", "headers/flexpath.rst", "headers/font.rst", "headers/gdsii.rst", "headers/gdstk.rst", "headers/gdswriter.rst", "headers/label.rst", "headers/library.rst", "headers/map.rst", "headers/oasis.rst", "headers/pathcommon.rst", "headers/polygon.rst", "headers/property.rst", "headers/rawcell.rst", "headers/reference.rst", "headers/repetition.rst", "headers/robustpath.rst", "headers/style.rst", "headers/utils.rst", "headers/vec.rst", "how-tos.rst", "index.rst", "library/gdstk.Cell.rst", "library/gdstk.GdsWriter.rst", "library/gdstk.Label.rst", "library/gdstk.Library.rst", "library/gdstk.RawCell.rst", "library/gdstk.Reference.rst", "library/gdstk.gds_info.rst", "library/gdstk.gds_units.rst", "library/gdstk.oas_precision.rst", "library/gdstk.oas_validate.rst", "library/gdstk.read_gds.rst", "library/gdstk.read_oas.rst", "library/gdstk.read_rawcells.rst", "reference_cpp.rst", "reference_python.rst"], "indexentries": {"add() (gdstk.cell method)": [[45, "gdstk.Cell.add", false]], "add() (gdstk.library method)": [[48, "gdstk.Library.add", false]], "all_inside() (in module gdstk)": [[5, "gdstk.all_inside", false]], "anchor (gdstk.label attribute)": [[47, "gdstk.Label.anchor", false]], "any_inside() (in module gdstk)": [[6, "gdstk.any_inside", false]], "apply_repetition() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.apply_repetition", false]], "apply_repetition() (gdstk.label method)": [[47, "gdstk.Label.apply_repetition", false]], "apply_repetition() (gdstk.polygon method)": [[2, "gdstk.Polygon.apply_repetition", false]], "apply_repetition() (gdstk.reference method)": [[50, "gdstk.Reference.apply_repetition", false]], "apply_repetition() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.apply_repetition", false]], "arc() (gdstk.curve method)": [[0, "gdstk.Curve.arc", false]], "arc() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.arc", false]], "arc() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.arc", false]], "area() (gdstk.cell method)": [[45, "gdstk.Cell.area", false]], "area() (gdstk.polygon method)": [[2, "gdstk.Polygon.area", false]], "bend_function (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.bend_function", false]], "bend_radius (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.bend_radius", false]], "bezier() (gdstk.curve method)": [[0, "gdstk.Curve.bezier", false]], "bezier() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.bezier", false]], "bezier() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.bezier", false]], "boolean() (in module gdstk)": [[7, "gdstk.boolean", false]], "bounding_box() (gdstk.cell method)": [[45, "gdstk.Cell.bounding_box", false]], "bounding_box() (gdstk.polygon method)": [[2, "gdstk.Polygon.bounding_box", false]], "bounding_box() (gdstk.reference method)": [[50, "gdstk.Reference.bounding_box", false]], "cell (class in gdstk)": [[45, "gdstk.Cell", false]], "cell (gdstk.reference attribute)": [[50, "gdstk.Reference.cell", false]], "cell_name (gdstk.reference attribute)": [[50, "gdstk.Reference.cell_name", false]], "cells (gdstk.library attribute)": [[48, "gdstk.Library.cells", false]], "close() (gdstk.gdswriter method)": [[46, "gdstk.GdsWriter.close", false]], "columns (gdstk.repetition attribute)": [[3, "gdstk.Repetition.columns", false]], "commands() (gdstk.curve method)": [[0, "gdstk.Curve.commands", false]], "commands() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.commands", false]], "commands() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.commands", false]], "contain() (gdstk.polygon method)": [[2, "gdstk.Polygon.contain", false]], "contain_all() (gdstk.polygon method)": [[2, "gdstk.Polygon.contain_all", false]], "contain_any() (gdstk.polygon method)": [[2, "gdstk.Polygon.contain_any", false]], "contour() (in module gdstk)": [[8, "gdstk.contour", false]], "convex_hull() (gdstk.cell method)": [[45, "gdstk.Cell.convex_hull", false]], "convex_hull() (gdstk.reference method)": [[50, "gdstk.Reference.convex_hull", false]], "copy() (gdstk.cell method)": [[45, "gdstk.Cell.copy", false]], "copy() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.copy", false]], "copy() (gdstk.label method)": [[47, "gdstk.Label.copy", false]], "copy() (gdstk.polygon method)": [[2, "gdstk.Polygon.copy", false]], "copy() (gdstk.reference method)": [[50, "gdstk.Reference.copy", false]], "copy() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.copy", false]], "cross() (in module gdstk)": [[9, "gdstk.cross", false]], "cubic() (gdstk.curve method)": [[0, "gdstk.Curve.cubic", false]], "cubic() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.cubic", false]], "cubic() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.cubic", false]], "cubic_smooth() (gdstk.curve method)": [[0, "gdstk.Curve.cubic_smooth", false]], "cubic_smooth() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.cubic_smooth", false]], "cubic_smooth() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.cubic_smooth", false]], "curve (class in gdstk)": [[0, "gdstk.Curve", false]], "datatype (gdstk.polygon attribute)": [[2, "gdstk.Polygon.datatype", false]], "datatypes (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.datatypes", false]], "datatypes (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.datatypes", false]], "delete_gds_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.delete_gds_property", false]], "delete_gds_property() (gdstk.label method)": [[47, "gdstk.Label.delete_gds_property", false]], "delete_gds_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.delete_gds_property", false]], "delete_gds_property() (gdstk.reference method)": [[50, "gdstk.Reference.delete_gds_property", false]], "delete_gds_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.delete_gds_property", false]], "delete_property() (gdstk.cell method)": [[45, "gdstk.Cell.delete_property", false]], "delete_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.delete_property", false]], "delete_property() (gdstk.label method)": [[47, "gdstk.Label.delete_property", false]], "delete_property() (gdstk.library method)": [[48, "gdstk.Library.delete_property", false]], "delete_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.delete_property", false]], "delete_property() (gdstk.reference method)": [[50, "gdstk.Reference.delete_property", false]], "delete_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.delete_property", false]], "dependencies() (gdstk.cell method)": [[45, "gdstk.Cell.dependencies", false]], "dependencies() (gdstk.rawcell method)": [[49, "gdstk.RawCell.dependencies", false]], "ellipse() (in module gdstk)": [[10, "gdstk.ellipse", false]], "ends (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.ends", false]], "ends (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.ends", false]], "fillet() (gdstk.polygon method)": [[2, "gdstk.Polygon.fillet", false]], "filter() (gdstk.cell method)": [[45, "gdstk.Cell.filter", false]], "flatten() (gdstk.cell method)": [[45, "gdstk.Cell.flatten", false]], "flexpath (class in gdstk)": [[1, "gdstk.FlexPath", false]], "fracture() (gdstk.polygon method)": [[2, "gdstk.Polygon.fracture", false]], "gds_info() (in module gdstk)": [[51, "gdstk.gds_info", false]], "gds_units() (in module gdstk)": [[52, "gdstk.gds_units", false]], "gdswriter (class in gdstk)": [[46, "gdstk.GdsWriter", false]], "get_gds_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.get_gds_property", false]], "get_gds_property() (gdstk.label method)": [[47, "gdstk.Label.get_gds_property", false]], "get_gds_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.get_gds_property", false]], "get_gds_property() (gdstk.reference method)": [[50, "gdstk.Reference.get_gds_property", false]], "get_gds_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.get_gds_property", false]], "get_labels() (gdstk.cell method)": [[45, "gdstk.Cell.get_labels", false]], "get_labels() (gdstk.reference method)": [[50, "gdstk.Reference.get_labels", false]], "get_offsets() (gdstk.repetition method)": [[3, "gdstk.Repetition.get_offsets", false]], "get_paths() (gdstk.cell method)": [[45, "gdstk.Cell.get_paths", false]], "get_paths() (gdstk.reference method)": [[50, "gdstk.Reference.get_paths", false]], "get_polygons() (gdstk.cell method)": [[45, "gdstk.Cell.get_polygons", false]], "get_polygons() (gdstk.reference method)": [[50, "gdstk.Reference.get_polygons", false]], "get_property() (gdstk.cell method)": [[45, "gdstk.Cell.get_property", false]], "get_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.get_property", false]], "get_property() (gdstk.label method)": [[47, "gdstk.Label.get_property", false]], "get_property() (gdstk.library method)": [[48, "gdstk.Library.get_property", false]], "get_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.get_property", false]], "get_property() (gdstk.reference method)": [[50, "gdstk.Reference.get_property", false]], "get_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.get_property", false]], "gradient() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.gradient", false]], "horizontal() (gdstk.curve method)": [[0, "gdstk.Curve.horizontal", false]], "horizontal() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.horizontal", false]], "horizontal() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.horizontal", false]], "inside() (in module gdstk)": [[11, "gdstk.inside", false]], "interpolation() (gdstk.curve method)": [[0, "gdstk.Curve.interpolation", false]], "interpolation() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.interpolation", false]], "interpolation() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.interpolation", false]], "joins (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.joins", false]], "label (class in gdstk)": [[47, "gdstk.Label", false]], "labels (gdstk.cell attribute)": [[45, "gdstk.Cell.labels", false]], "layer (gdstk.label attribute)": [[47, "gdstk.Label.layer", false]], "layer (gdstk.polygon attribute)": [[2, "gdstk.Polygon.layer", false]], "layers (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.layers", false]], "layers (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.layers", false]], "layers_and_datatypes() (gdstk.library method)": [[48, "gdstk.Library.layers_and_datatypes", false]], "layers_and_texttypes() (gdstk.library method)": [[48, "gdstk.Library.layers_and_texttypes", false]], "library (class in gdstk)": [[48, "gdstk.Library", false]], "magnification (gdstk.label attribute)": [[47, "gdstk.Label.magnification", false]], "magnification (gdstk.reference attribute)": [[50, "gdstk.Reference.magnification", false]], "max_evals (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.max_evals", false]], "mirror() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.mirror", false]], "mirror() (gdstk.polygon method)": [[2, "gdstk.Polygon.mirror", false]], "mirror() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.mirror", false]], "name (gdstk.cell attribute)": [[45, "gdstk.Cell.name", false]], "name (gdstk.library attribute)": [[48, "gdstk.Library.name", false]], "name (gdstk.rawcell attribute)": [[49, "gdstk.RawCell.name", false]], "new_cell() (gdstk.library method)": [[48, "gdstk.Library.new_cell", false]], "num_paths (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.num_paths", false]], "num_paths (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.num_paths", false]], "oas_precision() (in module gdstk)": [[53, "gdstk.oas_precision", false]], "oas_validate() (in module gdstk)": [[54, "gdstk.oas_validate", false]], "offset() (in module gdstk)": [[12, "gdstk.offset", false]], "offsets (gdstk.repetition attribute)": [[3, "gdstk.Repetition.offsets", false]], "offsets() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.offsets", false]], "offsets() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.offsets", false]], "origin (gdstk.label attribute)": [[47, "gdstk.Label.origin", false]], "origin (gdstk.reference attribute)": [[50, "gdstk.Reference.origin", false]], "parametric() (gdstk.curve method)": [[0, "gdstk.Curve.parametric", false]], "parametric() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.parametric", false]], "parametric() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.parametric", false]], "path_spines() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.path_spines", false]], "path_spines() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.path_spines", false]], "paths (gdstk.cell attribute)": [[45, "gdstk.Cell.paths", false]], "perimeter() (gdstk.polygon method)": [[2, "gdstk.Polygon.perimeter", false]], "points (gdstk.polygon attribute)": [[2, "gdstk.Polygon.points", false]], "points() (gdstk.curve method)": [[0, "gdstk.Curve.points", false]], "polygon (class in gdstk)": [[2, "gdstk.Polygon", false]], "polygons (gdstk.cell attribute)": [[45, "gdstk.Cell.polygons", false]], "position() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.position", false]], "precision (gdstk.library attribute)": [[48, "gdstk.Library.precision", false]], "properties (gdstk.cell attribute)": [[45, "gdstk.Cell.properties", false]], "properties (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.properties", false]], "properties (gdstk.label attribute)": [[47, "gdstk.Label.properties", false]], "properties (gdstk.library attribute)": [[48, "gdstk.Library.properties", false]], "properties (gdstk.polygon attribute)": [[2, "gdstk.Polygon.properties", false]], "properties (gdstk.reference attribute)": [[50, "gdstk.Reference.properties", false]], "properties (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.properties", false]], "quadratic() (gdstk.curve method)": [[0, "gdstk.Curve.quadratic", false]], "quadratic() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.quadratic", false]], "quadratic() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.quadratic", false]], "quadratic_smooth() (gdstk.curve method)": [[0, "gdstk.Curve.quadratic_smooth", false]], "quadratic_smooth() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.quadratic_smooth", false]], "quadratic_smooth() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.quadratic_smooth", false]], "racetrack() (in module gdstk)": [[13, "gdstk.racetrack", false]], "raith_data (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.raith_data", false]], "rawcell (class in gdstk)": [[49, "gdstk.RawCell", false]], "read_gds() (in module gdstk)": [[55, "gdstk.read_gds", false]], "read_oas() (in module gdstk)": [[56, "gdstk.read_oas", false]], "read_rawcells() (in module gdstk)": [[57, "gdstk.read_rawcells", false]], "rectangle() (in module gdstk)": [[14, "gdstk.rectangle", false]], "reference (class in gdstk)": [[50, "gdstk.Reference", false]], "references (gdstk.cell attribute)": [[45, "gdstk.Cell.references", false]], "regular_polygon() (in module gdstk)": [[15, "gdstk.regular_polygon", false]], "remap() (gdstk.cell method)": [[45, "gdstk.Cell.remap", false]], "remap() (gdstk.library method)": [[48, "gdstk.Library.remap", false]], "remove() (gdstk.cell method)": [[45, "gdstk.Cell.remove", false]], "remove() (gdstk.library method)": [[48, "gdstk.Library.remove", false]], "rename_cell() (gdstk.library method)": [[48, "gdstk.Library.rename_cell", false]], "repetition (class in gdstk)": [[3, "gdstk.Repetition", false]], "repetition (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.repetition", false]], "repetition (gdstk.label attribute)": [[47, "gdstk.Label.repetition", false]], "repetition (gdstk.polygon attribute)": [[2, "gdstk.Polygon.repetition", false]], "repetition (gdstk.reference attribute)": [[50, "gdstk.Reference.repetition", false]], "repetition (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.repetition", false]], "replace() (gdstk.library method)": [[48, "gdstk.Library.replace", false]], "robustpath (class in gdstk)": [[4, "gdstk.RobustPath", false]], "rotate() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.rotate", false]], "rotate() (gdstk.polygon method)": [[2, "gdstk.Polygon.rotate", false]], "rotate() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.rotate", false]], "rotation (gdstk.label attribute)": [[47, "gdstk.Label.rotation", false]], "rotation (gdstk.reference attribute)": [[50, "gdstk.Reference.rotation", false]], "rows (gdstk.repetition attribute)": [[3, "gdstk.Repetition.rows", false]], "scale() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.scale", false]], "scale() (gdstk.polygon method)": [[2, "gdstk.Polygon.scale", false]], "scale() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.scale", false]], "scale_width (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.scale_width", false]], "scale_width (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.scale_width", false]], "segment() (gdstk.curve method)": [[0, "gdstk.Curve.segment", false]], "segment() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.segment", false]], "segment() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.segment", false]], "set_bend_function() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_bend_function", false]], "set_bend_radius() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_bend_radius", false]], "set_datatypes() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_datatypes", false]], "set_datatypes() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.set_datatypes", false]], "set_ends() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_ends", false]], "set_ends() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.set_ends", false]], "set_gds_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_gds_property", false]], "set_gds_property() (gdstk.label method)": [[47, "gdstk.Label.set_gds_property", false]], "set_gds_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.set_gds_property", false]], "set_gds_property() (gdstk.reference method)": [[50, "gdstk.Reference.set_gds_property", false]], "set_gds_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.set_gds_property", false]], "set_joins() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_joins", false]], "set_layers() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_layers", false]], "set_layers() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.set_layers", false]], "set_property() (gdstk.cell method)": [[45, "gdstk.Cell.set_property", false]], "set_property() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.set_property", false]], "set_property() (gdstk.label method)": [[47, "gdstk.Label.set_property", false]], "set_property() (gdstk.library method)": [[48, "gdstk.Library.set_property", false]], "set_property() (gdstk.polygon method)": [[2, "gdstk.Polygon.set_property", false]], "set_property() (gdstk.reference method)": [[50, "gdstk.Reference.set_property", false]], "set_property() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.set_property", false]], "simple_path (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.simple_path", false]], "simple_path (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.simple_path", false]], "size (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.size", false]], "size (gdstk.polygon attribute)": [[2, "gdstk.Polygon.size", false]], "size (gdstk.rawcell attribute)": [[49, "gdstk.RawCell.size", false]], "size (gdstk.repetition attribute)": [[3, "gdstk.Repetition.size", false]], "size (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.size", false]], "slice() (in module gdstk)": [[16, "gdstk.slice", false]], "spacing (gdstk.repetition attribute)": [[3, "gdstk.Repetition.spacing", false]], "spine() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.spine", false]], "spine() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.spine", false]], "text (gdstk.label attribute)": [[47, "gdstk.Label.text", false]], "text() (in module gdstk)": [[17, "gdstk.text", false]], "texttype (gdstk.label attribute)": [[47, "gdstk.Label.texttype", false]], "to_polygons() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.to_polygons", false]], "to_polygons() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.to_polygons", false]], "tolerance (gdstk.curve attribute)": [[0, "gdstk.Curve.tolerance", false]], "tolerance (gdstk.flexpath attribute)": [[1, "gdstk.FlexPath.tolerance", false]], "tolerance (gdstk.robustpath attribute)": [[4, "gdstk.RobustPath.tolerance", false]], "top_level() (gdstk.library method)": [[48, "gdstk.Library.top_level", false]], "transform() (gdstk.polygon method)": [[2, "gdstk.Polygon.transform", false]], "translate() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.translate", false]], "translate() (gdstk.polygon method)": [[2, "gdstk.Polygon.translate", false]], "translate() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.translate", false]], "turn() (gdstk.curve method)": [[0, "gdstk.Curve.turn", false]], "turn() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.turn", false]], "turn() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.turn", false]], "unit (gdstk.library attribute)": [[48, "gdstk.Library.unit", false]], "v1 (gdstk.repetition attribute)": [[3, "gdstk.Repetition.v1", false]], "v2 (gdstk.repetition attribute)": [[3, "gdstk.Repetition.v2", false]], "vertical() (gdstk.curve method)": [[0, "gdstk.Curve.vertical", false]], "vertical() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.vertical", false]], "vertical() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.vertical", false]], "widths() (gdstk.flexpath method)": [[1, "gdstk.FlexPath.widths", false]], "widths() (gdstk.robustpath method)": [[4, "gdstk.RobustPath.widths", false]], "write() (gdstk.gdswriter method)": [[46, "gdstk.GdsWriter.write", false]], "write_gds() (gdstk.library method)": [[48, "gdstk.Library.write_gds", false]], "write_oas() (gdstk.library method)": [[48, "gdstk.Library.write_oas", false]], "write_svg() (gdstk.cell method)": [[45, "gdstk.Cell.write_svg", false]], "x_offsets (gdstk.repetition attribute)": [[3, "gdstk.Repetition.x_offsets", false]], "x_reflection (gdstk.label attribute)": [[47, "gdstk.Label.x_reflection", false]], "x_reflection (gdstk.reference attribute)": [[50, "gdstk.Reference.x_reflection", false]], "y_offsets (gdstk.repetition attribute)": [[3, "gdstk.Repetition.y_offsets", false]]}, "objects": {"gdstk": [[45, 0, 1, "", "Cell"], [0, 0, 1, "", "Curve"], [1, 0, 1, "", "FlexPath"], [46, 0, 1, "", "GdsWriter"], [47, 0, 1, "", "Label"], [48, 0, 1, "", "Library"], [2, 0, 1, "", "Polygon"], [49, 0, 1, "", "RawCell"], [50, 0, 1, "", "Reference"], [3, 0, 1, "", "Repetition"], [4, 0, 1, "", "RobustPath"], [5, 3, 1, "", "all_inside"], [6, 3, 1, "", "any_inside"], [7, 3, 1, "", "boolean"], [8, 3, 1, "", "contour"], [9, 3, 1, "", "cross"], [10, 3, 1, "", "ellipse"], [51, 3, 1, "", "gds_info"], [52, 3, 1, "", "gds_units"], [11, 3, 1, "", "inside"], [53, 3, 1, "", "oas_precision"], [54, 3, 1, "", "oas_validate"], [12, 3, 1, "", "offset"], [13, 3, 1, "", "racetrack"], [55, 3, 1, "", "read_gds"], [56, 3, 1, "", "read_oas"], [57, 3, 1, "", "read_rawcells"], [14, 3, 1, "", "rectangle"], [15, 3, 1, "", "regular_polygon"], [16, 3, 1, "", "slice"], [17, 3, 1, "", "text"]], "gdstk.Cell": [[45, 1, 1, "", "add"], [45, 1, 1, "", "area"], [45, 1, 1, "", "bounding_box"], [45, 1, 1, "", "convex_hull"], [45, 1, 1, "", "copy"], [45, 1, 1, "", "delete_property"], [45, 1, 1, "", "dependencies"], [45, 1, 1, "", "filter"], [45, 1, 1, "", "flatten"], [45, 1, 1, "", "get_labels"], [45, 1, 1, "", "get_paths"], [45, 1, 1, "", "get_polygons"], [45, 1, 1, "", "get_property"], [45, 2, 1, "", "labels"], [45, 2, 1, "", "name"], [45, 2, 1, "", "paths"], [45, 2, 1, "", "polygons"], [45, 2, 1, "", "properties"], [45, 2, 1, "", "references"], [45, 1, 1, "", "remap"], [45, 1, 1, "", "remove"], [45, 1, 1, "", "set_property"], [45, 1, 1, "", "write_svg"]], "gdstk.Curve": [[0, 1, 1, "", "arc"], [0, 1, 1, "", "bezier"], [0, 1, 1, "", "commands"], [0, 1, 1, "", "cubic"], [0, 1, 1, "", "cubic_smooth"], [0, 1, 1, "", "horizontal"], [0, 1, 1, "", "interpolation"], [0, 1, 1, "", "parametric"], [0, 1, 1, "", "points"], [0, 1, 1, "", "quadratic"], [0, 1, 1, "", "quadratic_smooth"], [0, 1, 1, "", "segment"], [0, 2, 1, "", "tolerance"], [0, 1, 1, "", "turn"], [0, 1, 1, "", "vertical"]], "gdstk.FlexPath": [[1, 1, 1, "", "apply_repetition"], [1, 1, 1, "", "arc"], [1, 2, 1, "", "bend_function"], [1, 2, 1, "", "bend_radius"], [1, 1, 1, "", "bezier"], [1, 1, 1, "", "commands"], [1, 1, 1, "", "copy"], [1, 1, 1, "", "cubic"], [1, 1, 1, "", "cubic_smooth"], [1, 2, 1, "", "datatypes"], [1, 1, 1, "", "delete_gds_property"], [1, 1, 1, "", "delete_property"], [1, 2, 1, "", "ends"], [1, 1, 1, "", "get_gds_property"], [1, 1, 1, "", "get_property"], [1, 1, 1, "", "horizontal"], [1, 1, 1, "", "interpolation"], [1, 2, 1, "", "joins"], [1, 2, 1, "", "layers"], [1, 1, 1, "", "mirror"], [1, 2, 1, "", "num_paths"], [1, 1, 1, "", "offsets"], [1, 1, 1, "", "parametric"], [1, 1, 1, "", "path_spines"], [1, 2, 1, "", "properties"], [1, 1, 1, "", "quadratic"], [1, 1, 1, "", "quadratic_smooth"], [1, 2, 1, "", "raith_data"], [1, 2, 1, "", "repetition"], [1, 1, 1, "", "rotate"], [1, 1, 1, "", "scale"], [1, 2, 1, "", "scale_width"], [1, 1, 1, "", "segment"], [1, 1, 1, "", "set_bend_function"], [1, 1, 1, "", "set_bend_radius"], [1, 1, 1, "", "set_datatypes"], [1, 1, 1, "", "set_ends"], [1, 1, 1, "", "set_gds_property"], [1, 1, 1, "", "set_joins"], [1, 1, 1, "", "set_layers"], [1, 1, 1, "", "set_property"], [1, 2, 1, "", "simple_path"], [1, 2, 1, "", "size"], [1, 1, 1, "", "spine"], [1, 1, 1, "", "to_polygons"], [1, 2, 1, "", "tolerance"], [1, 1, 1, "", "translate"], [1, 1, 1, "", "turn"], [1, 1, 1, "", "vertical"], [1, 1, 1, "", "widths"]], "gdstk.GdsWriter": [[46, 1, 1, "", "close"], [46, 1, 1, "", "write"]], "gdstk.Label": [[47, 2, 1, "", "anchor"], [47, 1, 1, "", "apply_repetition"], [47, 1, 1, "", "copy"], [47, 1, 1, "", "delete_gds_property"], [47, 1, 1, "", "delete_property"], [47, 1, 1, "", "get_gds_property"], [47, 1, 1, "", "get_property"], [47, 2, 1, "", "layer"], [47, 2, 1, "", "magnification"], [47, 2, 1, "", "origin"], [47, 2, 1, "", "properties"], [47, 2, 1, "", "repetition"], [47, 2, 1, "", "rotation"], [47, 1, 1, "", "set_gds_property"], [47, 1, 1, "", "set_property"], [47, 2, 1, "", "text"], [47, 2, 1, "", "texttype"], [47, 2, 1, "", "x_reflection"]], "gdstk.Library": [[48, 1, 1, "", "add"], [48, 2, 1, "", "cells"], [48, 1, 1, "", "delete_property"], [48, 1, 1, "", "get_property"], [48, 1, 1, "", "layers_and_datatypes"], [48, 1, 1, "", "layers_and_texttypes"], [48, 2, 1, "", "name"], [48, 1, 1, "", "new_cell"], [48, 2, 1, "", "precision"], [48, 2, 1, "", "properties"], [48, 1, 1, "", "remap"], [48, 1, 1, "", "remove"], [48, 1, 1, "", "rename_cell"], [48, 1, 1, "", "replace"], [48, 1, 1, "", "set_property"], [48, 1, 1, "", "top_level"], [48, 2, 1, "", "unit"], [48, 1, 1, "", "write_gds"], [48, 1, 1, "", "write_oas"]], "gdstk.Polygon": [[2, 1, 1, "", "apply_repetition"], [2, 1, 1, "", "area"], [2, 1, 1, "", "bounding_box"], [2, 1, 1, "", "contain"], [2, 1, 1, "", "contain_all"], [2, 1, 1, "", "contain_any"], [2, 1, 1, "", "copy"], [2, 2, 1, "", "datatype"], [2, 1, 1, "", "delete_gds_property"], [2, 1, 1, "", "delete_property"], [2, 1, 1, "", "fillet"], [2, 1, 1, "", "fracture"], [2, 1, 1, "", "get_gds_property"], [2, 1, 1, "", "get_property"], [2, 2, 1, "", "layer"], [2, 1, 1, "", "mirror"], [2, 1, 1, "", "perimeter"], [2, 2, 1, "", "points"], [2, 2, 1, "", "properties"], [2, 2, 1, "", "repetition"], [2, 1, 1, "", "rotate"], [2, 1, 1, "", "scale"], [2, 1, 1, "", "set_gds_property"], [2, 1, 1, "", "set_property"], [2, 2, 1, "", "size"], [2, 1, 1, "", "transform"], [2, 1, 1, "", "translate"]], "gdstk.RawCell": [[49, 1, 1, "", "dependencies"], [49, 2, 1, "", "name"], [49, 2, 1, "", "size"]], "gdstk.Reference": [[50, 1, 1, "", "apply_repetition"], [50, 1, 1, "", "bounding_box"], [50, 2, 1, "", "cell"], [50, 2, 1, "", "cell_name"], [50, 1, 1, "", "convex_hull"], [50, 1, 1, "", "copy"], [50, 1, 1, "", "delete_gds_property"], [50, 1, 1, "", "delete_property"], [50, 1, 1, "", "get_gds_property"], [50, 1, 1, "", "get_labels"], [50, 1, 1, "", "get_paths"], [50, 1, 1, "", "get_polygons"], [50, 1, 1, "", "get_property"], [50, 2, 1, "", "magnification"], [50, 2, 1, "", "origin"], [50, 2, 1, "", "properties"], [50, 2, 1, "", "repetition"], [50, 2, 1, "", "rotation"], [50, 1, 1, "", "set_gds_property"], [50, 1, 1, "", "set_property"], [50, 2, 1, "", "x_reflection"]], "gdstk.Repetition": [[3, 2, 1, "", "columns"], [3, 1, 1, "", "get_offsets"], [3, 2, 1, "", "offsets"], [3, 2, 1, "", "rows"], [3, 2, 1, "", "size"], [3, 2, 1, "", "spacing"], [3, 2, 1, "", "v1"], [3, 2, 1, "", "v2"], [3, 2, 1, "", "x_offsets"], [3, 2, 1, "", "y_offsets"]], "gdstk.RobustPath": [[4, 1, 1, "", "apply_repetition"], [4, 1, 1, "", "arc"], [4, 1, 1, "", "bezier"], [4, 1, 1, "", "commands"], [4, 1, 1, "", "copy"], [4, 1, 1, "", "cubic"], [4, 1, 1, "", "cubic_smooth"], [4, 2, 1, "", "datatypes"], [4, 1, 1, "", "delete_gds_property"], [4, 1, 1, "", "delete_property"], [4, 2, 1, "", "ends"], [4, 1, 1, "", "get_gds_property"], [4, 1, 1, "", "get_property"], [4, 1, 1, "", "gradient"], [4, 1, 1, "", "horizontal"], [4, 1, 1, "", "interpolation"], [4, 2, 1, "", "layers"], [4, 2, 1, "", "max_evals"], [4, 1, 1, "", "mirror"], [4, 2, 1, "", "num_paths"], [4, 1, 1, "", "offsets"], [4, 1, 1, "", "parametric"], [4, 1, 1, "", "path_spines"], [4, 1, 1, "", "position"], [4, 2, 1, "", "properties"], [4, 1, 1, "", "quadratic"], [4, 1, 1, "", "quadratic_smooth"], [4, 2, 1, "", "repetition"], [4, 1, 1, "", "rotate"], [4, 1, 1, "", "scale"], [4, 2, 1, "", "scale_width"], [4, 1, 1, "", "segment"], [4, 1, 1, "", "set_datatypes"], [4, 1, 1, "", "set_ends"], [4, 1, 1, "", "set_gds_property"], [4, 1, 1, "", "set_layers"], [4, 1, 1, "", "set_property"], [4, 2, 1, "", "simple_path"], [4, 2, 1, "", "size"], [4, 1, 1, "", "spine"], [4, 1, 1, "", "to_polygons"], [4, 2, 1, "", "tolerance"], [4, 1, 1, "", "translate"], [4, 1, 1, "", "turn"], [4, 1, 1, "", "vertical"], [4, 1, 1, "", "widths"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:function"}, "terms": {"": [0, 1, 2, 4, 18, 21, 23, 29, 30, 31, 32, 34, 42, 43, 45, 47, 50], "0": [0, 1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 37, 38, 39, 41, 42, 43, 44, 45, 47, 48, 50, 54, 55, 56, 57], "0001": 18, "001": 18, "002": 18, "01": [0, 2, 8, 10, 13, 18, 43], "05": 43, "051": 18, "0512": 18, "0j": [0, 2], "0x00": 26, "0x00000100000001b3": 41, "0x0001": 32, "0x0002": [28, 32], "0x0004": 32, "0x0008": 32, "0x0010": 32, "0x0020": 32, "0x0040": 32, "0x0080": 32, "0x01": 26, "0x0102": 28, "0x02": 26, "0x0206": 28, "0x0258": 28, "0x03": 26, "0x0305": 28, "0x04": 26, "0x0400": 28, "0x05": 26, "0x06": 26, "0x07": 26, "0x08": 26, "0x09": 26, "0x0a": 26, "0x0b": 26, "0x0c": 26, "0x0d": 26, "0x0e": 26, "0x0f": 26, "0x10": 26, "0x11": 26, "0x12": 26, "0x13": 26, "0x14": 26, "0x15": 26, "0x16": 26, "0x17": 26, "0x18": 26, "0x19": 26, "0x1a": 26, "0x1b": 26, "0x1c": 26, "0x1d": 26, "0x1e": 26, "0x1f": 26, "0x20": [21, 26, 32], "0x21": [21, 25, 26, 32, 35], "0x22": 26, "0x23": 26, "0x24": 26, "0x25": 26, "0x26": 26, "0x27": 26, "0x28": 26, "0x29": 26, "0x2a": 26, "0x2b": 26, "0x2c": 26, "0x2d": 26, "0x2e": 26, "0x2f": 26, "0x30": 26, "0x31": 26, "0x32": 26, "0x33": 26, "0x34": 26, "0x35": 26, "0x36": 26, "0x37": 26, "0x38": 26, "0x39": 26, "0x3a": 26, "0x3b": 26, "0x5a": 26, "0x62": 26, "0x7e": [21, 32, 35], "0x7f": 25, "0xcbf29ce484222325": 41, "1": [0, 1, 2, 4, 8, 9, 10, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 47, 48, 50, 55, 57, 58], "10": [0, 1, 2, 3, 4, 7, 9, 12, 15, 16, 18, 25, 29, 31, 32, 43, 45, 48, 50], "100": [10, 18, 25, 43], "1000": [4, 18, 43], "1002": 25, "1007": [0, 1, 4], "101": [2, 25], "1019": 25, "102": [2, 25], "103": [2, 25], "104": 25, "1043": 25, "105": 25, "1051": 18, "1051200": 18, "1066": 25, "108": 25, "10j": [45, 50], "11": [12, 25, 32, 43, 45, 50], "1102": 25, "1110": 25, "1122": 25, "1138": 25, "1158": 25, "118": 25, "12": [1, 17, 18, 25, 32, 43, 45, 50], "1202": 25, "122": 25, "1226": 25, "123": [0, 1, 4, 41], "12345": 18, "1250": 25, "1258": 25, "126": 25, "127": 8, "1286": 25, "128j": 8, "1294": 25, "13": [1, 25, 32, 45], "1318": 25, "1322": 25, "1334": 25, "1354": 25, "1371": 25, "1391": 25, "14": [16, 25, 32], "140": [0, 1, 4, 41], "1407": 25, "1428": 25, "1444": 25, "1464": 25, "147": 18, "147483647": 18, "147483648": 18, "1476": 25, "1480": 25, "1488": 25, "1492": 25, "15": [1, 7, 18, 25, 32, 43], "150": 43, "1500": 25, "1524": 25, "1532": 25, "1550": 25, "1560": 25, "1578": 25, "1595": 25, "16": [7, 17, 18, 25, 32, 34], "1611": 25, "1621": 25, "1641": 25, "1657": 25, "1667": 25, "1683": 25, "17": [25, 32], "1703": 25, "172": 25, "1739": 25, "1755": 25, "1779": 25, "1799": 25, "17th": 44, "18": [1, 13, 18, 25, 32, 43], "180": 25, "1803": 25, "1823": 25, "1843": 25, "1851": 25, "1855": 25, "19": [25, 32], "1900": 28, "1986": [0, 1, 4, 41], "199": [2, 18, 46, 48], "1a": 41, "1e": [0, 1, 2, 4, 7, 12, 16, 18, 30, 43, 46, 48], "1j": [0, 2, 18, 45, 50], "2": [0, 1, 2, 3, 4, 7, 8, 10, 12, 15, 16, 17, 18, 23, 24, 25, 26, 28, 29, 32, 34, 38, 39, 42, 43, 45, 47, 50, 51, 57], "20": [3, 7, 10, 18, 25, 28, 32, 43], "200": [10, 25, 43], "2003": 44, "2020": 27, "21": [25, 32], "22": [25, 32], "220": [25, 43], "222222": [18, 45], "23": [25, 32], "24": [18, 25, 32], "248": 25, "25": [18, 25, 32, 43], "250": 43, "255": 18, "255j": 8, "26": [25, 32], "260": 25, "27": [25, 32, 45, 50], "274": 25, "278": 25, "28": [25, 28, 32], "282": 25, "29": [25, 32], "2d": [18, 42], "2j": [0, 18], "2\u00b3\u00b2": 18, "2\u00b3\u00b9": 18, "3": [0, 1, 2, 3, 4, 7, 10, 12, 13, 15, 16, 18, 23, 25, 26, 32, 39, 41, 43, 45, 50], "30": [2, 7, 10, 25, 32], "300": 43, "31": 32, "310": 25, "313708498984761": [45, 50], "32": [25, 32, 41], "32px": 45, "33": 32, "34": [25, 32], "35": 25, "352": 25, "356": 25, "36": 25, "37": 25, "370": 25, "38": 25, "3g": 43, "4": [0, 1, 4, 8, 10, 12, 15, 17, 18, 25, 26, 28, 29, 30, 32, 34, 39, 43, 45, 50, 58], "40": [2, 7, 10, 25, 43], "400": 25, "41": 25, "42": 25, "428": 25, "43": 25, "44": 25, "45": [18, 25], "455": 25, "46": 25, "47": 25, "475": 25, "48": 25, "483": 18, "49": 25, "5": [0, 1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 15, 16, 17, 18, 23, 25, 26, 29, 32, 34, 39, 41, 43, 45, 50], "50": [7, 10, 18, 25, 43], "500": 43, "501": 25, "51": 25, "515": 25, "52": 25, "53": [25, 27], "54": 25, "55": [25, 43], "552": 25, "56": 25, "57": 25, "578": 25, "58": 25, "582": 25, "586": 25, "59": 25, "590": 25, "5j": [0, 2], "6": [0, 1, 4, 15, 16, 18, 25, 26, 28, 29, 30, 32, 39, 43, 45, 46, 47, 48], "60": [2, 10, 25], "604": 25, "61": 25, "62": [0, 25, 43], "63": 25, "64": [25, 41], "640": 25, "644": 25, "647": 18, "648": [18, 25], "65": 25, "66": 25, "66555281392367": [45, 50], "67": 25, "68": 25, "684": 25, "69": 25, "7": [0, 4, 15, 18, 25, 32, 43, 45], "70": [10, 25, 43], "704": 25, "707106781186548": 45, "708": 25, "71": 25, "72": 25, "728": 25, "73": 25, "74": 25, "75": [9, 18, 25, 43], "750": 43, "751": 25, "76": 25, "7677669529663689": 50, "77": 25, "78": 25, "785": 25, "79": 25, "8": [0, 1, 4, 8, 13, 16, 17, 18, 25, 29, 32, 34, 43, 45, 50], "80": [25, 43], "805": 25, "81": 25, "816310409006173": [45, 50], "8190": [2, 18], "828": 25, "83": 25, "840": 25, "85": 25, "850": 25, "86": 25, "87": 25, "870": 25, "88": 25, "882": 25, "89": 25, "894": 25, "9": [0, 7, 15, 17, 18, 25, 27, 29, 30, 32, 34, 43, 46, 48], "90": 25, "906": 25, "91": 25, "92": 25, "93": 25, "938": 25, "94": 25, "944": 25, "95": 25, "96": 25, "964": 25, "97": 25, "98": 25, "984": 25, "99": 25, "A": [0, 1, 2, 3, 4, 10, 12, 23, 24, 35, 43, 44, 45, 46, 48, 49, 50], "AND": 44, "AS": 44, "And": 22, "As": [7, 18], "BE": 44, "BUT": 44, "By": 18, "FOR": 44, "For": [12, 17, 18, 21, 34, 39, 43, 44, 47], "IN": 44, "If": [0, 1, 2, 4, 5, 6, 7, 10, 11, 12, 13, 16, 18, 20, 21, 23, 24, 27, 28, 30, 31, 34, 36, 37, 39, 41, 43, 45, 46, 47, 48, 49, 50, 54, 55, 56], "In": [2, 18, 23, 24, 39, 43, 46, 58], "It": [0, 1, 4, 18, 21, 28, 30, 36, 39, 43, 44, 45, 49], "NO": 44, "NOT": [20, 21, 30, 35, 44], "No": [21, 23, 24, 28, 29, 30, 34, 36, 37, 38, 39], "Not": [18, 22, 39], "OF": 44, "OR": 44, "On": 26, "One": [0, 1, 4, 7, 12, 16, 47], "Or": [22, 43], "THE": 44, "TO": 44, "That": [18, 36, 58], "The": [0, 1, 2, 3, 4, 7, 8, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 30, 31, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 47, 48, 49, 50, 51, 55, 56, 58], "Their": [34, 35, 58], "There": 18, "These": [1, 2, 4, 18, 21, 24, 29, 34, 35, 37, 39, 43, 45, 47, 48, 50, 58], "To": [18, 20, 25, 45], "Tos": [44, 58], "WITH": 44, "__file__": 43, "__main__": 43, "__name__": 43, "__stdc_format_macro": 27, "__version__": 17, "_all_coord": 25, "_f": 43, "_first_coord": 25, "_first_poli": 25, "_num_coord": 25, "_num_poli": 25, "_use_math_defin": 27, "_win32": 36, "abc": 18, "abl": 18, "about": [21, 24, 30, 46, 48], "abov": [18, 39, 43, 44], "absolut": [0, 1, 4, 23, 43, 45], "accept": [1, 4, 18, 45], "access": [1, 2, 4, 18, 45, 47, 48, 50], "accompani": [27, 30, 44], "accomplish": 43, "accord": [0, 1, 4, 22, 45, 50], "account": [29, 34], "accumul": 39, "achiev": 30, "aco": 43, "across": [1, 2, 4, 18, 43, 45, 47, 50], "actual": [2, 18, 39, 43], "acut": [12, 33], "ad": [18, 21, 30, 35, 43], "add": [18, 23, 35, 39, 43, 45, 47, 48, 50, 57], "addit": [0, 1, 4, 18, 24, 39], "addition": 18, "adjac": [1, 2, 4, 12, 18, 24, 34, 39], "advantag": [18, 43], "advis": 18, "affect": [21, 45], "after": [1, 2, 4, 18, 20, 27, 39, 45, 47, 50], "again": 43, "against": [5, 6, 11, 49], "aim": 43, "algorithm": [0, 1, 4, 44], "align": [43, 47, 48], "align_ref": 43, "alignment_mark": 43, "all": [0, 1, 2, 3, 4, 5, 7, 18, 20, 21, 23, 24, 25, 27, 28, 30, 31, 34, 36, 37, 39, 40, 43, 44, 45, 48, 49, 50, 51, 58], "all_insid": 34, "all_occur": 35, "all_text": [18, 43], "alloc": [18, 20, 21, 24, 27, 30, 31, 35, 39, 40, 41, 43, 58], "allocate_clear": [18, 19, 27, 31, 35, 43, 58], "allocated_polygon": 43, "allow": [18, 21, 30, 43], "allvalu": 32, "almost": 49, "along": [1, 3, 4, 16, 18, 22, 24, 38, 39, 41, 44, 50], "alpha": 43, "alreadi": [24, 39, 43], "also": [1, 4, 18, 21, 23, 36, 37, 39, 43, 44, 45, 48, 50], "although": [18, 48], "alwai": [3, 18, 25, 30, 35, 45], "among": 1, "amount": [18, 45], "an": [0, 1, 2, 3, 4, 7, 10, 18, 20, 21, 22, 23, 24, 25, 30, 32, 34, 39, 41, 43, 45, 47, 48, 49, 50, 53, 54, 56], "analog": 18, "anchor": [29, 47], "ang": [0, 1, 4, 45, 50], "ang0": [0, 1, 4], "ang1": [0, 1, 4], "angl": [0, 1, 2, 4, 7, 10, 15, 18, 23, 24, 26, 34, 39, 41, 42, 43, 45, 47, 50], "angle0": 23, "angle1": 23, "angle_constraint": [18, 23, 24, 39, 41, 43], "angle_f": 39, "angle_i": 39, "ani": [2, 3, 5, 6, 7, 11, 12, 16, 18, 21, 23, 24, 28, 29, 30, 31, 32, 34, 36, 37, 39, 41, 43, 44, 45, 47, 48, 49, 54, 58], "annot": 18, "anoth": [18, 43, 50], "any_insid": [34, 43], "anyon": 44, "anyth": 34, "anywai": 30, "api": 44, "appear": [21, 30, 35, 48], "append": [0, 1, 4, 18, 20, 21, 22, 23, 24, 29, 30, 34, 36, 37, 38, 39, 43], "append_bezi": 23, "append_cub": 23, "append_quad": 23, "append_terminating_nul": 32, "append_unsaf": [20, 23, 31], "appli": [1, 2, 4, 7, 12, 16, 18, 21, 24, 29, 34, 37, 38, 39, 40, 43, 45, 47, 50], "applic": 44, "apply_repetit": [1, 2, 4, 21, 24, 29, 34, 37, 39, 43, 45, 47, 50], "approach": 4, "appropri": 41, "approxim": [0, 1, 2, 4, 10, 13, 18, 23, 34, 39, 41], "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 16, 17, 18, 21, 22, 23, 24, 27, 29, 30, 32, 34, 35, 36, 37, 38, 39, 41, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 58], "arbitrari": 18, "arc": [0, 1, 4, 13, 18, 23, 24, 34, 39, 41, 43], "arc_num_point": 41, "arc_start": 39, "arcco": 43, "arctan2": [1, 4, 43], "area": [2, 8, 18, 34, 45], "aref": [26, 43], "arg": [0, 43], "argc": [18, 43], "argument": [0, 1, 2, 3, 4, 8, 18, 21, 22, 23, 24, 29, 30, 34, 37, 38, 39, 41, 45, 50], "argv": [18, 43], "aris": 44, "arm": 9, "arm1": 43, "arm2": 43, "arm_point": 43, "arm_width": [9, 34], "around": [21, 43, 45], "arrai": [0, 1, 3, 8, 18, 21, 22, 23, 24, 25, 27, 29, 30, 31, 32, 34, 36, 37, 38, 39, 40, 41, 43, 44, 58], "array_growth_factor": 20, "array_ref": [45, 50], "arriv": [0, 1, 4], "ascii": [18, 21, 30, 45], "asciistr": 26, "aspect": [17, 34, 58], "assert": [31, 43], "assign": [1, 2, 4, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 31, 47], "associ": [1, 2, 4, 18, 21, 23, 24, 28, 29, 30, 34, 36, 37, 39, 45, 47, 48, 50], "assum": [0, 1, 4, 21, 30, 35, 43], "astr": 32, "atan2": [42, 43], "attent": 18, "attr": [1, 2, 4, 47, 50], "attribut": [0, 1, 2, 3, 4, 21, 35, 43, 45, 47, 48, 49, 50], "attrtabl": 26, "august": 44, "automat": [0, 1, 4, 18, 43, 46, 48], "avail": [18, 44, 51], "avoid": [12, 18, 43], "ax": [16, 23], "axi": [2, 16, 18, 38, 45, 47, 50], "b": 43, "background": [21, 43, 45], "base": [0, 1, 2, 4, 18, 21, 24, 34, 43, 44, 45, 47, 50], "basic": [42, 43, 58], "bbox": [2, 45, 50], "beam": 1, "becaus": [18, 23, 24, 39, 43, 45, 50], "becom": 33, "befor": [12, 18, 20, 21, 23, 24, 29, 30, 31, 34, 37, 38, 39, 40, 43, 45, 47, 50], "begin": 39, "being": [18, 23, 45, 50], "below": [0, 1, 4, 18, 27, 45, 50], "bend": [1, 18], "bend_funct": [1, 24, 33], "bend_function_data": 24, "bend_radiu": [1, 18, 24, 33, 43], "bend_typ": [18, 24, 33, 43], "bend_type_nam": 33, "bendfunct": [24, 41], "bendtyp": [18, 24, 33, 43], "besid": 18, "best": 48, "better": [0, 1, 4, 18, 58], "between": [0, 1, 4, 7, 8, 12, 16, 17, 18, 23, 24, 32, 34, 39, 41, 48, 50], "bevel": [1, 12, 18, 22, 33], "beyond": 43, "bezier": [0, 1, 4, 18, 23, 24, 39], "bezier2": 39, "bezier3": 39, "bf02187690": [0, 1, 4], "bgnextn": 26, "bgnlib": 26, "bgnstr": 26, "big": 41, "big_endian_swap16": [28, 41], "big_endian_swap32": 41, "big_endian_swap64": [28, 41], "bin": 22, "binari": 49, "bit": [30, 41], "bitarrai": 26, "black": 45, "block": 31, "bool": [2, 5, 6, 18, 20, 21, 22, 23, 24, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43], "boolean": [2, 11, 22, 34, 43, 44], "booleanerror": 41, "boost": [27, 44], "both": [1, 4, 18, 24, 39, 43, 45, 50], "bound": [2, 18, 21, 29, 32, 34, 37, 45, 48, 50], "boundari": [18, 24, 26, 39], "bounding_box": [2, 21, 29, 34, 37, 45, 50], "bounding_box_max": 21, "bounding_box_min": 21, "bounding_box_valid": 21, "box": [2, 18, 21, 26, 29, 34, 37, 45, 48, 50], "boxtyp": 26, "break": 43, "browser": 47, "bstring": 32, "bu": 43, "buffer": [26, 32, 36, 41], "buffer_count": 26, "buffer_end": 28, "buffer_s": 41, "buffer_start": 28, "buffer_unit": 28, "build": [18, 23, 39, 43], "built": 21, "by_spec": 45, "byte": [1, 2, 4, 18, 26, 32, 35, 41, 45, 47, 48, 49, 50], "b\u00e9zier": [0, 1, 4, 18, 23, 39, 41], "c": [0, 1, 4, 18, 23, 32, 41, 43, 44, 48], "c1": 18, "c2": 18, "c3": 18, "c4": 18, "c_count": 25, "c_slice": 10, "ca": 41, "cach": [21, 37, 48], "cad": 44, "calcul": [0, 1, 2, 3, 4, 10, 13, 18, 21, 23, 24, 29, 30, 32, 34, 37, 39, 41, 43, 45, 48, 50, 54], "call": [18, 21, 24, 28, 29, 32, 34, 35, 36, 37, 39, 41, 58], "callabl": [0, 1, 4, 45], "caller": [28, 30], "calloc": [19, 27, 58], "can": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 16, 18, 21, 22, 23, 24, 25, 28, 30, 34, 35, 37, 39, 41, 43, 45, 46, 47, 48, 50, 58], "cannot": [1, 18, 20, 37], "cap": [1, 4, 18], "capac": [18, 20, 31, 40, 43], "care": [18, 43, 58], "case": [2, 18, 21, 23, 28, 30, 32, 33, 34, 43, 46], "caus": 22, "caution": 30, "cb": 41, "cblock": 32, "cell": [3, 27, 28, 30, 32, 36, 37, 44, 46, 48, 49, 50, 51, 57, 58], "cell1": [45, 46, 57], "cell2": [45, 46, 57], "cell_": 37, "cell_1": [45, 57], "cell_2": [45, 57], "cell_arrai": [18, 30, 43], "cell_nam": [18, 30, 43, 48, 50, 51], "cell_ref_num": 32, "cell_to_gd": [24, 39], "cellnam": 32, "cellname_implicit": 32, "center": [1, 2, 4, 9, 10, 13, 15, 18, 24, 34, 39, 41, 47], "center_gradi": 39, "center_intersect": 39, "center_point": 39, "center_posit": 39, "central": [1, 4], "certain": 58, "chain": 18, "challeng": 18, "chang": [1, 4, 18, 21, 24, 30, 36, 37, 39, 41, 43], "char": [18, 21, 23, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 41, 43], "charact": [0, 1, 4, 17, 18, 21, 23, 32, 34, 35], "charg": 44, "check": [2, 5, 6, 11, 18, 20, 24, 30, 34, 39, 43, 44, 48, 49, 54], "checksum": [30, 32, 41], "checksum32": [32, 41, 48], "checksumerror": [30, 41], "chip": 44, "chose": 18, "chosen": 18, "circl": [7, 10, 12, 30, 32, 34, 43, 48], "circle_cel": 43, "circle_cell_nam": 43, "circle_referec": 43, "circle_toler": [30, 32, 48], "circletoler": 48, "circuit": [18, 44], "circular": [0, 1, 4, 13, 18, 23, 33, 34, 43], "circumv": 18, "class": [0, 1, 2, 3, 4, 18, 20, 31, 39, 41, 43, 45, 46, 47, 48, 49, 50, 59], "clear": [18, 20, 21, 23, 24, 29, 30, 31, 34, 36, 37, 38, 39, 40, 43], "clip": [7, 22, 44], "clipper_tool": [27, 58], "clockwis": [0, 1, 4, 18, 23, 34], "close": [0, 1, 4, 18, 23, 28, 32, 46], "closepoli": 43, "cmo": 18, "co": [0, 1, 4, 18, 39, 42], "code": [25, 41, 43, 44], "codepoint": 25, "coincid": [2, 5, 6, 11, 18, 34], "col": 34, "collid": 43, "color": [21, 45], "colrow": 26, "column": [2, 3, 17, 18, 34, 38, 43, 45, 50], "come": 49, "command": [0, 1, 4, 23, 24, 39], "comment": 47, "common": 43, "comp": 21, "compani": 43, "comparison": 18, "complet": [18, 23, 30, 46], "complex": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 23, 43, 44, 45, 47], "compon": [18, 43], "composit": 34, "compress": [30, 48], "compression_level": 48, "comput": [0, 1, 4, 18, 41, 45, 50], "computation": [18, 39, 48], "concaten": 23, "concept": 43, "concret": 24, "condit": 1, "config_flag": [30, 32], "configur": [18, 32], "connect": [0, 1, 4, 18, 34, 44], "consecut": [0, 1], "consid": [2, 5, 6, 11, 23, 34], "consist": 58, "const": [18, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43], "constant": [4, 18, 24, 30, 39, 58], "constrain": [23, 41], "construct": [0, 18, 39, 43, 44], "constructor": 58, "consum": 18, "contact": 18, "contact_cel": 18, "contact_cell_nam": 18, "contact_poli": 18, "contact_ref1": 18, "contact_ref2": 18, "contain": [1, 2, 4, 18, 20, 23, 25, 34, 43, 45, 47, 48, 50, 58], "contain_al": [2, 34], "contain_ani": [2, 34, 43], "content": [7, 12, 16, 18, 21, 30, 40, 43, 45], "context": 18, "continu": [0, 1, 4, 18, 23], "contour": [1, 4, 34], "contract": 44, "control": [0, 1, 4, 18, 23, 37, 41], "control_poli": 0, "control_poly_1": 0, "control_poly_2": 0, "convert": [18, 30, 55, 56], "convex": [21, 37, 41, 45, 50], "convex_hul": [21, 37, 41, 45, 50], "convex_hull_valid": 21, "coord": [38, 43], "coord_i": [23, 24, 39], "coord_x": [23, 24, 39], "coordin": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 25, 42, 45, 47], "copi": [1, 2, 3, 4, 18, 21, 24, 29, 30, 31, 34, 37, 38, 39, 40, 43, 44, 45, 47, 50], "copy_from": [20, 21, 23, 24, 29, 30, 31, 34, 37, 38, 39, 40, 43], "copy_str": [18, 21, 29, 30, 31, 37, 41, 43], "copyright": [27, 44], "corner": [1, 2, 14, 18, 21, 29, 34, 37, 45, 50], "corner1": [14, 34], "corner2": [14, 34], "correct": 23, "correctli": 47, "correspond": [0, 1, 4, 21], "cos_rot": 39, "could": [18, 23, 43], "count": [18, 20, 21, 22, 23, 24, 25, 28, 30, 31, 32, 34, 35, 36, 39, 40, 41, 43], "counter": [0, 1, 4, 18, 23, 34], "coupler": 43, "cours": [43, 58], "cover": [44, 58], "cp": 25, "cplx_conj": 42, "cplx_div": 42, "cplx_from_angl": [18, 42], "cplx_inv": 42, "cplx_mul": 42, "cpp": [43, 58], "crc32": [32, 48], "creat": [1, 2, 3, 4, 8, 9, 10, 13, 14, 15, 17, 18, 23, 24, 28, 34, 35, 36, 37, 38, 39, 45, 46, 47, 48, 49, 50, 58, 59], "create_new": 35, "creation": [1, 4, 18, 24, 30, 39, 43, 44], "cross": [18, 34, 42, 43], "cross1": 9, "cross2": 9, "cross_": 43, "ctrapezoid": 32, "ctrl": [23, 39, 41], "cubic": [0, 1, 4, 18, 23, 24, 39, 41, 43], "cubic_smooth": [0, 1, 4, 18, 23, 24, 39], "curl": 41, "current": [0, 1, 4, 18, 21, 23, 28, 30, 31, 40, 43, 46, 48, 49], "cursor": [32, 36], "curv": [1, 4, 24, 27, 39, 41, 43, 58], "curvatur": [0, 1, 4, 12], "curve3": 43, "curve4": 43, "curve_funct": [0, 23, 24, 39], "curve_gradi": 39, "curveinstruct": [23, 24, 39], "custom": [1, 2, 4, 18, 21, 43, 45, 47, 48, 50], "custom_broken_join": 1, "custom_pointy_end": 1, "cut": [16, 18, 22], "cutout": 18, "cutout_point": 18, "cutout_poli": 18, "cycl": [0, 1, 4, 23, 24, 34, 39, 41], "d": [0, 1, 4, 8, 34, 41, 43], "d04030": 40, "d89080": 40, "damag": 44, "dasharrai": 45, "data": [1, 2, 4, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 23, 24, 25, 30, 32, 34, 36, 37, 39, 41, 43, 45, 48, 50, 51, 55, 58], "data_s": 32, "datatyp": [0, 1, 2, 4, 7, 8, 9, 10, 12, 13, 14, 15, 17, 26, 43, 45, 47, 50], "datetim": [46, 48], "de": 21, "deal": 44, "dealloc": 40, "debug_print": 31, "decim": 18, "decod": 57, "decreas": 30, "decrement": 43, "deep": 30, "deep_copi": [21, 30, 45], "def": [0, 1, 4, 43], "default": [1, 4, 18, 21, 25, 30, 41, 43, 45, 50, 55, 56, 58], "default_svg_label_styl": 41, "default_svg_shape_styl": 41, "defect": 43, "defin": [0, 1, 2, 3, 4, 10, 18, 21, 23, 24, 25, 27, 29, 30, 32, 34, 37, 38, 39, 41, 43, 45, 47, 50, 58], "definit": [0, 1, 4, 18, 58], "deflate_level": 30, "degre": 18, "del": [31, 40, 46], "delet": [1, 2, 4, 45, 46, 47, 48, 50], "delete_gds_properti": [1, 2, 4, 47, 50], "delete_properti": [1, 2, 4, 45, 47, 48, 50], "delta": 32, "demonstr": [18, 43], "den": 1, "dep": 57, "depend": [3, 21, 30, 36, 39, 43, 45, 48, 49, 57, 58], "depth": [21, 37, 45, 50], "deriv": 44, "describ": 42, "descript": 47, "design": [18, 43, 44, 46, 47, 48], "desir": [1, 2, 4, 7, 8, 12, 16, 18, 21, 24, 25, 30, 31, 34, 39, 43, 45, 46, 48], "destructor": 58, "detail": [41, 58], "detect": [18, 30, 48], "detect_rectangl": 48, "detect_trapezoid": 48, "determin": [4, 41], "dev_cel": 43, "dev_ref": 43, "develop": 44, "devic": [18, 43], "device_cel": 18, "device_cell_nam": 18, "device_ref": 18, "diamet": 43, "dict": [45, 51, 57], "dict_kei": 57, "dictat": 24, "dictionari": [18, 43, 45, 48, 51, 57], "differ": [3, 7, 18, 39, 43, 50], "digit": 45, "dilat": [12, 18, 22], "dimens": [21, 45], "dimension": 8, "direct": [1, 2, 3, 4, 16, 17, 23, 38, 41, 43, 50], "directin": 43, "directional_coupl": 43, "directional_coupler_cel": 43, "directli": [18, 21, 24, 39], "directori": [18, 43], "disabl": 48, "disadvantag": 18, "disclaim": 44, "discontinu": 4, "discret": [0, 1, 4, 41], "discuss": 30, "displai": [44, 47], "disregard": 18, "distanc": [1, 4, 8, 12, 18, 22, 23, 24, 39, 41, 43], "distance_to_lin": 41, "distance_to_line_sq": 41, "distribut": [27, 44], "divid": 24, "do": [1, 4, 18, 30, 34, 41, 44, 47, 48, 58], "document": [2, 30, 58], "doe": [1, 2, 4, 18, 20, 21, 30, 32, 36, 39, 43, 45, 47, 48, 50, 54, 58], "doesn": [18, 21, 24, 34], "doi": [0, 1, 4], "domain": 25, "don": [18, 43], "donat": 44, "done": [36, 46], "dont": 43, "dot": 45, "doubl": [18, 20, 21, 22, 23, 24, 26, 28, 29, 30, 32, 34, 35, 37, 38, 39, 41, 42, 43], "double_print": 41, "doughnut": 18, "downsid": 18, "dp": 43, "draw": [18, 21, 25, 34], "drawback": 18, "drawn": [18, 21, 25], "duplic": 48, "dure": 7, "dx": [1, 2, 4], "dy": [1, 2, 4], "dynam": [24, 27, 30, 39, 41, 58], "e": [0, 1, 4, 8, 18, 21, 23, 24, 29, 32, 34, 38, 40, 41, 42, 47], "each": [0, 1, 2, 4, 5, 6, 7, 11, 12, 16, 18, 23, 24, 30, 34, 35, 39, 41, 43, 45, 47, 48, 50], "earlier": [18, 43], "easi": [0, 1, 4, 41], "easili": 18, "east": 47, "eaxmpl": 46, "edg": [1, 2, 5, 6, 11, 18, 22, 34], "edit": 18, "editor": [18, 43], "effect": [0, 1, 4, 18, 22, 43], "effici": [18, 43, 44, 48], "eightbyter": 26, "either": [18, 21, 30, 45, 50], "el": [24, 39], "electr": 43, "electron": [1, 18, 44], "element": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 16, 18, 20, 21, 24, 30, 34, 37, 38, 39, 40, 43, 45, 47, 48, 49, 50], "element_cent": [24, 39], "elflag": 26, "elif": 43, "elkei": 26, "ellips": [7, 12, 16, 18, 23, 34, 43, 45], "ellipse_": 18, "ellipt": [0, 1, 4, 18, 23, 39], "elliptical_angle_transform": 41, "els": [1, 18, 19, 20, 28, 31, 36, 43], "elsewher": 35, "emploi": 18, "empti": [2, 7, 21, 22, 30], "enabl": 30, "encapsul": 41, "enclos": 18, "encod": [21, 30, 45], "end": [0, 1, 4, 18, 20, 23, 24, 29, 32, 34, 35, 37, 38, 39, 43], "end_extens": [24, 33, 39, 43], "end_funct": [24, 33, 39, 43], "end_function_data": [24, 39, 43], "end_offset": [18, 39], "end_point": [23, 24, 39, 43], "end_typ": [18, 24, 33, 39, 43], "end_type_nam": 33, "end_width": [18, 39], "endel": 26, "endextn": 26, "endfunct": [24, 39, 41], "endian": 41, "endif": [19, 27, 36], "endlib": 26, "endmask": 26, "endpoint": [0, 1, 4], "endstr": 26, "endtyp": [18, 24, 33, 39, 43], "enforc": [21, 30], "engin": 44, "enough": [22, 43, 58], "ensur": [0, 1, 4, 18, 20, 23, 49], "ensure_slot": [20, 23, 31, 43], "entir": [43, 44], "entiti": 18, "enum": [22, 26, 29, 32, 33, 35, 37, 38, 39, 41, 58], "equal": [1, 23, 31, 43, 48, 49], "equival": [18, 24, 29, 34, 37, 38, 39, 58], "erod": [12, 18, 22], "eros": [18, 22], "error": [18, 28, 30, 34, 41], "error_cod": [28, 30, 32, 36, 43], "error_logg": [28, 41], "errorcod": [21, 22, 24, 26, 28, 29, 30, 32, 34, 35, 36, 37, 39, 41, 43], "etc": 43, "etch": 18, "eval": 39, "eval_bezi": 41, "eval_bezier2": 41, "eval_bezier3": 41, "eval_lin": 41, "evalu": [4, 39, 41], "even": [21, 24, 25, 39], "event": 44, "ever": [24, 39], "everi": [1, 23], "exampl": [0, 1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 15, 16, 17, 18, 20, 22, 43, 45, 47, 48, 50, 55, 56, 57, 58], "example_boolean": 18, "example_circl": 18, "example_curves1": 18, "example_curves2": 18, "example_curves3": 18, "example_fillet": 18, "example_flexpath1": 18, "example_flexpath2": 18, "example_flexpath3": 18, "example_hol": 18, "example_layerdatatyp": 18, "example_offset": 18, "example_polygon": 18, "example_slic": 18, "example_transform": 18, "except": [7, 12, 16, 36, 39, 45, 58], "exclud": 34, "execut": [7, 22, 23, 24, 39, 43, 44, 45, 50], "exemplifi": 18, "exist": [1, 2, 4, 18, 31, 35, 43, 45, 47, 48, 50], "exit": 43, "exit_failur": 43, "exp": [0, 18, 45, 50], "expect": [1, 18, 24, 39, 48, 58], "expens": [18, 48], "explain": 37, "explic": [32, 38, 43], "explicit": [3, 32, 38, 43], "explicitgrid": 32, "explicitli": [36, 38], "explicitx": [32, 38, 43], "explicitxgrid": 32, "explicitygrid": 32, "export": [18, 45], "express": 44, "extend": [1, 4, 18, 20, 33, 43], "extens": [1, 4, 18, 43], "extern": [32, 41, 49], "extra": [18, 32, 43], "extract": [8, 36], "extrema": 38, "f": [17, 43, 45, 50], "f_cell": [45, 50], "fabric": [18, 43], "facilit": [18, 24, 39, 43], "fact": 43, "factor": [1, 2, 4, 22, 41, 43, 45, 47], "fals": [0, 1, 2, 4, 5, 6, 12, 13, 17, 18, 20, 21, 22, 23, 31, 39, 43, 45, 47, 48, 50, 54], "famili": 43, "fclose": 28, "fd": 36, "featur": [18, 44, 58], "few": [30, 43, 58], "field": [30, 44], "file": [1, 2, 4, 21, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59], "fileerror": 41, "filenam": [18, 21, 28, 30, 36, 43, 48], "fileno": 36, "fill": [20, 31, 40, 43, 45], "fill_frac": 43, "fill_offsets_and_width": 24, "fill_widths_and_offset": 39, "fillet": [2, 34, 43], "fillet_radiu": 43, "filleted_pad": 43, "filleted_path": 18, "filletedpaddata": 43, "filter": [21, 24, 37, 39, 44, 45, 50, 55], "filtered_lib": 55, "final": [1, 10, 18, 28, 30, 43, 45], "final_angl": [0, 1, 4, 10, 12, 18, 23, 24, 34, 39, 41], "final_curl": [0, 1, 4, 23, 24, 39, 41], "final_valu": [18, 39, 43], "find": [4, 18, 30, 39, 41], "fine": 18, "finer": 18, "finish": 46, "first": [0, 1, 2, 3, 4, 7, 14, 20, 21, 23, 24, 26, 32, 35, 38, 39, 43, 44, 45, 47, 48, 50], "first_codepoint": 25, "first_direct": 41, "first_point": 41, "fit": 44, "fix": [18, 41, 43], "flag": [1, 4, 21, 23, 24, 32, 39, 47], "flat": 21, "flatten": [21, 43, 45], "flexibl": [1, 43], "flexpath": [4, 5, 6, 7, 11, 12, 16, 18, 21, 23, 27, 37, 39, 43, 45, 50, 58], "flexpath_arrai": [18, 21, 43], "flexpathel": 24, "float": [1, 2, 21, 45, 53], "flush": [1, 4, 18, 33], "fnv": 41, "follow": [0, 1, 2, 4, 18, 21, 22, 23, 27, 37, 41, 43, 44, 45, 47, 48, 50, 51, 58], "font": [17, 18, 26, 44, 45, 58], "font_manag": 43, "font_prop": 43, "fontproperti": 43, "fopen": 28, "forbidden": 21, "form": [18, 23, 34, 43, 44, 45, 57], "format": [18, 21, 24, 26, 29, 34, 35, 37, 39, 41, 47, 48, 49], "former": 43, "forward": 20, "found": [1, 2, 4, 20, 21, 30, 31, 43, 45, 47, 48, 50], "four": 18, "fourbyter": 26, "fourbytesignedinteg": 26, "fp": [18, 43], "fp1": 18, "fp2": 18, "fp3": 18, "fp4": 18, "fp5": 18, "fpath": 4, "fput": 28, "fraction": 43, "fractur": [2, 18, 24, 28, 30, 34, 39, 46, 48], "frame": 47, "fread": 36, "free": [19, 20, 27, 30, 43, 44, 58], "free_al": [21, 30, 43], "free_alloc": [18, 19, 20, 21, 27, 30, 31, 43, 58], "free_slot": [20, 23], "freed": 58, "freedom": 18, "freeli": [1, 4, 18, 21, 58], "from": [0, 1, 4, 8, 18, 20, 21, 23, 24, 25, 28, 30, 36, 39, 41, 43, 44, 45, 48, 49, 51, 55, 56], "from_below": [4, 39], "fseek64": 36, "full": [8, 12, 17, 18, 34, 43], "full_siz": [9, 34], "fulli": 58, "func_data": 39, "function": [0, 1, 4, 18, 21, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 43, 45, 58, 59], "fundament": 45, "furnish": 44, "further": [30, 58], "furthermor": 36, "futur": 41, "fwrite": 28, "g": 40, "gabrielli": 27, "gamma": 43, "gap": [20, 31], "garant": 22, "gather": [30, 43, 51], "gd": [18, 43, 48, 55, 57], "gds_info": 30, "gds_timestamp": 30, "gds_unit": [30, 43, 49], "gdsii": [1, 2, 4, 21, 24, 27, 28, 29, 30, 34, 35, 36, 37, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 55, 57, 58, 59], "gdsii_read_record": 26, "gdsii_real_from_doubl": [26, 28], "gdsii_real_to_doubl": 26, "gdsiidatatyp": 26, "gdsiirecord": [26, 58], "gdspy": 44, "gdstk": [18, 21, 23, 24, 25, 28, 29, 30, 34, 36, 37, 39, 43, 58], "gdstk_custom_alloc": [19, 27], "gdstk_header_gdstk": 27, "gdstk_initial_map_capac": 31, "gdstk_map_capacity_threshold": 31, "gdstk_map_growth_factor": 31, "gdstk_version": 27, "gdswriter": [27, 58], "gdswriter_init": 28, "gener": [1, 2, 3, 4, 18, 24, 26, 32, 38, 39, 42, 43, 44, 45, 47, 48, 50, 58], "geom": [0, 1, 4, 41], "geometr": [2, 18, 47, 59], "geometri": [12, 21, 22, 30, 37, 44, 45, 47, 50, 51, 55, 56], "geometryinfo": [21, 37], "get": [30, 31, 40, 43, 44, 48, 58], "get_cel": 30, "get_count": [32, 38], "get_depend": [21, 36, 43, 45], "get_extrema": 38, "get_flexpath": [21, 37], "get_gds_properti": [1, 2, 4, 35, 47, 50], "get_label": [21, 37, 43, 45, 50], "get_label_tag": [21, 30], "get_lay": [41, 43], "get_now": [28, 41], "get_offset": [3, 38], "get_path": [43, 45, 50], "get_polygon": [21, 37, 43, 45, 50], "get_properti": [1, 2, 4, 35, 45, 47, 48, 50], "get_raw_depend": [21, 43], "get_rawcel": 30, "get_robustpath": [21, 37], "get_shape_tag": [21, 30], "get_slot": [31, 40], "get_typ": 41, "gettingstart": 30, "github": [30, 44], "give": 48, "given": [0, 1, 2, 3, 4, 8, 18, 22, 23, 25, 28, 34, 35, 40, 41], "global": [41, 58], "glyph": [25, 34, 43], "go": [18, 43, 58], "good": [0, 1, 4, 47], "grad": 43, "grad_data": 39, "gradient": [4, 39, 43], "grant": 44, "grat1": 43, "grat2": 43, "grate": 43, "grating_cel": 43, "grating_ref1": 43, "grating_ref2": 43, "greater": [13, 55, 56], "grid": [18, 22, 43], "guarante": [21, 41], "h": [0, 1, 4, 18, 43, 58], "ha": [0, 1, 4, 18, 30, 34, 43], "half": [2, 33, 34], "half_pi": [0, 1, 4], "half_trace_width": 43, "half_width_and_offset": [24, 39], "halfwidth": [18, 33], "hand": 23, "happen": 18, "has_kei": 31, "hash": [21, 31, 40, 41, 43], "hash_fnv_offset": 41, "hash_fnv_prim": 41, "have": [1, 2, 4, 18, 21, 24, 30, 32, 34, 39, 41, 43, 45, 47, 48, 50, 54], "hcoord": 43, "header": [25, 26, 27, 28, 32, 44], "heap": 18, "heater1": 43, "heater2": 43, "heater_point": 43, "height": [17, 18, 34], "heitzmann": [27, 30], "held": 28, "help": [18, 44], "here": 43, "herebi": 44, "hierarch": 18, "hierarchi": [18, 21], "hline": 43, "hobbi": [0, 1, 4, 41], "hobby_interpol": 41, "hold": [18, 24, 35, 39, 43], "holder": 44, "hole": [22, 34, 43], "homogen": 2, "horizont": [0, 1, 4, 17, 18, 22, 23, 24, 34, 39, 45, 47, 50], "horizontal_lineskip": 25, "horizontal_step": 25, "horizontal_tab": 25, "host": 41, "how": [37, 44, 58], "howev": 22, "hpp": [18, 27, 43], "htext": 18, "html": 30, "http": [25, 27, 30], "hull": [21, 37, 41, 45, 50], "hundr": 18, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 49, 50, 55, 56, 57, 58], "idea": 43, "ident": [0, 1, 3, 4, 18, 39], "identifi": [18, 21], "idiom": [18, 58], "idx": 20, "ifdef": [19, 36], "ifndef": 27, "ignor": [45, 50], "illustr": 43, "im": 42, "imag": [18, 21, 45, 47], "imagin": 18, "imaginari": 18, "impact": 18, "implement": [27, 41, 58], "impli": 44, "implicit": 32, "import": [18, 30, 31, 43, 49, 55, 56, 58], "imposs": 18, "includ": [3, 18, 21, 26, 27, 28, 30, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 48, 49, 50, 58], "include_path": [21, 37, 45, 50], "inclus": 4, "increas": 18, "increment": [25, 28], "independ": [43, 45], "index": [20, 23, 25, 31, 40, 45, 57], "index_": 20, "indic": [3, 12, 16, 18, 21, 23, 24, 32, 34, 37, 39, 41, 45, 50], "individu": [18, 43], "industri": 18, "infil": [18, 51, 52, 53, 54, 55, 56, 57], "info": [30, 51], "inform": [18, 21, 24, 28, 30, 44, 47, 51], "infring": 44, "ing": 30, "inherit": 58, "init": [18, 21, 23, 24, 29, 30, 37, 39, 43, 58], "initi": [1, 10, 23, 24, 30, 39, 58], "initial_angl": [0, 1, 4, 10, 12, 18, 23, 24, 34, 39, 41], "initial_array_capac": 20, "initial_curl": [0, 1, 4, 23, 24, 39, 41], "initial_point": 4, "initial_posit": [23, 24, 39], "initial_valu": [18, 39, 43], "inlin": [19, 20, 22, 28, 32, 33, 41, 42], "inner": [1, 18, 42], "inner_radiu": [10, 13, 18, 34], "inner_radius_i": 34, "inner_radius_x": 34, "input": [23, 51, 52, 53, 54, 55, 56, 57], "inputfileerror": 41, "inputfileopenerror": 41, "insert": [20, 21, 30, 31, 35, 50], "insid": [2, 5, 6, 34, 43, 48], "inspect": 58, "inspir": 18, "instal": [27, 44], "instanc": [18, 20, 21, 23, 24, 29, 30, 31, 34, 37, 38, 39, 40, 50], "instanti": 43, "instead": [1, 2, 21, 27, 39, 43, 47], "instruct": [23, 44], "insufficientmemori": 41, "int": [3, 18, 32, 43], "int64_t": [21, 32, 35, 36, 37, 41, 42, 43], "integ": [15, 18, 22, 35, 39, 42, 45, 48, 50], "intend": 35, "intens": 39, "interfac": [21, 23, 24, 28, 29, 30, 34, 36, 37, 39, 58], "interferomet": 43, "intern": [18, 21, 22, 23, 31, 32, 40, 41, 42], "interpol": [0, 1, 4, 7, 18, 23, 24, 39, 41, 43], "interpolationtyp": [18, 39, 43], "interpret": [0, 1, 18, 21], "intersect": [1, 4, 18, 39, 41], "intersectionnotfound": 41, "intvec2": [20, 32, 41, 42], "inv": 18, "invalid": [21, 37, 48], "invalidfil": 41, "invalidrepetit": 41, "inward": 44, "io": 30, "is_multiple_of_pi_over_2": 41, "isolin": 34, "issu": 18, "ital": 43, "item": [18, 20, 23, 24, 31, 39, 40, 43], "iter": [31, 40, 43, 45, 55], "iter_seg": 43, "its": [0, 1, 2, 4, 18, 21, 23, 24, 29, 34, 36, 37, 39, 40, 45, 47, 48, 50], "itself": 43, "j": [0, 1, 4, 20, 21, 43, 45], "john": 41, "join": [1, 4, 12, 18, 22, 33, 39, 43], "join_funct": [24, 33], "join_function_data": 24, "join_typ": [18, 24, 33, 43], "join_type_nam": 33, "joinfunct": [24, 41], "joint": 12, "jointyp": [18, 24, 33, 43], "just": [18, 58], "keep": [18, 23, 25, 45, 48], "kei": [21, 30, 31, 41, 44, 45, 51, 57], "kept": [18, 30, 45], "kind": 44, "kit": [43, 44], "klayout": 18, "know": [18, 43], "l": [0, 1, 4, 23], "label": [3, 18, 21, 27, 30, 37, 43, 45, 50, 51, 58], "label_": 47, "label_arrai": [18, 21], "label_n": 47, "label_nw": 47, "label_o": 47, "label_s": 47, "label_styl": [21, 45], "label_sw": 47, "label_tag": 30, "label_text": 18, "label_w": 47, "lambda": [0, 4, 18, 45], "languag": [43, 44], "larg": [18, 22, 44, 46], "larger": [18, 34, 43], "largest": [21, 45], "laser": 18, "last": [0, 1, 4, 18, 20, 23, 35, 39, 41, 43], "last_ctrl": 23, "last_properti": 32, "later": [18, 43], "latter": [1, 4, 37, 43], "layer": [1, 2, 4, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 26, 37, 41, 43, 45, 47, 48, 50, 51, 55], "layer_type_map": [45, 48], "layername_data": 32, "layername_text": 32, "layers_and_datatyp": [48, 51], "layers_and_texttyp": [48, 51], "layout": [28, 41, 43, 44, 45, 47, 48, 55, 56], "ld": 18, "leak": 18, "least": [1, 8, 12, 20, 22, 23, 32, 34, 35, 39], "leav": [0, 1, 4, 43], "left": [2, 18, 28, 30, 37, 45, 50], "left_gradi": 39, "left_intersect": 39, "left_point": 39, "left_posit": 39, "len": [2, 16, 28, 32, 41, 42, 43, 45, 48, 57], "lenght_scal": 8, "length": [1, 2, 4, 8, 9, 13, 15, 18, 22, 23, 26, 31, 34, 40, 41, 42, 43, 48], "length_scal": 8, "length_sq": [23, 42], "lerp": 39, "less": [1, 4, 21, 23, 34, 43, 48], "let": 18, "level": [8, 18, 21, 22, 30, 34, 37, 43, 45, 48, 50], "lg": 20, "liabil": 44, "liabl": 44, "lib": [18, 43, 48], "lib1": [18, 43], "lib1_cell_nam": 43, "lib2": [18, 43], "lib3": 18, "lib_nam": [18, 43], "libarri": 45, "libc": 58, "libdirs": 26, "libnam": 26, "librari": [21, 27, 32, 42, 44, 45, 46, 49, 51, 52, 53, 55, 56, 57, 58], "library_nam": 28, "libraryinfo": 30, "libsecur": 26, "licens": 27, "license_1_0": 27, "lift": 18, "lightwav": 44, "like": [2, 8], "lim": 1, "limit": [18, 21, 31, 37, 44, 58], "line": [0, 1, 2, 4, 17, 18, 23, 34, 39, 41], "linear": [3, 4, 18, 32, 39, 43], "linearli": [1, 4, 18], "lineto": 43, "link": 35, "linkkei": 26, "linktyp": 26, "linspac": 43, "list": [1, 2, 4, 7, 8, 12, 16, 17, 18, 32, 35, 45, 47, 48, 49, 50, 51], "lithographi": [1, 18, 43], "littl": [41, 43], "little_endian_swap16": 41, "little_endian_swap32": 41, "little_endian_swap64": 41, "ll": [18, 43], "load": [30, 36, 43, 51, 55, 56, 57], "localtim": 41, "locat": [18, 43], "log": 41, "long": [18, 43, 58], "longer": 36, "loop": [21, 43, 45], "loos": 0, "lost": 18, "low": 18, "lower": [2, 23, 34, 37, 45, 50], "lowerbound": 32, "lowercas": [0, 1, 4], "luca": 27, "ly": 34, "m": [8, 18, 41, 43], "m_pi": [18, 23, 41, 43], "mach": 43, "mach_zehnder_interferomet": 43, "mach_zenhder_interferomet": 43, "machin": 44, "made": [0, 1, 4, 18], "mag": [26, 29, 37], "magnif": [2, 18, 24, 29, 34, 37, 38, 39, 43, 45, 47, 50, 58], "mai": [18, 22], "main": [18, 30, 39, 43, 45, 48, 50], "main_cel": [18, 43, 45, 50], "main_cell_nam": [18, 43], "mainli": 18, "major": [18, 34, 43], "make": [1, 4, 39, 43, 45, 49], "make_first_lib": 43, "make_second_lib": 43, "make_tag": [18, 41, 43], "malloc": [19, 27, 58], "manag": [27, 44], "manhattan": 32, "manhattanhorizontalfirst": 32, "manhattanverticalfirst": 32, "mani": [18, 37, 48], "manipul": [44, 59], "manner": 43, "manual": [18, 24, 28, 39, 43, 58], "map": [18, 21, 27, 30, 32, 36, 37, 40, 43, 45, 48, 58], "mapitem": [31, 43], "margin": [21, 45], "mark": [43, 48], "marker": 43, "mask": [18, 26], "match": [1, 2, 4, 24, 45, 47, 48, 50, 58], "math": 43, "matplotlib": 43, "matrix": [2, 38, 39], "matter": 43, "max": [21, 29, 34, 37, 43], "max_ev": [4, 39, 58], "max_evals_": 39, "max_i": [2, 45, 50], "max_point": [2, 18, 21, 28, 30, 34, 46, 48], "max_x": [2, 45, 50], "maxim": [2, 4, 12, 18, 30, 39, 41, 46, 48], "maximum": [21, 45], "mean": [0, 1, 4, 18], "meaning": 23, "meant": [32, 36, 41, 44, 49], "mechan": 44, "meet": 18, "member": [35, 58], "memcpi": 20, "memmov": 20, "memori": [1, 4, 27, 28, 30, 36, 41, 43, 44, 46, 49], "mention": 18, "merchant": 44, "merg": [7, 12, 22, 44], "met": 1, "metadata": [1, 2, 4, 45, 47, 48, 50], "meter": [18, 46, 48], "method": [0, 1, 2, 3, 4, 18, 43, 45, 46, 47, 48, 49, 50, 58], "metric": 25, "mgrid": 8, "microelectron": 18, "mid": 1, "might": [41, 46, 58], "min": [21, 29, 34, 37, 43], "min_i": [2, 45, 50], "min_x": [2, 45, 50], "mind": 18, "minim": [22, 58], "minor": 43, "mirror": [1, 2, 4, 18, 24, 34, 39], "missingrefer": 41, "miter": [1, 12, 18, 22, 33], "mix": 18, "mm": 18, "mock": [0, 1, 4], "modern": 18, "modif": [18, 30], "modifi": [18, 43, 49, 58], "modul": [18, 43, 44], "more": [18, 39, 43, 46, 48], "most": [2, 18, 34, 37], "move": 31, "moveto": 43, "much": 18, "multi": 46, "multipl": [0, 1, 2, 3, 4, 12, 18, 23, 41, 43, 45, 47, 48, 50], "must": [0, 1, 4, 12, 18, 21, 22, 23, 24, 26, 27, 29, 30, 32, 34, 37, 38, 39, 41, 43, 44, 45, 50], "my_ref": 18, "mzi": 43, "mzi_ref": 43, "n": [0, 1, 4, 8, 16, 20, 23, 28, 29, 31, 32, 41, 43, 47], "name": [1, 2, 4, 18, 21, 30, 35, 36, 37, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58], "name_": [21, 30, 37], "namespac": [18, 21, 23, 24, 28, 29, 30, 34, 36, 37, 39, 43, 58], "natur": [1, 18, 33], "ndarrai": [0, 1, 3, 4, 45, 50], "ne": [29, 32, 47], "necessari": 18, "need": [4, 21, 24, 28, 36, 39, 41, 43], "neg": [0, 1, 4, 12, 22, 23, 37, 45, 50, 55, 56], "neighbor": [0, 1, 4, 8, 32], "net": 25, "new": [1, 2, 4, 12, 18, 21, 24, 30, 35, 39, 41, 43, 45, 47, 48, 50], "new_capac": [31, 40], "new_cel": [18, 30, 43, 48], "new_item": 31, "new_map": 31, "new_nam": [21, 30, 48], "new_timestamp": 30, "newli": [1, 2, 4, 21, 47, 50], "next": [31, 35, 39, 40, 43], "next_": 31, "ngdstk": 17, "nin": 45, "nm": 18, "nodata": 26, "node": 26, "nodetyp": 26, "noerror": [32, 41, 43], "non": [44, 45, 50], "none": [0, 1, 2, 3, 4, 7, 10, 32, 33, 35, 38, 43, 45, 46, 47, 48, 50, 54, 55], "nonetheless": 18, "normal": 42, "north": 47, "northeast": 47, "northwest": 47, "note": [30, 39, 43, 46], "noth": 41, "notic": 44, "now": 43, "nscale": 43, "nstring": 32, "null": [18, 20, 21, 23, 24, 28, 29, 30, 31, 34, 35, 37, 39, 40, 41, 43], "num": 43, "num_byt": 36, "num_cel": 48, "num_el": [24, 39], "num_elements_": [24, 39], "num_label": [30, 51], "num_path": [1, 4, 30, 51], "num_polygon": [30, 51], "num_refer": [30, 51], "number": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23, 24, 25, 31, 34, 35, 38, 39, 40, 41, 43, 45, 46, 47, 48, 50, 51, 55, 56], "numer": [0, 1, 4, 39], "numpi": [0, 1, 3, 4, 8, 10, 12, 18, 43, 45, 47, 50], "nw": [29, 32, 47], "o": [18, 29, 47], "oa": [18, 56], "oas_info": 30, "oas_precis": 30, "oas_valid": 30, "oasi": [1, 2, 4, 21, 24, 27, 29, 30, 34, 35, 39, 42, 44, 45, 47, 48, 50, 53, 54, 56, 58, 59], "oasis_config_": 30, "oasis_config_detect_al": [18, 32], "oasis_config_detect_rectangl": 32, "oasis_config_detect_trapezoid": 32, "oasis_config_include_checksum32": 32, "oasis_config_include_crc32": 32, "oasis_config_property_bounding_box": 32, "oasis_config_property_cell_offset": 32, "oasis_config_property_max_count": 32, "oasis_config_property_top_level": 32, "oasis_config_standard_properti": 32, "oasis_putc": 32, "oasis_read": 32, "oasis_read_1delta": 32, "oasis_read_2delta": 32, "oasis_read_3delta": 32, "oasis_read_gdelta": 32, "oasis_read_integ": 32, "oasis_read_point_list": 32, "oasis_read_r": 32, "oasis_read_real_by_typ": 32, "oasis_read_repetit": 32, "oasis_read_str": 32, "oasis_read_unsigned_integ": 32, "oasis_writ": 32, "oasis_write_1delta": 32, "oasis_write_2delta": 32, "oasis_write_3delta": 32, "oasis_write_gdelta": 32, "oasis_write_integ": 32, "oasis_write_point_list": 32, "oasis_write_r": 32, "oasis_write_repetit": 32, "oasis_write_unsigned_integ": 32, "oasisdatatyp": 32, "oasisdirect": 32, "oasisinterv": 32, "oasispointlist": 32, "oasisrecord": [32, 58], "oasisrepetit": 32, "oasisst": [24, 32, 34, 35, 39], "oasisstream": [24, 32, 34, 35, 39], "oasisvalid": 32, "object": [0, 1, 2, 3, 4, 18, 38, 43, 44, 46, 47, 48, 50, 59], "obtain": [16, 30, 44], "occur": [24, 39], "occurr": 20, "octangular": 32, "off": 18, "offer": [18, 43], "offici": 2, "offset": [0, 1, 3, 4, 16, 22, 24, 36, 38, 39, 43, 44, 48], "offset0": 39, "offset1": [18, 39], "offset2": 18, "offset3": 18, "offset_arrai": 39, "offset_read": 36, "offset_scal": [39, 58], "offsetjoin": [18, 22], "offsets1": 43, "offsets2": 43, "often": [18, 43], "old": [30, 48], "old_cel": 30, "old_nam": [30, 48], "older": 18, "onc": [18, 23, 28, 43, 46, 48], "one": [0, 1, 2, 4, 8, 11, 18, 24, 30, 34, 35, 39, 43, 45, 46, 48, 50], "ones": 39, "onli": [1, 2, 3, 4, 18, 21, 23, 24, 26, 27, 30, 32, 33, 37, 39, 41, 43, 45, 47, 48, 49, 50, 55, 58], "open": [0, 1, 4, 18, 28, 36, 39], "oper": [7, 12, 20, 22, 42, 43, 44, 45, 48, 50], "operand": 7, "operand1": 7, "operand2": 7, "oppos": 14, "option": [18, 24, 43, 45, 48, 49, 50], "order": [0, 1, 2, 4, 18, 20, 21, 24, 29, 34, 35, 37, 38, 39, 43, 45], "orderr": 34, "org": 27, "organ": 44, "orient": [18, 34], "orig": [29, 37], "origin": [1, 2, 3, 4, 12, 18, 24, 29, 30, 34, 37, 38, 39, 43, 47, 50], "ortho": 42, "orthogon": 16, "other": [2, 18, 27, 30, 43, 44, 45, 48, 58], "otherwis": [0, 1, 2, 4, 5, 6, 21, 24, 30, 31, 39, 44], "our": 18, "out": [18, 21, 24, 28, 29, 32, 34, 35, 36, 37, 39, 44, 47], "out_cel": 18, "outer": [1, 18], "outfil": [45, 46, 48], "output": [18, 21, 23, 24, 28, 29, 30, 32, 34, 35, 36, 37, 39, 40, 43, 45, 46, 48], "outputfileopenerror": [28, 41], "outward": 44, "over": [21, 31, 40, 43, 45], "overal": 34, "overflow": [22, 41], "overlap": [24, 39, 43], "overload": 58, "overwrit": 35, "overwritten": 41, "owner": [21, 23, 24, 28, 29, 30, 34, 36, 37, 39], "p": [1, 2, 18, 20, 22, 31, 41, 43], "p0": [1, 23, 24, 34, 39, 41, 43], "p1": [1, 2, 4, 18, 22, 23, 24, 34, 39, 41, 43, 45], "p2": [1, 2, 4, 18, 22, 23, 39, 41, 45], "p3": [18, 23, 39, 41], "p4": 18, "p_count": 25, "p_idx": 25, "pad": [21, 32, 44, 45], "pad_as_percentag": 21, "pad_data": 43, "pad_radiu": 43, "pair": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 45, 47], "paper": 18, "parallel": [1, 4, 18], "paramet": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 41, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], "parameter": [18, 43], "parametr": [0, 1, 4, 18, 23, 24, 39, 44], "parametric1": 18, "parametric2": 18, "parametric3": 18, "parametric4": 18, "parametric5": 18, "parametric6": 18, "parametric7": 18, "parametricdoubl": [39, 41], "parametricvec2": [23, 24, 39, 41], "parent": 43, "pars": [0, 23], "part": [1, 18, 27, 44, 49], "parti": 44, "partial": 18, "particular": [18, 43, 44], "particularli": 43, "pascalcas": 58, "pass": [18, 24, 26], "past": 39, "patch": 43, "path": [0, 1, 3, 4, 7, 12, 21, 24, 26, 30, 32, 37, 39, 44, 45, 46, 48, 50, 51, 52, 53, 54, 55, 56, 57], "path_1": [1, 4], "path_2": [1, 4], "path_command": [1, 4], "path_funct": [1, 4, 39], "path_gradi": [4, 39], "path_mark": 43, "path_spin": [1, 4], "pathcommon": [27, 58], "pathlib": [43, 45, 46, 48, 51, 52, 53, 54, 55, 56, 57], "pathtyp": 26, "pattern": 43, "pcell": 43, "pdk": [43, 49], "pelulamu": 25, "per": [0, 1, 4, 12, 18, 39, 46, 48], "percentag": [21, 45], "perform": [7, 18, 48, 50], "perimet": [2, 34], "period": 43, "permiss": 44, "permit": 44, "person": [43, 44], "photon": 43, "pi": [0, 1, 4, 8, 10, 12, 18, 43, 45, 47, 50], "piec": [18, 34], "place": [18, 32], "placement": 32, "placement_transform": 32, "planar": 44, "pleas": [30, 44], "plex": 26, "plu": [39, 41], "point": [0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 16, 18, 21, 23, 24, 25, 32, 34, 37, 39, 41, 42, 44, 50], "point1": 39, "point2": 39, "point3": 39, "point_arrai": [18, 23, 24, 34, 37, 39, 43], "pointer": [21, 30], "points1": 18, "points2": 18, "points3": 18, "points4": 18, "pol": 43, "polar": 18, "poli": [16, 18, 22, 43, 45], "poly1": [22, 45], "poly2": [22, 45], "poly3": 15, "poly4": 15, "poly5": 15, "poly6": 15, "poly_arrai": 18, "poly_list": 2, "polygon": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 21, 22, 23, 24, 25, 27, 28, 30, 32, 37, 39, 42, 43, 44, 45, 46, 47, 48, 50, 51, 58], "polygon_1": [0, 2], "polygon_2": [0, 2], "polygon_arrai": [18, 21, 43], "polygon_bb": [2, 45, 50], "polygon_hul": [45, 50], "polygoncomparisonfunct": 21, "polyogn": 34, "polys1": 22, "polys2": 22, "pop": 43, "port": 43, "pos_filt": 43, "posit": [0, 1, 3, 4, 12, 16, 17, 18, 22, 23, 34, 39, 43, 45, 47, 50], "posix": 36, "possibl": [1, 18, 43, 46], "power": 43, "practic": 43, "pre": [0, 1, 4], "pread": 36, "precis": [2, 7, 8, 12, 16, 18, 21, 22, 24, 28, 29, 30, 34, 37, 39, 41, 43, 45, 46, 48, 50, 51, 52, 53, 55, 56], "precision_": 30, "precsis": 18, "predefin": 18, "prefer": [43, 49], "prepar": 44, "present": [3, 26, 30, 41, 43], "previou": [0, 1, 4, 18, 23, 32, 39], "prid64": 20, "primarili": 18, "primit": [0, 1, 4], "print": [0, 1, 2, 16, 18, 20, 21, 23, 24, 29, 30, 31, 34, 36, 37, 38, 39, 40, 43, 45, 50, 57], "printabl": 32, "printf": [20, 31, 43], "priu64": [20, 31], "privat": [23, 24, 39, 58], "probabl": 58, "problem": 43, "process": [18, 23, 24, 39, 43, 45, 49, 50], "processor": 44, "produc": [24, 39], "program": [18, 43], "prop": 43, "propattr": 26, "properli": [18, 21, 24, 30, 39, 43], "properti": [1, 2, 4, 18, 21, 24, 29, 30, 32, 34, 37, 39, 45, 47, 48, 50, 58], "properties_clear": [30, 35], "properties_copi": 35, "properties_print": 35, "properties_to_gd": 35, "properties_to_oa": 35, "property_name_map": 32, "property_value_arrai": 32, "property_values_copi": 35, "propertytyp": 35, "propertyvalu": [32, 35], "propnam": 32, "propname_implicit": 32, "propstr": 32, "propstring_implicit": 32, "propvalu": 26, "provid": [18, 30, 43, 44], "pt": 43, "ptr": [19, 27, 58], "public": 25, "pull": 20, "purpos": [18, 44], "push": 20, "putchar": 20, "px": 21, "py": 43, "pyobject": [21, 23, 24, 28, 29, 30, 34, 36, 37, 39], "python": [18, 21, 23, 24, 28, 29, 30, 34, 36, 37, 39, 43, 44], "q": [0, 1, 4, 23], "quadrat": [0, 1, 4, 18, 23, 24, 39, 41, 43], "quadratic_smooth": [0, 1, 4, 18, 23, 24, 39], "queri": [18, 48, 50], "r": [1, 18, 43], "r_slice": 10, "racetrack": [2, 34], "racetrack1": 13, "racetrack2": 13, "rad": [0, 1, 4], "rad0": [0, 1, 4, 23], "rad1": [0, 1, 4, 23], "radian": [0, 1, 2, 4, 15, 29, 37, 45, 47, 50], "radii": [0, 1, 4, 18, 34], "radiu": [0, 1, 2, 4, 10, 13, 18, 23, 24, 34, 39, 41, 43], "radius_i": [23, 24, 34, 39, 41], "radius_x": [23, 24, 34, 39, 41], "raith": 1, "raith_data": [1, 24], "raithdata": [24, 27], "raithmbmspath": 26, "raithpxxdata": 26, "rang": [4, 18, 21, 25, 35, 43], "ratio": [0, 1, 4, 17, 34], "raw": [30, 45, 49], "raw_cel": 57, "raw_depend": 43, "rawcel": [18, 21, 27, 28, 30, 37, 43, 50, 57, 58], "rawcell_": 37, "rawcell_arrai": [30, 43], "rawsourc": 36, "re": [18, 31, 42, 43], "read": [1, 2, 3, 4, 26, 30, 36, 42, 45, 48, 49, 52, 53, 55], "read_gd": [18, 30, 43, 48], "read_oa": [18, 30], "read_rawcel": [18, 36, 43, 49], "reader": 35, "readm": 44, "real": [18, 26, 35], "realdoubl": 32, "realfloat": 32, "realiz": 58, "realloc": [19, 20, 27, 35, 43, 58], "realnegativeinteg": 32, "realnegativeratio": 32, "realnegativereciproc": 32, "realpositiveinteg": 32, "realpositiveratio": 32, "realpositivereciproc": 32, "reason": [18, 39], "receiv": 43, "recommend": 18, "record": [18, 23, 26], "rect": [8, 17, 18, 43], "rect1": 18, "rect2": 18, "rectangl": [2, 8, 17, 18, 30, 32, 34, 43, 45, 47, 48, 50, 57], "rectangular": [3, 8, 18, 32, 38, 43], "rectangulari": 32, "rectangularx": 32, "recurs": [21, 36, 45, 49, 50], "red": 45, "redefin": 43, "reduc": [18, 34], "reduct": 30, "ref": [43, 45, 50], "ref1": [18, 43], "ref2": [18, 43], "ref_arrai": 3, "refer": [3, 5, 6, 7, 11, 12, 16, 21, 23, 24, 27, 29, 30, 32, 34, 36, 38, 39, 43, 44, 45, 48, 51, 57], "referenc": [18, 21, 43, 45, 49, 50], "reference_arrai": [18, 21, 43], "referencea": 32, "referenceb": 32, "referencen": 32, "referencetyp": [18, 37, 43], "reflect": [0, 1, 2, 45, 47, 50], "reflib": 26, "region": [8, 39, 43], "regular": [3, 15, 32, 38, 43], "regular_polygon": [16, 18, 34, 43], "rel": [0, 1, 4, 18, 23, 24, 32, 39, 43], "relev": 43, "remain": [20, 25, 36], "remap": [21, 45, 48], "remap_tag": [21, 30], "remov": [18, 20, 21, 23, 24, 30, 39, 43, 45, 48], "remove_gds_properti": 35, "remove_item": 20, "remove_overlapping_point": 24, "remove_properti": 35, "remove_unord": 20, "removed_refer": [21, 43], "renam": [30, 43, 48], "rename_cel": [30, 48], "render": [0, 1, 4, 18, 43], "render_text": 43, "repeat": [18, 43], "repeat_and_transform": 37, "repeatedli": 18, "repetit": [1, 2, 4, 7, 12, 16, 18, 24, 27, 29, 32, 34, 37, 39, 44, 45, 47, 50, 58], "repetitiontyp": [18, 38, 43], "replac": [30, 48, 58], "replace_cel": 30, "report": [28, 30], "repositori": 44, "repres": [1, 2, 4, 8, 12, 18, 35, 39, 45, 47, 48, 50], "represent": [1, 4, 18, 21, 24, 37, 39, 41, 45, 50], "reproduc": 44, "request": 25, "requir": [1, 2, 3, 4, 18, 27, 43, 48, 49, 50, 58], "rescal": 44, "reserv": [26, 43], "reshap": 43, "resiz": [31, 40], "resolut": [12, 18], "reson": 43, "resonator_cel": 43, "resonator_cell_copi": 43, "resonator_cell_nam": 43, "resonator_ref": 43, "resonator_refs_p": 43, "resourc": 18, "respect": [0, 1, 17, 18, 22, 24, 30, 34, 37, 39, 41, 43, 47, 58], "respons": [18, 37, 43, 58], "resson": 43, "ressonator_copi": 43, "restrict": [21, 44], "result": [2, 7, 8, 12, 16, 18, 21, 22, 24, 28, 29, 30, 31, 32, 34, 36, 37, 38, 39, 41, 43, 45, 48, 50, 54], "retain": 37, "retriev": 39, "return": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 41, 42, 43, 45, 47, 48, 50, 51, 52, 53, 54, 55, 56, 57], "reus": [18, 43], "revers": 35, "right": [2, 18, 37, 45, 50], "right_gradi": 39, "right_intersect": 39, "right_point": 39, "right_posit": 39, "ring": [10, 13, 16, 18, 34], "ring1": 18, "ring2": 18, "ring3": 18, "robuspath": 4, "robust": [4, 39], "robustpath": [1, 5, 6, 7, 11, 12, 16, 18, 21, 27, 37, 43, 58], "robustpath_arrai": [18, 21, 43], "robustpath_cel": 18, "robustpath_cell_nam": 18, "robustpathel": 39, "rot": [0, 1, 4, 29, 37], "rotat": [0, 1, 2, 4, 15, 18, 23, 24, 29, 34, 37, 38, 39, 43, 45, 47, 50], "round": [1, 4, 7, 8, 12, 16, 18, 22, 33, 34, 43, 55, 56], "routin": [24, 39], "row": [2, 3, 18, 34, 38, 43, 45, 50], "rp": [18, 43], "rpath": 4, "rule": [21, 30, 37], "runtim": 18, "s_bounding_box_available_property_nam": 32, "s_bounding_box_property_nam": 32, "s_cell_offset_property_nam": 32, "s_gds_properti": [1, 2, 4, 47, 50], "s_gds_property_nam": 32, "s_max_int_size_property_nam": 32, "s_max_path_property_nam": 32, "s_max_polygon_property_nam": 32, "s_max_string_size_property_nam": 32, "s_max_uint_size_property_nam": 32, "s_top_level_property_nam": 32, "safe": [36, 41, 58], "safeti": 44, "said": 58, "same": [1, 2, 4, 18, 21, 23, 24, 29, 30, 34, 35, 37, 38, 39, 43, 45, 47, 48, 49, 50, 58], "sampl": 18, "save": [24, 30, 39, 43, 46, 48], "scalar": 41, "scale": [1, 2, 4, 8, 18, 21, 22, 24, 29, 30, 32, 34, 37, 39, 41, 43, 45, 47, 50], "scale_and_round_arrai": 41, "scale_width": [1, 4, 18, 24, 39, 43], "scaled_point": 41, "scenario": 18, "scope": 18, "se": [29, 32, 47], "second": [0, 1, 2, 3, 4, 7, 18, 21, 43, 45, 50], "second_direct": 41, "second_point": 41, "section": [0, 1, 4, 18, 23, 34, 43], "see": [18, 27, 30], "seek_set": 36, "seem": 18, "segment": [0, 1, 2, 4, 13, 18, 23, 24, 39, 43], "segments_intersect": 41, "self": [0, 1, 2, 4, 45, 46, 47, 48, 50], "separ": [18, 24, 25, 39], "sequenc": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 16, 18, 45, 47, 48, 50], "seri": [23, 35], "serif": 43, "serp": 39, "serv": 43, "set": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 18, 21, 22, 24, 27, 30, 31, 34, 39, 40, 41, 43, 44, 45, 47, 48, 50, 51, 58], "set_bend_funct": 1, "set_bend_radiu": 1, "set_datatyp": [1, 4], "set_end": [1, 4], "set_error_logg": 41, "set_gds_properti": [1, 2, 4, 35, 47, 50], "set_join": 1, "set_lay": [1, 4, 41], "set_properti": [1, 2, 4, 35, 45, 47, 48, 50], "set_typ": 41, "sever": [18, 23, 43], "shall": 44, "shape": [1, 3, 4, 8, 9, 10, 13, 18, 23, 24, 30, 34, 39, 43, 45, 50, 55, 56], "shape_styl": [21, 45], "shape_tag": 30, "sharp": 18, "short": 23, "shortcut": 43, "shortest": [2, 34], "shorthand": [18, 22], "should": [1, 3, 18, 20, 21, 22, 23, 24, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 43, 45, 47, 50], "shouldn": 58, "show": [18, 43], "side": [1, 4, 15, 18, 34], "side_length": [15, 34], "sign": [18, 34], "signatur": [2, 30, 32, 54], "signed_area": 34, "signedinteg": 32, "significantli": 30, "similar": [18, 21, 39], "similarli": [18, 39], "simpl": [1, 4, 18, 24, 43], "simple_path": [1, 4, 18, 24, 33, 39, 43, 45, 50], "simple_rot": 39, "simple_scal": 39, "simpli": [18, 21, 31], "simplic": 43, "simplifi": 18, "simultan": [18, 28], "sin": [1, 4, 8, 18, 39, 42], "sin_rot": 39, "sinc": [18, 43], "singl": [0, 1, 2, 4, 18, 23, 24, 39, 43, 45], "singlevalu": 32, "situat": 18, "size": [0, 1, 2, 3, 4, 17, 18, 19, 26, 27, 30, 32, 34, 36, 43, 45, 48, 49, 55, 56, 58], "size_t": [32, 41], "sizeof": [18, 20, 28, 31, 41, 43], "skip": 43, "slice": [10, 22], "slices1": 18, "slices2": 18, "slices3": 18, "slot": 20, "slow": [45, 50], "small": 18, "smaller": [2, 18, 49], "smallest": [45, 50], "smooth": [0, 1, 4, 18, 23, 33, 39, 41, 43], "smoothli": [1, 4], "snake_cas": 58, "sname": 26, "snap": 18, "snapshot": 21, "so": [3, 4, 18, 21, 22, 25, 28, 35, 36, 43, 44, 58], "softwar": [2, 18, 27, 44], "sole": 44, "solut": [18, 44], "some": [3, 18, 41, 43, 48], "some_cel": 18, "some_function_that_creates_a_huge_cel": 46, "somewher": 18, "sort": [21, 22, 27, 45], "sort_funct": 45, "sourc": [21, 30, 36, 43, 44, 58], "south": 47, "southeast": 47, "southwest": 47, "space": [3, 17, 18, 21, 26, 32, 34, 38, 43, 45, 50], "spec": 45, "special": [1, 2, 4, 30, 47, 50, 58], "specif": [1, 2, 4, 18, 20, 21, 30, 43, 45, 47, 48, 50, 58], "specifi": [0, 1, 2, 3, 4, 16, 18, 20, 28, 30, 45], "speed": 48, "spike": 12, "spine": [1, 4, 23, 24, 39, 58], "spine_gradi": 39, "spine_intersect": 39, "spine_point": 39, "spine_posit": 39, "spiral": [1, 4], "spline": [0, 1, 4, 41], "split": 1, "sqrt": [1, 42, 43], "squar": [41, 43], "square_cel": 43, "square_cell_nam": 43, "square_referec": 43, "src": 20, "sref": [26, 43], "srfname": 26, "stack": 18, "stamp": 18, "standard": [18, 48], "standard_properti": 48, "stare": 18, "start": [0, 1, 2, 4, 17, 23, 24, 29, 32, 34, 35, 36, 37, 38, 39, 43, 44, 48, 58], "starting_point": 43, "state": [23, 24, 34, 35, 39, 58], "statement": 44, "static": [41, 58], "stdio": [18, 43], "step": [3, 18, 39, 46], "still": [18, 46], "stl": 58, "store": [1, 2, 4, 18, 21, 23, 24, 28, 29, 30, 34, 35, 36, 37, 39, 41, 43, 45, 46, 47, 48, 49, 50], "str": [1, 2, 4, 7, 16, 17, 41, 45, 46, 47, 48, 50, 51, 52, 53, 54, 55, 56, 57], "straight": [0, 1, 4, 13, 18, 23, 39, 43], "straight_length": [13, 34], "stran": 26, "strclass": 26, "strcmp": [31, 43], "strcpy": 43, "stream": [46, 55, 56], "string": [17, 18, 21, 26, 29, 30, 31, 34, 35, 41, 47, 48], "strlen": [28, 43], "strname": 26, "stroke": [40, 45], "strtype": 26, "struct": [20, 21, 22, 23, 24, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 58], "structnam": 58, "structur": [18, 21, 45, 49, 58], "style": [21, 27, 41, 43, 44], "style_map": 40, "stylemap": [21, 40], "styptabl": 26, "sub0": 39, "sub1": 39, "subcompon": 43, "subdivid": 18, "subject": 44, "subpath": 39, "subpath_arrai": [39, 43], "subpathtyp": 39, "substitut": 20, "subtract": 18, "successor": 44, "suffici": 43, "sum": [1, 43], "suppli": 27, "support": [1, 2, 4, 18, 29, 30, 43, 45, 47, 48, 50], "suppos": [21, 24, 29, 32, 34, 35, 36, 37, 39], "suppress": 22, "sure": 43, "svg": [0, 18, 21, 24, 29, 34, 37, 39, 40, 41, 43, 45, 47], "sw": [29, 32, 47], "swap": [26, 41], "switch": 33, "sx": 2, "sy": 2, "symmetr": [18, 43], "syntax": 18, "system": [18, 44], "t": [0, 1, 4, 18, 20, 21, 23, 24, 31, 34, 41, 43, 58], "t_full_etch": 18, "t_lift_off": 18, "t_partial_etch": 18, "tabl": [0, 1, 4, 43], "tag": [18, 21, 24, 29, 30, 34, 37, 39, 40, 41, 43], "tagmap": [21, 30], "take": [1, 18, 43], "taken": [18, 29, 34, 58], "tangent": [0, 1, 4], "tapecod": 26, "tapenum": 26, "taper": [1, 4, 18, 43], "task": 43, "teeth": 43, "temp_kei": 31, "templat": [20, 31, 41, 58], "tension": [0, 1, 4, 18, 23, 24, 39, 41, 43], "tension_in": [0, 1, 4], "tension_out": [0, 1, 4], "term": 27, "termin": [21, 29, 30, 31, 34, 35, 41], "test": [5, 6, 11, 43, 57], "text": [7, 12, 25, 26, 29, 32, 34, 41, 43, 44, 45, 47, 48, 50, 51, 58], "text_": 29, "text_cel": 18, "text_cell_nam": 18, "textnod": 26, "textpath": 43, "textstr": 32, "textstring_implicit": 32, "texttyp": [18, 26, 45, 47, 50], "than": [13, 18, 21, 34, 43, 55, 56], "thei": [0, 1, 4, 18, 21, 23, 24, 27, 29, 30, 32, 34, 35, 36, 37, 39, 43, 45, 47, 49, 50, 58], "them": [1, 18, 21, 37, 43, 45, 49, 57], "themselv": 45, "therefor": [18, 24, 39], "thereof": 21, "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30, 31, 32, 34, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 55, 56, 58], "third": [18, 44], "those": [1, 2, 4, 7, 18, 23, 24, 30, 34, 39, 43, 45, 47, 48, 50, 58], "though": [18, 24, 39], "thread": [36, 41, 44], "through": [0, 1, 2, 4, 18, 23, 24, 28, 30, 32, 35, 36, 39, 41, 43, 58], "throughout": [18, 27, 30, 42], "thru": [4, 25, 46], "time": [17, 18, 21, 23, 28, 30, 34, 46, 48], "timestamp": [21, 28, 30, 46, 48], "titl": 44, "tm": [21, 28, 30, 41], "tm_hour": 28, "tm_mdai": 28, "tm_min": 28, "tm_mon": 28, "tm_sec": 28, "tm_year": 28, "to_arrai": [31, 43], "to_gd": [21, 24, 28, 29, 34, 36, 37, 39], "to_oa": [24, 34, 39], "to_polygon": [1, 4, 18, 24, 39, 43], "to_svg": [21, 24, 29, 34, 37, 39], "todo": 30, "togeth": 18, "toler": [0, 1, 2, 4, 10, 12, 13, 18, 22, 23, 24, 30, 34, 39, 41, 43, 48, 55, 56, 58], "tolerance_": [23, 39], "too": [22, 46], "tool": 44, "top": [0, 18, 30, 39, 43, 48], "top_cel": [30, 55, 56], "top_level": [18, 30, 48, 55, 56], "top_rawcel": 30, "tort": 44, "total": [9, 34], "touch": [21, 23, 24, 28, 29, 30, 34, 36, 37, 39], "trace": 43, "track": 48, "trafo": [39, 58], "transform": [1, 2, 4, 21, 24, 29, 34, 37, 38, 39, 44, 45, 47, 50, 58], "transistor": 18, "translat": [1, 2, 4, 18, 24, 29, 34, 37, 39, 43, 45], "transmit": 44, "trapezoid": [30, 48], "trapezoid_a": 32, "trapezoid_ab": 32, "trapezoid_b": 32, "treat": [1, 4, 24, 39], "tree": 21, "triangl": [16, 43], "true": [0, 1, 2, 4, 5, 6, 12, 13, 18, 20, 21, 22, 23, 24, 30, 31, 35, 36, 37, 39, 41, 43, 45, 47, 48, 49, 50, 54, 57], "tupl": [1, 2, 4, 11, 45, 48, 50, 51, 52, 54, 55], "turn": [0, 1, 4, 23, 24, 39], "two": [18, 43], "twobytesignedinteg": 26, "txt": [18, 27, 43], "type": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 32, 35, 37, 38, 39, 41, 43, 45, 47, 48, 50, 51, 55, 58], "typedef": [21, 41], "typefac": 43, "typic": [18, 44], "u": [0, 1, 4, 18, 39, 42, 43], "u0": [1, 39, 41], "u1": [1, 39, 41], "uint16_t": [25, 28, 30, 32, 35, 41, 43], "uint32_t": [21, 24, 29, 30, 32, 34, 36, 37, 39, 41], "uint64_t": [18, 19, 20, 21, 23, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36, 38, 39, 40, 41, 43, 58], "uint8_t": [26, 30, 32, 35, 36, 41], "uinteg": 26, "unabl": [18, 28], "under": [1, 2, 4, 27, 47, 50], "understood": 8, "undesir": 31, "union": [7, 12, 18, 23, 35, 36, 37, 38, 39, 42], "uniqu": [1, 2, 4, 18, 21, 30, 43, 45, 47, 48, 50], "unit": [21, 26, 28, 30, 41, 43, 46, 48, 49, 51, 52, 55, 56], "unit_": 30, "unit_cel": 43, "unit_cell_nam": 43, "unit_ref": 43, "unit_refs_p": 43, "unknown": 33, "unless": [21, 39, 44], "unlik": 39, "unofficialspecif": 41, "unscii": 25, "unsign": 41, "unsigned_integ": 35, "unsignedinteg": [32, 35], "unsupportedrecord": 41, "until": [34, 36], "up": [1, 4, 18, 21, 30, 43, 45, 49, 58], "updat": [30, 41, 43, 48], "upper": [2, 37, 45, 50], "upper_cas": 58, "upperbound": 32, "uppercas": [0, 1, 4], "us": [0, 1, 2, 4, 10, 13, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 55, 56, 58, 59], "use_union": [12, 18, 22], "user": [18, 21, 24, 27, 29, 32, 34, 35, 36, 37, 39, 41, 43, 46, 48, 49, 58], "ustr": 26, "usual": [2, 18], "ut0": 41, "ut1": 41, "util": [27, 58], "v": [0, 1, 4, 23, 24, 34, 39, 42], "v0": [1, 43], "v1": [1, 3, 38, 42, 43, 45, 50], "v2": [3, 38, 42, 43, 45, 50], "valid": [18, 21, 23, 24, 30, 39, 48, 54], "valu": [0, 1, 2, 4, 12, 18, 21, 23, 24, 26, 28, 29, 30, 31, 32, 34, 35, 36, 37, 39, 40, 41, 43, 45, 47, 48, 50], "value_print": 31, "var": 58, "vari": [0, 1, 4], "variabl": 58, "variat": 18, "variou": 21, "vcoord": 43, "vec": [27, 58], "vec2": [18, 20, 21, 23, 24, 25, 29, 32, 34, 37, 38, 39, 41, 42, 43], "vector": [1, 2, 3, 4, 41, 43], "verifi": 18, "version": [0, 1, 4, 18, 21, 23, 24, 25, 27, 36, 37, 39, 41, 42, 43, 44], "vertex": [2, 7, 8, 12, 16, 18, 34], "vertic": [0, 1, 2, 4, 5, 6, 11, 12, 13, 17, 18, 22, 23, 24, 34, 39, 42, 45, 46, 48, 50], "vertical_lineskip": 25, "vertical_step": 25, "vertical_tab": 25, "via": 30, "viewer": [18, 43], "viewport": 45, "virtual": 58, "visit": [45, 50], "vline": 43, "void": [18, 19, 20, 21, 23, 24, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 43, 58], "vtext": 18, "w": [29, 32, 43, 47], "wa": [18, 43], "wai": [18, 43, 49, 58], "want": 43, "warn": 41, "warranti": 44, "waveguid": 43, "wb": 28, "we": [18, 25, 43, 58], "weakli": 18, "well": 7, "west": 47, "wg_cell": 43, "wg_ref": 43, "when": [0, 1, 4, 18, 21, 22, 24, 34, 39, 42, 43, 46, 48, 49, 50, 58], "whenev": [18, 21], "where": [4, 8, 16, 18, 36, 43], "wherea": [0, 1, 4, 12, 18], "whether": [2, 5, 6, 11, 21, 23, 24, 32, 39, 44, 45, 48, 50], "which": [3, 18, 21, 23, 24, 28, 30, 32, 34, 35, 39, 41, 43, 45, 48, 58], "whichev": 2, "while": [31, 43, 45], "whole": [18, 21, 30, 40, 44, 45, 58], "whom": 44, "whose": [18, 45], "why": 43, "wider": 43, "width": [1, 4, 9, 18, 24, 26, 33, 39, 41, 43], "width0": 39, "width1": [18, 39], "width2": 18, "width_arrai": 39, "width_scal": [39, 58], "witch": 18, "within": [18, 25, 30, 35, 41, 43, 45], "without": [18, 30, 43, 44, 51, 57], "work": [18, 37, 43, 44], "world": 18, "worri": 18, "would": [18, 43], "write": [17, 18, 28, 42, 46], "write_cel": 28, "write_gd": [18, 21, 30, 43, 46, 48, 57], "write_oa": [18, 30, 32, 48], "write_rawcel": 28, "write_svg": [18, 21, 45], "writer": [43, 46], "written": [18, 28, 39, 46, 48], "wrt": 43, "www": 27, "x": [0, 1, 2, 3, 4, 8, 16, 18, 20, 21, 23, 25, 32, 34, 37, 38, 39, 42, 43, 47, 50], "x0": [0, 1, 4, 23], "x1": [0, 1, 4, 23], "x2": [0, 1, 4, 23], "x_axi": 22, "x_offset": [3, 43], "x_refl": [29, 37], "x_reflect": [2, 24, 29, 34, 37, 38, 39, 43, 45, 47, 50], "xelement": 32, "xgeometri": 32, "xmax": 43, "xname": 32, "xname_implicit": 32, "xor": [7, 18, 22, 43, 44], "xt": 39, "xy": [0, 1, 4, 26], "xyabsolut": 32, "xyrel": 32, "y": [0, 1, 2, 3, 4, 8, 16, 18, 20, 23, 25, 32, 38, 39, 42, 43], "y0": [0, 1, 4, 23], "y1": [0, 1, 4, 23], "y2": [0, 1, 4, 23], "y_offset": [3, 43], "you": 39, "yt": 39, "z": 42, "z1": 42, "z2": 42, "zehnder": 43, "zero": [1, 4, 20, 21, 23, 24, 29, 30, 31, 34, 37, 38, 39, 40, 41, 55, 56, 58], "zliberror": 41, "\u00b5m": 18, "\u00b9\u00b2": 18, "\u2076": 18, "\u2079": 18}, "titles": ["gdstk.Curve", "gdstk.FlexPath", "gdstk.Polygon", "gdstk.Repetition", "gdstk.RobustPath", "gdstk.all_inside", "gdstk.any_inside", "gdstk.boolean", "gdstk.contour", "gdstk.cross", "gdstk.ellipse", "gdstk.inside", "gdstk.offset", "gdstk.racetrack", "gdstk.rectangle", "gdstk.regular_polygon", "gdstk.slice", "gdstk.text", "Getting Started", "allocator.h", "array.h", "cell.h", "clipper_tools.h", "curve.h", "flexpath.h", "font.h", "gdsii.h", "gdstk.h", "gdswriter.h", "label.h", "library.h", "map.h", "oasis.h", "pathcommon.h", "polygon.h", "property.h", "rawcell.h", "reference.h", "repetition.h", "robustpath.h", "style.h", "utils.h", "vec.h", "How-Tos", "Gdstk Documentation", "gdstk.Cell", "gdstk.GdsWriter", "gdstk.Label", "gdstk.Library", "gdstk.RawCell", "gdstk.Reference", "gdstk.gds_info", "gdstk.gds_units", "gdstk.oas_precision", "gdstk.oas_validate", "gdstk.read_gds", "gdstk.read_oas", "gdstk.read_rawcells", "C++ Reference", "Python API Reference"], "titleterms": {"A": 18, "Tos": 43, "about": 18, "all_insid": 5, "alloc": 19, "along": 43, "any_insid": 6, "api": 59, "arrai": 20, "boolean": [7, 18], "c": 58, "cell": [18, 21, 43, 45], "circl": 18, "clipper_tool": 22, "code": 58, "connect": 43, "construct": 59, "content": 44, "contour": 8, "creat": 43, "cross": 9, "curv": [0, 18, 23], "datatyp": 18, "document": 44, "ellips": 10, "file": [18, 58], "fillet": 18, "filter": 43, "first": 18, "flexibl": 18, "flexpath": [1, 24], "font": [25, 43], "gds_info": 51, "gds_unit": 52, "gdsii": [18, 26], "gdstk": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 27, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57], "gdswriter": [28, 46], "geometri": [18, 43, 59], "get": 18, "h": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "header": 58, "hole": 18, "how": 43, "insid": 11, "label": [29, 47], "layer": 18, "layout": 18, "librari": [18, 30, 43, 48, 59], "licens": 44, "load": 18, "manag": 58, "map": 31, "memori": 58, "merg": 43, "note": [0, 1, 2, 3, 4, 7, 8, 12, 16, 17, 18, 45, 47, 48, 49, 50], "oas_precis": 53, "oas_valid": 54, "oasi": [18, 32], "offset": [12, 18], "oper": 18, "organ": 59, "pad": 43, "parametr": 43, "part": 43, "path": [18, 43], "pathcommon": 33, "point": 43, "polygon": [2, 18, 34], "properti": 35, "python": 59, "racetrack": 13, "raw": 18, "rawcel": [36, 49], "read_gd": 55, "read_oa": 56, "read_rawcel": 57, "rectangl": 14, "refer": [18, 37, 50, 58, 59], "regular_polygon": 15, "repetit": [3, 38, 43], "robust": 18, "robustpath": [4, 39], "safeti": 58, "save": 18, "slice": [16, 18], "start": 18, "style": [40, 58], "support": 44, "system": 43, "tabl": 44, "text": [17, 18], "thread": 58, "transform": [18, 43], "unit": 18, "us": 43, "util": 41, "vec": 42}}) \ No newline at end of file